Browse Source

Fixed bug where allocas get inserted at the wrong place. (#2140)

Adam Yang 6 years ago
parent
commit
cfb330ef56

+ 3 - 3
tools/clang/lib/CodeGen/CGExprCXX.cpp

@@ -198,7 +198,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
         This = EmitLValue(Base).getAddress();
       } else {
         llvm::Value *Val = EmitScalarExpr(Base);
-        This = Builder.CreateAlloca(Val->getType());
+        This = CreateTempAlloca(Val->getType());
         CGM.getHLSLRuntime().EmitHLSLMatrixStore(*this, Val, This, Base->getType());
       }
 
@@ -222,7 +222,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
           This = LV.getAddress();
           if (isa<ExtMatrixElementExpr>(Base)) {
             llvm::Value *Val = Builder.CreateLoad(This);
-            This = Builder.CreateAlloca(Val->getType());
+            This = CreateTempAlloca(Val->getType());
             Builder.CreateStore(Val, This);
           }
         } else {
@@ -245,7 +245,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
         }
       } else {
         llvm::Value *Val = EmitScalarExpr(Base);
-        This = Builder.CreateAlloca(Val->getType());
+        This = CreateTempAlloca(Val->getType());
         Builder.CreateStore(Val, This);
       }
       bool isBool = false;

+ 3 - 3
tools/clang/test/CodeGenHLSL/batch/misc/RValSubscript.hlsl

@@ -1,6 +1,7 @@
 // RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
 
-// CHECK: alloca [16 x i32]
+// CHECK-DAG: alloca [16 x i32]
+// CHECK-DAG: alloca [4 x i1]
 
 // For b4[2]
 // CHECK: cbufferLoadLegacy
@@ -30,7 +31,6 @@
 // CHECK: fcmp fast olt
 // CHECK: fcmp fast olt
 // CHECK: fcmp fast olt
-// CHECK: alloca [4 x i1]
 
 // For (xt == 0)[i][i]
 // CHECK: fcmp fast oeq
@@ -63,4 +63,4 @@ float4 main(uint4 a : A) : SV_TARGET
   x += (x4 < i)[i];
   x += (xt == 6)[i][i];
   return x;
-}
+}

+ 32 - 0
tools/clang/test/CodeGenHLSL/batch/misc/gv_memcpy_before_alloca.hlsl

@@ -0,0 +1,32 @@
+// RUN: %dxc /Od /T vs_6_0 /E main %s | FileCheck %s
+
+// Regression check for a case with /Od where there is a static variable struct
+// write before an alloca. As part of the algorithm to replace all uses of the
+// GV before initialization with 0's, the basic block is split where the first
+// memcpy occurs. This may cause alloca's to get stuck in a non-emtry block and
+// be missed by lowering transformations, such as in this example, an alloca of
+// <16 x float> sticks around.
+
+// CHECK: void @main
+
+float4x4 make(float4 a, float4 b, float4 c, float4 d)
+{
+ float4x4 mat;
+ mat._11_21_31_41 = a;
+ mat._12_22_32_42 = b;
+ mat._13_23_33_43 = c;
+ mat._14_24_34_44 = d;
+ return mat;
+}
+struct A {
+ float2 foo;
+};
+
+static A glob_a;
+
+void main()
+{
+ A a;
+ glob_a = a;
+ float3 b = float3(make(0, 1, 2, float4(0,0,0,1))[3].xyz);
+}