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.
This commit is contained in:
Tex Riddell 2021-04-26 17:25:50 -07:00 коммит произвёл GitHub
Родитель 88ddd4c978
Коммит 162a1587c6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 41 добавлений и 5 удалений

Просмотреть файл

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

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -1,13 +1,14 @@
// RUN: %dxc -E amplification -T as_6_5 %s | FileCheck %s // 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. // in to DispatchMesh, with no alloca involved.
// CHECK: define void @amplification // CHECK: define void @amplification
// CHECK-NOT: alloca // CHECK-NOT: alloca
// CHECK-NOT: addrspacecast // CHECK-NOT: addrspacecast
// CHECK-NOT: bitcast // 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 // CHECK: ret void
struct MeshPayload struct MeshPayload