2
0
Эх сурвалжийг харах

[spirv] Fix wrong type when casting bool to literal int (#928)

Lei Zhang 7 жил өмнө
parent
commit
dfff2c0e15

+ 10 - 1
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -4465,7 +4465,7 @@ uint32_t SPIRVEmitter::castToInt(const uint32_t fromVal, QualType fromType,
   if (isSameScalarOrVecType(fromType, toIntType))
     return fromVal;
 
-  const uint32_t intType = typeTranslator.translateType(toIntType);
+  uint32_t intType = typeTranslator.translateType(toIntType);
 
   // AST may include a 'literal int' to 'int' conversion. No-op.
   if (fromType->isLiteralType(astContext) && fromType->isIntegerType() &&
@@ -4475,6 +4475,15 @@ uint32_t SPIRVEmitter::castToInt(const uint32_t fromVal, QualType fromType,
   if (isBoolOrVecOfBoolType(fromType)) {
     const uint32_t one = getValueOne(toIntType);
     const uint32_t zero = getValueZero(toIntType);
+    if (toIntType->isScalarType() && toIntType->isLiteralType(astContext)) {
+      // Special case for handling casting from boolean values to literal ints.
+      // For source code like (a == b) != 5, an IntegralCast will be inserted
+      // for (a == b), whose return type will be 64-bit integer if following the
+      // normal path.
+      // TODO: This is not beautiful. But other ways are even worse.
+      intType = toIntType->isSignedIntegerType() ? theBuilder.getInt32Type()
+                                                 : theBuilder.getUint32Type();
+    }
     return theBuilder.createSelect(intType, fromVal, one, zero);
   }
 

+ 9 - 0
tools/clang/test/CodeGenSPIRV/cast.2literal-int.implicit.hlsl

@@ -0,0 +1,9 @@
+// Run: %dxc -T vs_6_0 -E main
+
+bool main(int a : A, int b : B) : C {
+// CHECK:       [[a:%\d+]] = OpLoad %int %a
+// CHECK-NEXT:  [[b:%\d+]] = OpLoad %int %b
+// CHECK-NEXT: [[eq:%\d+]] = OpIEqual %bool [[a]] [[b]]
+// CHECK-NEXT:    {{%\d+}} = OpSelect %int [[eq]] %int_1 %int_0
+    return (a == b) != 0;
+}

+ 3 - 0
tools/clang/unittests/SPIRV/CodeGenSPIRVTest.cpp

@@ -288,6 +288,9 @@ TEST_F(FileTest, CastImplicit2UInt) { runFileTest("cast.2uint.implicit.hlsl"); }
 TEST_F(FileTest, CastExplicit2UInt) { runFileTest("cast.2uint.explicit.hlsl"); }
 TEST_F(FileTest, CastImplicit2FP) { runFileTest("cast.2fp.implicit.hlsl"); }
 TEST_F(FileTest, CastExplicit2FP) { runFileTest("cast.2fp.explicit.hlsl"); }
+TEST_F(FileTest, CastImplicit2LiteralInt) {
+  runFileTest("cast.2literal-int.implicit.hlsl");
+}
 TEST_F(FileTest, CastImplicitFlatConversion) {
   runFileTest("cast.flat-conversion.implicit.hlsl");
 }