summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-03-14 16:21:03 -0400
committerGitHub <noreply@github.com>2019-03-14 16:21:03 -0400
commitc8e36bd128a29654b2ec145038da9e132330581b (patch)
tree950ce7c3bb1cc235f97ceb982643e99245c87e16
parent04416431993b1d5efa8eac759a16832d40c2a159 (diff)
Hotfix/bool fix (#907)
* * Handle ! for bool vector in glsl * Handle operators that have a boolean return value * || or && take bool * * Add comment in bool-op.slang test about doing || or && on vector types not supported for GLSL targets
-rw-r--r--source/slang/core.meta.slang11
-rw-r--r--source/slang/core.meta.slang.h13
-rw-r--r--source/slang/emit.cpp33
-rw-r--r--source/slang/slang-stdlib.cpp20
-rw-r--r--tests/bugs/bool-op.slang77
-rw-r--r--tests/bugs/bool-op.slang.expected.txt16
6 files changed, 146 insertions, 24 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index f3e57b90b..e42669822 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -1103,22 +1103,25 @@ for (auto op : unaryOps)
if ((type.flags & op.flags) == 0)
continue;
+ char const* resultType = type.name;
+ if (op.flags & BOOL_RESULT) resultType = "bool";
+
char const* fixity = (op.flags & POSTFIX) != 0 ? "__postfix " : "__prefix ";
char const* qual = (op.flags & ASSIGNMENT) != 0 ? "in out " : "";
// scalar version
sb << fixity;
- sb << "__intrinsic_op(" << int(op.opCode) << ") " << type.name << " operator" << op.opName << "(" << qual << type.name << " value);\n";
+ sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " operator" << op.opName << "(" << qual << type.name << " value);\n";
// vector version
sb << "__generic<let N : int> ";
sb << fixity;
- sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << type.name << ",N> operator" << op.opName << "(" << qual << "vector<" << type.name << ",N> value);\n";
+ sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(" << qual << "vector<" << type.name << ",N> value);\n";
// matrix version
sb << "__generic<let N : int, let M : int> ";
sb << fixity;
- sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << type.name << ",N,M> operator" << op.opName << "(" << qual << "matrix<" << type.name << ",N,M> value);\n";
+ sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(" << qual << "matrix<" << type.name << ",N,M> value);\n";
}
}
@@ -1133,7 +1136,7 @@ for (auto op : binaryOps)
char const* rightType = leftType;
char const* resultType = leftType;
- if (op.flags & COMPARISON) resultType = "bool";
+ if (op.flags & BOOL_RESULT) resultType = "bool";
char const* leftQual = "";
if(op.flags & ASSIGNMENT) leftQual = "in out ";
diff --git a/source/slang/core.meta.slang.h b/source/slang/core.meta.slang.h
index 2ae45a01c..6dc84df43 100644
--- a/source/slang/core.meta.slang.h
+++ b/source/slang/core.meta.slang.h
@@ -1121,22 +1121,25 @@ for (auto op : unaryOps)
if ((type.flags & op.flags) == 0)
continue;
+ char const* resultType = type.name;
+ if (op.flags & BOOL_RESULT) resultType = "bool";
+
char const* fixity = (op.flags & POSTFIX) != 0 ? "__postfix " : "__prefix ";
char const* qual = (op.flags & ASSIGNMENT) != 0 ? "in out " : "";
// scalar version
sb << fixity;
- sb << "__intrinsic_op(" << int(op.opCode) << ") " << type.name << " operator" << op.opName << "(" << qual << type.name << " value);\n";
+ sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " operator" << op.opName << "(" << qual << type.name << " value);\n";
// vector version
sb << "__generic<let N : int> ";
sb << fixity;
- sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << type.name << ",N> operator" << op.opName << "(" << qual << "vector<" << type.name << ",N> value);\n";
+ sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(" << qual << "vector<" << type.name << ",N> value);\n";
// matrix version
sb << "__generic<let N : int, let M : int> ";
sb << fixity;
- sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << type.name << ",N,M> operator" << op.opName << "(" << qual << "matrix<" << type.name << ",N,M> value);\n";
+ sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(" << qual << "matrix<" << type.name << ",N,M> value);\n";
}
}
@@ -1151,7 +1154,7 @@ for (auto op : binaryOps)
char const* rightType = leftType;
char const* resultType = leftType;
- if (op.flags & COMPARISON) resultType = "bool";
+ if (op.flags & BOOL_RESULT) resultType = "bool";
char const* leftQual = "";
if(op.flags & ASSIGNMENT) leftQual = "in out ";
@@ -1202,7 +1205,7 @@ for (auto op : binaryOps)
sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(" << leftQual << "matrix<" << leftType << ",N,M> left, " << rightType << " right);\n";
}
}
-SLANG_RAW("#line 1187 \"core.meta.slang\"")
+SLANG_RAW("#line 1190 \"core.meta.slang\"")
SLANG_RAW("\n")
SLANG_RAW("\n")
SLANG_RAW("// Operators to apply to `enum` types\n")
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 0c1896c0c..d2de479b4 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -3621,6 +3621,33 @@ struct EmitVisitor
}
}
+ void emitNot(EmitContext* ctx, IRInst* inst, IREmitMode mode, EOpInfo& ioOuterPrec, bool* outNeedClose)
+ {
+ IRInst* operand = inst->getOperand(0);
+
+ if (getTarget(ctx) == CodeGenTarget::GLSL)
+ {
+ if (auto vectorType = as<IRVectorType>(operand->getDataType()))
+ {
+ // Handle as a function call
+ auto prec = kEOp_Postfix;
+ *outNeedClose = maybeEmitParens(ioOuterPrec, prec);
+
+ emit("not(");
+ emitIROperand(ctx, operand, mode, kEOp_General);
+ emit(")");
+ return;
+ }
+ }
+
+ auto prec = kEOp_Prefix;
+ *outNeedClose = maybeEmitParens(ioOuterPrec, prec);
+
+ emit("!");
+ emitIROperand(ctx, operand, mode, rightSide(prec, ioOuterPrec));
+ }
+
+
void emitComparison(EmitContext* ctx, IRInst* inst, IREmitMode mode, EOpInfo& ioOuterPrec, const EOpInfo& opPrec, bool* needCloseOut)
{
if (getTarget(ctx) == CodeGenTarget::GLSL)
@@ -3839,11 +3866,7 @@ struct EmitVisitor
case kIROp_Not:
{
- auto prec = kEOp_Prefix;
- needClose = maybeEmitParens(outerPrec, prec);
-
- emit("!");
- emitIROperand(ctx, inst->getOperand(0), mode, rightSide(prec, outerPrec));
+ emitNot(ctx, inst, mode, outerPrec, &needClose);
}
break;
diff --git a/source/slang/slang-stdlib.cpp b/source/slang/slang-stdlib.cpp
index 936c92fdd..183bed9ba 100644
--- a/source/slang/slang-stdlib.cpp
+++ b/source/slang/slang-stdlib.cpp
@@ -46,7 +46,7 @@ namespace Slang
{
SINT_MASK = 1 << 0,
FLOAT_MASK = 1 << 1,
- COMPARISON = 1 << 2,
+ BOOL_RESULT = 1 << 2,
BOOL_MASK = 1 << 3,
UINT_MASK = 1 << 4,
ASSIGNMENT = 1 << 5,
@@ -203,7 +203,7 @@ namespace Slang
static const OpInfo unaryOps[] = {
{ kIRPseudoOp_Pos, "+", ARITHMETIC_MASK },
{ kIROp_Neg, "-", ARITHMETIC_MASK },
- { kIROp_Not, "!", ANY_MASK },
+ { kIROp_Not, "!", BOOL_MASK | BOOL_RESULT },
{ kIROp_BitNot, "~", INT_MASK },
{ kIRPseudoOp_PreInc, "++", ARITHMETIC_MASK | ASSIGNMENT },
{ kIRPseudoOp_PreDec, "--", ARITHMETIC_MASK | ASSIGNMENT },
@@ -217,19 +217,19 @@ namespace Slang
{ kIROp_Mul, "*", ARITHMETIC_MASK },
{ kIROp_Div, "/", ARITHMETIC_MASK },
{ kIROp_Mod, "%", INT_MASK },
- { kIROp_And, "&&", LOGICAL_MASK },
- { kIROp_Or, "||", LOGICAL_MASK },
+ { kIROp_And, "&&", BOOL_MASK | BOOL_RESULT},
+ { kIROp_Or, "||", BOOL_MASK | BOOL_RESULT },
{ kIROp_BitAnd, "&", LOGICAL_MASK },
{ kIROp_BitOr, "|", LOGICAL_MASK },
{ kIROp_BitXor, "^", LOGICAL_MASK },
{ kIROp_Lsh, "<<", INT_MASK },
{ kIROp_Rsh, ">>", INT_MASK },
- { kIROp_Eql, "==", ANY_MASK | COMPARISON },
- { kIROp_Neq, "!=", ANY_MASK | COMPARISON },
- { kIROp_Greater, ">", ARITHMETIC_MASK | COMPARISON },
- { kIROp_Less, "<", ARITHMETIC_MASK | COMPARISON },
- { kIROp_Geq, ">=", ARITHMETIC_MASK | COMPARISON },
- { kIROp_Leq, "<=", ARITHMETIC_MASK | COMPARISON },
+ { kIROp_Eql, "==", ANY_MASK | BOOL_RESULT },
+ { kIROp_Neq, "!=", ANY_MASK | BOOL_RESULT },
+ { kIROp_Greater, ">", ARITHMETIC_MASK | BOOL_RESULT },
+ { kIROp_Less, "<", ARITHMETIC_MASK | BOOL_RESULT },
+ { kIROp_Geq, ">=", ARITHMETIC_MASK | BOOL_RESULT },
+ { kIROp_Leq, "<=", ARITHMETIC_MASK | BOOL_RESULT },
{ kIRPseudoOp_AddAssign, "+=", ASSIGNMENT | ARITHMETIC_MASK },
{ kIRPseudoOp_SubAssign, "-=", ASSIGNMENT | ARITHMETIC_MASK },
{ kIRPseudoOp_MulAssign, "*=", ASSIGNMENT | ARITHMETIC_MASK },
diff --git a/tests/bugs/bool-op.slang b/tests/bugs/bool-op.slang
new file mode 100644
index 000000000..1388ef8f1
--- /dev/null
+++ b/tests/bugs/bool-op.slang
@@ -0,0 +1,77 @@
+// enum.slang
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute
+//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute
+
+// Confirm operations that produce bools - such as comparisons, or && ||, ! work correctly
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], stride=4):dxbinding(0),glbinding(0),out
+RWStructuredBuffer<int> outputBuffer;
+
+[numthreads(16, 1, 1)]
+void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
+{
+ uint tid = dispatchThreadID.x;;
+
+ uint uv = tid;
+ int iv = int(tid);
+
+ bool2 bv2 = { tid & 1, tid > 10 };
+
+ float2 f2 = { float(tid), float(tid + 1) };
+
+ bool bv = tid > 6;
+ let not_bv2 = !bv2;
+
+ int r = 0;
+ if (bv)
+ {
+ r |= 0x0001;
+ }
+ if (!bv)
+ {
+ r |= 0x0002;
+ }
+
+ if (iv)
+ {
+ r|= 0x0004;
+ }
+ if (!iv)
+ {
+ r|= 0x0008;
+ }
+
+ if (uv)
+ {
+ r |= 0x0010;
+ }
+ if (!uv)
+ {
+ r |= 0x0020;
+ }
+
+ if (all(bv2))
+ {
+ r |= 0x0040;
+ }
+ if (all(not_bv2))
+ {
+ r |= 0x0080;
+ }
+
+ if (any(!f2))
+ {
+ r |= 0x0100;
+ }
+
+ // TODO(JS): Support on GLSL targets
+ // This doesn't currently work on GLSL targets, and because there
+ // do not appear to be any vector bitwise operations. Could be achieved
+ // by deconstructing, and reconstructing the vec result
+ /* if (all(f2 || bv2))
+ {
+ r |= 0x0200;
+ } */
+
+ outputBuffer[tid] = r;
+} \ No newline at end of file
diff --git a/tests/bugs/bool-op.slang.expected.txt b/tests/bugs/bool-op.slang.expected.txt
new file mode 100644
index 000000000..08b720347
--- /dev/null
+++ b/tests/bugs/bool-op.slang.expected.txt
@@ -0,0 +1,16 @@
+1AA
+16
+96
+16
+96
+16
+96
+15
+95
+15
+95
+55
+15
+55
+15
+55