Browse Source

[spirv] Emit OpLogical{|Not}Equal for boolean comparison (#526)

Lei Zhang 8 years ago
parent
commit
378c2224b8

+ 22 - 8
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -1297,6 +1297,28 @@ case BO_##kind : {                                                             \
   break
 
   switch (op) {
+  case BO_EQ: {
+    if (isBoolOrVecMatOfBoolType(type))
+      return spv::Op::OpLogicalEqual;
+    if (isSintType || isUintType)
+      return spv::Op::OpIEqual;
+    if (isFloatType)
+      return spv::Op::OpFOrdEqual;
+  } break;
+  case BO_NE: {
+    if (isBoolOrVecMatOfBoolType(type))
+      return spv::Op::OpLogicalNotEqual;
+    if (isSintType || isUintType)
+      return spv::Op::OpINotEqual;
+    if (isFloatType)
+      return spv::Op::OpFOrdNotEqual;
+  } break;
+  // According to HLSL doc, all sides of the && and || expression are always
+  // evaluated.
+  case BO_LAnd:
+    return spv::Op::OpLogicalAnd;
+  case BO_LOr:
+    return spv::Op::OpLogicalOr;
     BIN_OP_CASE_INT_FLOAT(Add, IAdd, FAdd);
     BIN_OP_CASE_INT_FLOAT(AddAssign, IAdd, FAdd);
     BIN_OP_CASE_INT_FLOAT(Sub, ISub, FSub);
@@ -1328,8 +1350,6 @@ case BO_##kind : {                                                             \
                                 FOrdGreaterThan);
     BIN_OP_CASE_SINT_UINT_FLOAT(GE, SGreaterThanEqual, UGreaterThanEqual,
                                 FOrdGreaterThanEqual);
-    BIN_OP_CASE_INT_FLOAT(EQ, IEqual, FOrdEqual);
-    BIN_OP_CASE_INT_FLOAT(NE, INotEqual, FOrdNotEqual);
     BIN_OP_CASE_SINT_UINT(And, BitwiseAnd, BitwiseAnd);
     BIN_OP_CASE_SINT_UINT(AndAssign, BitwiseAnd, BitwiseAnd);
     BIN_OP_CASE_SINT_UINT(Or, BitwiseOr, BitwiseOr);
@@ -1340,12 +1360,6 @@ case BO_##kind : {                                                             \
     BIN_OP_CASE_SINT_UINT(ShlAssign, ShiftLeftLogical, ShiftLeftLogical);
     BIN_OP_CASE_SINT_UINT(Shr, ShiftRightArithmetic, ShiftRightLogical);
     BIN_OP_CASE_SINT_UINT(ShrAssign, ShiftRightArithmetic, ShiftRightLogical);
-  // According to HLSL doc, all sides of the && and || expression are always
-  // evaluated.
-  case BO_LAnd:
-    return spv::Op::OpLogicalAnd;
-  case BO_LOr:
-    return spv::Op::OpLogicalOr;
   default:
     break;
   }

+ 10 - 0
tools/clang/test/CodeGenSPIRV/binary-op.comparison.scalar.hlsl

@@ -5,6 +5,7 @@ void main() {
     int a, b;
     uint i, j;
     float o, p;
+    bool x, y;
 
 // CHECK:      [[a0:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[b0:%\d+]] = OpLoad %int %b
@@ -80,4 +81,13 @@ void main() {
 // CHECK-NEXT: [[p5:%\d+]] = OpLoad %float %p
 // CHECK-NEXT: {{%\d+}} = OpFOrdNotEqual %bool [[o5]] [[p5]]
     r = o != p;
+
+// CHECK:      [[x0:%\d+]] = OpLoad %bool %x
+// CHECK-NEXT: [[y0:%\d+]] = OpLoad %bool %y
+// CHECK-NEXT: {{%\d+}} = OpLogicalEqual %bool [[x0]] [[y0]]
+    r = x == y;
+// CHECK:      [[x1:%\d+]] = OpLoad %bool %x
+// CHECK-NEXT: [[y1:%\d+]] = OpLoad %bool %y
+// CHECK-NEXT: {{%\d+}} = OpLogicalNotEqual %bool [[x1]] [[y1]]
+    r = x != y;
 }

+ 10 - 0
tools/clang/test/CodeGenSPIRV/binary-op.comparison.vector.hlsl

@@ -12,6 +12,7 @@ void main() {
     int2   i, j;
     uint3  m, n;
     float4 o, p;
+    bool2  x, y;
 
 // CHECK:      [[a0:%\d+]] = OpLoad %int %a
 // CHECK-NEXT: [[b0:%\d+]] = OpLoad %int %b
@@ -112,4 +113,13 @@ void main() {
 // CHECK-NEXT: [[p5:%\d+]] = OpLoad %v4float %p
 // CHECK-NEXT: {{%\d+}} = OpFOrdNotEqual %v4bool [[o5]] [[p5]]
     r4 = o != p;
+
+// CHECK:      [[x0:%\d+]] = OpLoad %v2bool %x
+// CHECK-NEXT: [[y0:%\d+]] = OpLoad %v2bool %y
+// CHECK-NEXT: {{%\d+}} = OpLogicalEqual %v2bool [[x0]] [[y0]]
+    r2 = x == y;
+// CHECK:      [[x1:%\d+]] = OpLoad %v2bool %x
+// CHECK-NEXT: [[y1:%\d+]] = OpLoad %v2bool %y
+// CHECK-NEXT: {{%\d+}} = OpLogicalNotEqual %v2bool [[x1]] [[y1]]
+    r2 = x != y;
 }