Skip to content

Commit 2612c2a

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 2612c2a

6 files changed

+113
-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,40 @@
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):SIMPLE(filecheck=WGSL):-target wgsl -stage compute -entry computeMain
4+
//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHK):-slang -compute -shaderobj
5+
//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHK):-vk -compute -shaderobj
6+
//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=CHK):-cuda -compute -shaderobj
7+
//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=CHK):-cpu -compute -shaderobj
8+
9+
// SM6.0 and above require to use `and()` and `or()` when the operands are non-scalar.
10+
// And SM below SM6.0 doesn't have the functions, `and()` and `or()`.
11+
12+
//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer
13+
RWStructuredBuffer<int> outputBuffer;
14+
15+
static int result = 0;
16+
17+
bool2 assignFunc(int index)
18+
{
19+
result++;
20+
return bool2(true);
21+
}
22+
23+
[numthreads(4, 1, 1)]
24+
void computeMain(int3 dispatchThreadID : SV_DispatchThreadID)
25+
{
26+
int index = dispatchThreadID.x;
27+
28+
//SM5:!all({{.*}}&&
29+
//SM6:!all({{ *}}and(
30+
//WGSL:!all( select(vec2<bool>(false),
31+
if (!all(bool2(index < 2) && assignFunc(index)))
32+
{
33+
result++;
34+
}
35+
36+
outputBuffer[index] = result;
37+
38+
//CHK-COUNT-2: 1
39+
//CHK-COUNT-2: 2
40+
}

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)