Selaa lähdekoodia

[spirv] convertBitwidth should do nothing for literal types. (#2062)

When converting from one type to another, we first convert to the proper
bitwidth, and then perform type cast. For example, converting a 64-bit
int to a 32-bit float is done by first converting the 64-bit int
to a 32-bit int (OpSConvert), and then converting the 32-bit int to a
32-bit float (OpConvertSToF).

If the "from type" or "to type" for the conversion is a 'literal type',
then we should not perform the bitwidth conversion. The
LiteralTypeVisitor should deduce the right type for the literal.
Ehsan 6 vuotta sitten
vanhempi
commit
1341ec1e19

+ 4 - 7
tools/clang/lib/SPIRV/SpirvEmitter.cpp

@@ -6191,13 +6191,10 @@ SpirvInstruction *SpirvEmitter::convertBitwidth(SpirvInstruction *fromVal,
                                                 QualType fromType,
                                                 QualType toType,
                                                 QualType *resultType) {
-  // At the moment, we will not make bitwidth conversions for literal int and
-  // literal float types because they always indicate 64-bit and do not
-  // represent what SPIR-V was actually resolved to.
-  // TODO: If the evaluated type is added to SpirvEvalInfo, change 'fromVal' to
-  // SpirvEvalInfo and use it to handle literal types more accurately.
-  if (fromType->isSpecificBuiltinType(BuiltinType::LitFloat) ||
-      fromType->isSpecificBuiltinType(BuiltinType::LitInt))
+  // At the moment, we will not make bitwidth conversions to/from literal int
+  // and literal float types because they do not represent the intended SPIR-V
+  // bitwidth.
+  if (isLitTypeOrVecOfLitType(fromType) || isLitTypeOrVecOfLitType(toType))
     return fromVal;
 
   const auto fromBitwidth = getElementSpirvBitwidth(

+ 10 - 0
tools/clang/test/CodeGenSPIRV/var.init.struct.hlsl

@@ -33,6 +33,10 @@ struct P {
     float z;
 };
 
+struct W {
+  float4 color;
+};
+
 void main() {
 // CHECK-LABEL: %bb_entry = OpLabel
 
@@ -88,4 +92,10 @@ void main() {
            s2,          // Embedded struct
            s2           // Decomposing struct + type casting
           };
+
+    // Using InitListExpr
+// CHECK:        [[int4_zero:%\d+]] = OpCompositeConstruct %v4int %int_0 %int_0 %int_0 %int_0
+// CHECK-NEXT: [[float4_zero:%\d+]] = OpConvertSToF %v4float [[int4_zero]]
+// CHECK-NEXT:             {{%\d+}} = OpCompositeConstruct %W [[float4_zero]]
+    W w = { (0).xxxx };
 }