Преглед изворни кода

Fix regression in lib vector arg case when skipping copy-out (#3232)

Tex Riddell пре 4 година
родитељ
комит
600c06a3f5

+ 12 - 2
lib/HLSL/HLLegalizeParameter.cpp

@@ -81,8 +81,18 @@ bool isPointerNeedToLower(Value *V, Type *HandleTy) {
     V = GEP->getPointerOperand();
   }
   CallInst *CI = dyn_cast<CallInst>(V);
-  if (!CI)
-    return false;
+  if (!CI) {
+    // If array of vector, we need a copy to handle vector to array in LowerTypePasses.
+    Type *Ty = V->getType();
+    if (Ty->isPointerTy())
+      Ty = Ty->getPointerElementType();
+    if (!Ty->isArrayTy())
+      return false;
+    while (Ty->isArrayTy()) {
+      Ty = Ty->getArrayElementType();
+    }
+    return Ty->isVectorTy();
+  }
   HLOpcodeGroup group = GetHLOpcodeGroup(CI->getCalledFunction());
   if (group != HLOpcodeGroup::HLSubscript)
     return false;

+ 44 - 0
tools/clang/test/HLSLFileCheck/shader_targets/library/lib-copy-vec.hlsl

@@ -0,0 +1,44 @@
+// RUN: %dxc -T lib_6_3 -D INIT=array[0],array[1] -D ACCUM=array[0]+array[1] %s | FileCheck %s -check-prefixes=CHECK,VEC
+// RUN: %dxc -T lib_6_3 -D INIT=s_array[0],s_array[1] -D ACCUM=s_array[0]+s_array[1] %s | FileCheck %s -check-prefixes=CHECK,VEC
+
+// RUN: %dxc -T lib_6_3 -D INIT=f0,f1 -D ACCUM=f0+f1 %s | FileCheck %s -check-prefixes=CHECK,VEC
+// RUN: %dxc -T lib_6_3 -D INIT=s_f0,s_f1 -D ACCUM=s_f0+s_f1 %s | FileCheck %s -check-prefixes=CHECK,VEC
+
+// RUN: %dxc -T lib_6_3 -D INIT=agg -D ACCUM=agg.f3 %s | FileCheck %s -check-prefixes=CHECK,AGG
+// RUN: %dxc -T lib_6_3 -D INIT=s_agg -D ACCUM=s_agg.f3 %s | FileCheck %s -check-prefixes=CHECK,AGG
+
+// RUN: %dxc -T lib_6_3 -D INIT=agg -D ACCUM=agg.array[0]+agg.array[1] -D ARRAY %s | FileCheck %s -check-prefixes=CHECK,AGG
+// RUN: %dxc -T lib_6_3 -D INIT=s_agg -D ACCUM=s_agg.array[0]+s_agg.array[1] -D ARRAY %s | FileCheck %s -check-prefixes=CHECK,AGG
+
+// CHECK: define <3 x float> @"\01?main@@YA?AV?$vector@M$02@@XZ"()
+// VEC: alloca <3 x float>
+// VEC: alloca <3 x float>
+// AGG: alloca %struct.Agg
+// CHECK-NOT: alloca
+
+struct Agg {
+#ifdef ARRAY
+  float3 array[2];
+#else
+  float3 f3;
+#endif
+};
+
+void get(out float3 f0, out float3 f1);
+void get(out Agg agg);
+
+static float3 s_array[2];
+static float3 s_f0, s_f1;
+static Agg s_agg;
+
+export
+float3 main() {
+  float3 result = 0;
+
+  float3 array[2];
+  float3 f0, f1;
+  Agg agg;
+
+  get(INIT);
+  return ACCUM;
+}