Sfoglia il codice sorgente

[spirv] OpLoad for lvalue operands of binary operators (#1020)

Some times we won't have proper LValueToRValue implicit cast for
binary operator operands; HLSLVectorElementExpr is one example.
Lei Zhang 7 anni fa
parent
commit
37e3ec9ebf

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

@@ -4538,18 +4538,18 @@ SpirvEvalInfo SPIRVEmitter::processBinaryOp(const Expr *lhs, const Expr *rhs,
   SpirvEvalInfo rhsVal = 0, lhsPtr = 0, lhsVal = 0;
   if (BinaryOperator::isCompoundAssignmentOp(opcode)) {
     // Evalute rhs before lhs
-    rhsVal = doExpr(rhs);
+    rhsVal = loadIfGLValue(rhs);
     lhsVal = lhsPtr = doExpr(lhs);
     // This is a compound assignment. We need to load the lhs value if lhs
     // is not already rvalue and does not generate a vector shuffle.
     if (!lhsPtr.isRValue() && !isVectorShuffle(lhs)) {
-      const uint32_t lhsTy = typeTranslator.translateType(lhs->getType());
-      lhsVal = theBuilder.createLoad(lhsTy, lhsPtr);
+      lhsVal = loadIfGLValue(lhs, lhsPtr);
     }
   } else {
     // Evalute lhs before rhs
-    lhsVal = lhsPtr = doExpr(lhs);
-    rhsVal = doExpr(rhs);
+    lhsPtr = doExpr(lhs);
+    lhsVal = loadIfGLValue(lhs, lhsPtr);
+    rhsVal = loadIfGLValue(rhs);
   }
 
   if (lhsInfo)

+ 15 - 1
tools/clang/test/CodeGenSPIRV/op.vector.swizzle.size1.hlsl

@@ -1,7 +1,11 @@
 // Run: %dxc -T vs_6_0 -E main
 
-void main() {
+struct S { float4 f; };
+StructuredBuffer<S> PerFrame;
+
+void main(float4 input: INPUT) {
 // CHECK-LABEL: %bb_entry = OpLabel
+    float4 v4f;
     float2 v2f;
     float1 v1f1, v1f2;
     float sf;
@@ -36,4 +40,14 @@ void main() {
 // CHECK-NEXT: [[v5:%\d+]] = OpLoad %float %v1f1
 // CHECK-NEXT: OpStore %v1f2 [[v5]]
     v1f2.x.r.x = v1f1.r.x.r;
+
+    // Selecting from resources
+// CHECK:      [[fptr:%\d+]] = OpAccessChain %_ptr_Uniform_v4float %PerFrame %int_0 %uint_5 %int_0
+// CHECK-NEXT: [[elem:%\d+]] = OpAccessChain %_ptr_Uniform_float [[fptr]] %int_3
+// CHECK-NEXT:      {{%\d+}} = OpLoad %float [[elem]]
+    v4f = input * PerFrame[5].f.www.r;
+// CHECK:      [[fptr:%\d+]] = OpAccessChain %_ptr_Uniform_v4float %PerFrame %int_0 %uint_6 %int_0
+// CHECK-NEXT: [[elem:%\d+]] = OpAccessChain %_ptr_Uniform_float [[fptr]] %int_2
+// CHECK-NEXT:      {{%\d+}} = OpLoad %float [[elem]]
+    sf = PerFrame[6].f.zzz.r * input.y;
 }