Browse Source

[spirv] Fix cast function when src type is literal (#988)

Ehsan 7 years ago
parent
commit
72d4fcc4e0

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

@@ -4820,8 +4820,9 @@ uint32_t SPIRVEmitter::castToInt(const uint32_t fromVal, QualType fromType,
   uint32_t intType = typeTranslator.translateType(toIntType);
 
   // AST may include a 'literal int' to 'int' conversion. No-op.
+  // 'literal int' to 'uint' must still go through conversion.
   if (fromType->isSpecificBuiltinType(BuiltinType::LitInt) &&
-      typeTranslator.translateType(fromType) == intType)
+      toIntType->isSignedIntegerType())
     return fromVal;
 
   if (isBoolOrVecOfBoolType(fromType)) {
@@ -6936,11 +6937,10 @@ uint32_t SPIRVEmitter::tryToEvaluateAsFloat32(const llvm::APFloat &floatValue) {
   return 0;
 }
 
-uint32_t SPIRVEmitter::translateAPFloat(const llvm::APFloat &floatValue,
+uint32_t SPIRVEmitter::translateAPFloat(llvm::APFloat floatValue,
                                         QualType targetType) {
-  // The float value may have to go through conversion, so work on a local copy.
-  llvm::APFloat value = floatValue;
-  const auto valueBitwidth = llvm::APFloat::getSizeInBits(value.getSemantics());
+  const auto valueBitwidth =
+      llvm::APFloat::getSizeInBits(floatValue.getSemantics());
 
   // Find out the target bitwidth.
   targetType = typeTranslator.getIntendedLiteralType(targetType);
@@ -6956,18 +6956,18 @@ uint32_t SPIRVEmitter::translateAPFloat(const llvm::APFloat &floatValue,
         targetBitwidth == 16 ? llvm::APFloat::IEEEhalf
                              : targetBitwidth == 32 ? llvm::APFloat::IEEEsingle
                                                     : llvm::APFloat::IEEEdouble;
-    value.convert(targetSemantics, llvm::APFloat::roundingMode::rmTowardZero,
-                  &losesInfo);
+    floatValue.convert(targetSemantics,
+                       llvm::APFloat::roundingMode::rmTowardZero, &losesInfo);
   }
 
   switch (targetBitwidth) {
   case 16:
     return theBuilder.getConstantFloat16(
-        static_cast<uint16_t>(value.bitcastToAPInt().getZExtValue()));
+        static_cast<uint16_t>(floatValue.bitcastToAPInt().getZExtValue()));
   case 32:
-    return theBuilder.getConstantFloat32(value.convertToFloat());
+    return theBuilder.getConstantFloat32(floatValue.convertToFloat());
   case 64:
-    return theBuilder.getConstantFloat64(value.convertToDouble());
+    return theBuilder.getConstantFloat64(floatValue.convertToDouble());
   default:
     break;
   }

+ 1 - 2
tools/clang/lib/SPIRV/SPIRVEmitter.h

@@ -431,8 +431,7 @@ private:
 
   /// Translates the given frontend APFloat into its SPIR-V equivalent for the
   /// given targetType.
-  uint32_t translateAPFloat(const llvm::APFloat &floatValue,
-                            QualType targetType);
+  uint32_t translateAPFloat(llvm::APFloat floatValue, QualType targetType);
 
   /// Tries to evaluate the given Expr as a constant and returns the <result-id>
   /// if success. Otherwise, returns 0.

+ 0 - 1
tools/clang/test/CodeGenSPIRV/op.array.access.hlsl

@@ -57,4 +57,3 @@ float main(float val: A, uint index: B) : C {
 
     return r;
 }
-// CHECK-WHOLE-SPIR-V:

+ 4 - 1
tools/clang/test/CodeGenSPIRV/ternary-op.cond-op.hlsl

@@ -80,9 +80,12 @@ void main() {
 // CHECK-NEXT:       {{%\d+}} = OpConvertSToF %float [[a_int]]
     float a = cond ? 1 : 0;
 
-
 // CHECK:      [[c_long:%\d+]] = OpSelect %long {{%\d+}} %long_3000000000 %long_4000000000
 // CHECK-NEXT:        {{%\d+}} = OpConvertSToF %float [[c_long]]
     // TODO: Use OpSConvert to first convert long to int. Then use OpConvertSToF.
     float c = cond ? 3000000000 : 4000000000;
+
+// CHECK:      [[d_int:%\d+]] = OpSelect %int {{%\d+}} %int_1 %int_0
+// CHECK-NEXT:       {{%\d+}} = OpBitcast %uint [[d_int]]
+    uint d = cond ? 1 : 0;
 }