Skip to content

Commit 4324aaf

Browse files
committed
Use and() and or() functions for logical-AND and OR
With this commit, Slang will emit function calls to `and()` and `or()` for the logical-AND and logical-OR when the operands are non-scalar and the target profile is SM6.0 and above. This is required change from SM6.0. For WGSL, there is no operator overloadings of `&&` and `||` when the operands are non-scalar. Unlike HLSL, WGSL also don't have `and()` nor `or()`. Alternatively, we can use `select()`.
1 parent 075b10e commit 4324aaf

6 files changed

+106
-21
lines changed

lock

Whitespace-only changes.

source/slang/slang-emit-hlsl.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,36 @@ bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
821821
}
822822
break;
823823
}
824+
case kIROp_And:
825+
case kIROp_Or:
826+
{
827+
// SM6.0 requires to use `and()` and `or()` functions for the logical-AND and
828+
// logical-OR, respectively, with non-scalar operands.
829+
auto targetProfile = getTargetProgram()->getOptionSet().getProfile();
830+
if (targetProfile.getVersion() < ProfileVersion::DX_6_0)
831+
return false;
832+
833+
if (as<IRBasicType>(inst->getDataType()))
834+
return false;
835+
836+
const auto emitOp = getEmitOpForOp(inst->getOp());
837+
const auto info = getInfo(emitOp);
838+
839+
if (inst->getOp() == kIROp_And)
840+
{
841+
m_writer->emit(" and(");
842+
}
843+
else
844+
{
845+
m_writer->emit(" or(");
846+
}
847+
emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
848+
m_writer->emit(", ");
849+
emitOperand(inst->getOperand(1), getInfo(EmitOp::General));
850+
m_writer->emit(")");
851+
return true;
852+
}
853+
824854
case kIROp_BitCast:
825855
{
826856
// For simplicity, we will handle all bit-cast operations

source/slang/slang-emit-wgsl.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -1312,6 +1312,40 @@ bool WGSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
13121312
}
13131313
break;
13141314

1315+
case kIROp_And:
1316+
case kIROp_Or:
1317+
{
1318+
// WGSL doesn't have operator overloadings for `&&` and `||` when the operands are
1319+
// non-scalar. Unlike HLSL, WGSL doesn't have `and()` and `or()`.
1320+
if (as<IRBasicType>(inst->getDataType()))
1321+
return false;
1322+
1323+
const auto emitOp = getEmitOpForOp(inst->getOp());
1324+
const auto info = getInfo(emitOp);
1325+
1326+
if (inst->getOp() == kIROp_And)
1327+
{
1328+
m_writer->emit(" select(");
1329+
emitType(inst->getDataType());
1330+
m_writer->emit("(false),");
1331+
emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
1332+
m_writer->emit(", ");
1333+
emitOperand(inst->getOperand(1), getInfo(EmitOp::General));
1334+
m_writer->emit(")");
1335+
}
1336+
else
1337+
{
1338+
m_writer->emit(" select(");
1339+
emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
1340+
m_writer->emit(", ");
1341+
emitType(inst->getDataType());
1342+
m_writer->emit("(true), ");
1343+
emitOperand(inst->getOperand(1), getInfo(EmitOp::General));
1344+
m_writer->emit(")");
1345+
}
1346+
return true;
1347+
}
1348+
13151349
case kIROp_BitCast:
13161350
{
13171351
// In WGSL there is a built-in bitcast function!
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//TEST(compute):SIMPLE(filecheck=SM5):-target hlsl -profile cs_5_1 -entry computeMain
2+
//TEST(compute):SIMPLE(filecheck=SM6):-target hlsl -profile cs_6_0 -entry computeMain
3+
//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHK):-slang -compute -shaderobj
4+
//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHK):-vk -compute -shaderobj
5+
//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=CHK):-cuda -compute -shaderobj
6+
//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=CHK):-cpu -compute -shaderobj
7+
8+
// SM6.0 and above require to use `and()` and `or()` when the operands are non-scalar.
9+
// And SM below SM6.0 doesn't have the functions, `and()` and `or()`.
10+
11+
//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer
12+
RWStructuredBuffer<int> outputBuffer;
13+
14+
bool2 assignFunc(int index)
15+
{
16+
outputBuffer[index] = 1;
17+
return bool2(true);
18+
}
19+
20+
[numthreads(4, 1, 1)]
21+
void computeMain(int3 dispatchThreadID : SV_DispatchThreadID)
22+
{
23+
int index = dispatchThreadID.x;
24+
25+
//SM5:!all({{.*}}&&
26+
//SM6:!all({{ *}}and(
27+
if (!all(bool2(index < 2) && assignFunc(index)))
28+
{
29+
outputBuffer[0] = 1;
30+
}
31+
32+
//CHK-COUNT-4: 1
33+
}

tests/compute/logic-short-circuit-evaluation.slang

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
//TEST(compute):COMPARE_COMPUTE:-dx12 -compute -shaderobj
2-
//TEST(compute):COMPARE_COMPUTE:-vk -compute -shaderobj
3-
//TEST(compute):COMPARE_COMPUTE_EX:-cuda -compute -shaderobj
4-
//TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute -compile-arg -O3 -shaderobj
5-
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj
1+
//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHK):-dx12 -compute -shaderobj
2+
//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHK):-vk -compute -shaderobj
3+
//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=CHK):-cuda -compute -shaderobj
4+
//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=CHK):-cpu -compute -compile-arg -O3 -shaderobj
5+
//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=CHK):-slang -compute -shaderobj
66

77
// Test doing vector comparisons
88

@@ -25,4 +25,8 @@ void computeMain(int3 dispatchThreadID : SV_DispatchThreadID)
2525

2626
// Only the last 4 elements will be 1.
2727
(index < 12) || assignFunc(index);
28+
29+
//CHK-COUNT-4: 1
30+
//CHK-COUNT-8: 0
31+
//CHK-COUNT-4: 1
2832
}

tests/compute/logic-short-circuit-evaluation.slang.expected.txt

-16
This file was deleted.

0 commit comments

Comments
 (0)