Browse Source

Fix detection of inner UDT ptr used by lowered intrinsic (DispatchMesh) (#3713)

- In constant GEP case, the outer structure would be reported as used by
the intrinsic, preventing SROA of outer struct and resulting in the wrong
type for the intrinsic.
Tex Riddell 4 years ago
parent
commit
162a1587c6

+ 3 - 3
lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp

@@ -334,12 +334,12 @@ static unsigned IsPtrUsedByLoweredFn(
             "otherwise, multiple uses in single call");
       }
 
-    } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(user)) {
+    } else if (GEPOperator *GEP = dyn_cast<GEPOperator>(user)) {
       // Not what we are looking for if GEP result is not [array of] struct.
       // If use is under struct member, we can still SROA the outer struct.
       if (!dxilutil::StripArrayTypes(GEP->getType()->getPointerElementType())
             ->isStructTy() ||
-          FindFirstStructMemberIdxInGEP(cast<GEPOperator>(GEP)))
+          FindFirstStructMemberIdxInGEP(GEP))
         continue;
       if (IsPtrUsedByLoweredFn(user, CollectedUses))
         bFound = true;
@@ -350,7 +350,7 @@ static unsigned IsPtrUsedByLoweredFn(
 
     } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(user)) {
       unsigned opcode = CE->getOpcode();
-      if (opcode == Instruction::AddrSpaceCast || opcode == Instruction::GetElementPtr)
+      if (opcode == Instruction::AddrSpaceCast)
         if (IsPtrUsedByLoweredFn(user, CollectedUses))
           bFound = true;
     }

+ 35 - 0
tools/clang/test/HLSLFileCheck/shader_targets/mesh/as-groupshared-nested-payload.hlsl

@@ -0,0 +1,35 @@
+// RUN: %dxc -E amplification -T as_6_5 %s | FileCheck %s
+
+// Make sure we pass groupshared mesh payload directly into DispatchMesh,
+// with correct type, and no alloca involved.
+
+// CHECK: define void @amplification
+// CHECK-NOT: alloca
+// CHECK-NOT: addrspacecast
+// CHECK-NOT: bitcast
+// CHECK: call void @dx.op.dispatchMesh.struct.MeshPayload{{[^ ]*}}(i32 173, i32 1, i32 1, i32 1, %struct.MeshPayload{{[^ ]*}} addrspace(3)*
+// CHECK-NOT: addrspacecast
+// CHECK: ret void
+
+struct MeshPayload
+{
+  float arr[3];
+  uint4 data;
+};
+
+struct GSStruct
+{
+  MeshPayload pld;
+  MeshPayload pld2;
+};
+
+groupshared GSStruct gs;
+GSStruct cb_gs;
+
+[numthreads(4,1,1)]
+void amplification(uint gtid : SV_GroupIndex)
+{
+//  gs = cb_gs;
+  gs.pld.data[gtid] = gtid;
+  DispatchMesh(1,1,1,gs.pld);
+}

+ 3 - 2
tools/clang/test/HLSLFileCheck/shader_targets/mesh/as-groupshared-payload.hlsl

@@ -1,13 +1,14 @@
 // RUN: %dxc -E amplification -T as_6_5 %s | FileCheck %s
 
-// Make sure we pass constant gep of groupshared mesh payload directly
+// Make sure we pass groupshared mesh payload directly
 // in to DispatchMesh, with no alloca involved.
 
 // CHECK: define void @amplification
 // CHECK-NOT: alloca
 // CHECK-NOT: addrspacecast
 // CHECK-NOT: bitcast
-// CHECK: call void @dx.op.dispatchMesh.struct.MeshPayload{{[^ ]*}}(i32 173, i32 1, i32 1, i32 1, %struct.MeshPayload{{[^ ]*}} addrspace(3)* getelementptr inbounds (%struct.GSStruct{{[^ ]*}}, %struct.GSStruct{{[^ ]*}} addrspace(3)* @"\01?gs@@3UGSStruct@@A{{[^ ]*}}", i32 0, i32 1))
+// CHECK: call void @dx.op.dispatchMesh.struct.MeshPayload{{[^ ]*}}(i32 173, i32 1, i32 1, i32 1, %struct.MeshPayload{{[^ ]*}} addrspace(3)*
+// CHECK-NOT: addrspacecast
 // CHECK: ret void
 
 struct MeshPayload