Skip to content

Commit 053e7ac

Browse files
authored
Refactor udt intrinsic arg copy to before SROA, flatten RayDesc (#7440)
Intrinsics that take UDT arguments need copy-in/copy-out. Other aggregate args are flattened for intrinsic calls. Previously, these operations were intermingled, driven by SROA on alloca/GV values. There were RayDesc arguments that weren't treated consistently, and weren't copied in when necessary, leading to problems. They should be flattened into the intrinsic arguments, but TraceRay calls didn't do this. This change: - flattens RayDesc args for all intrinsics that use them. - separates the copy-in/copy-out generation into a separate operation before SROA. Ideally, this copy-in/copy-out would have been generated by CodeGen based on by-value passing, but that's a deeper intrinsic AST issue potentially. - Updated and added tests. Fixes #7434.
1 parent fef2f94 commit 053e7ac

18 files changed

+1375
-481
lines changed

include/dxc/DXIL/DxilConstants.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1583,6 +1583,10 @@ const unsigned kMSStoreOutputColOpIdx = 3;
15831583
const unsigned kMSStoreOutputVIdxOpIdx = 4;
15841584
const unsigned kMSStoreOutputValOpIdx = 5;
15851585

1586+
// HitObject::MakeMiss
1587+
const unsigned kHitObjectMakeMiss_RayDescOpIdx = 3;
1588+
const unsigned kHitObjectMakeMiss_NumOp = 11;
1589+
15861590
// HitObject::TraceRay
15871591
const unsigned kHitObjectTraceRay_RayDescOpIdx = 7;
15881592
const unsigned kHitObjectTraceRay_PayloadOpIdx = 15;

include/dxc/HLSL/HLOperations.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,12 @@ const unsigned kAnnotateHandleResourceTypeOpIdx = 3;
396396

397397
// TraceRay.
398398
const unsigned kTraceRayRayDescOpIdx = 7;
399-
const unsigned kTraceRayPayLoadOpIdx = 8;
399+
// kTraceRayPayloadPreOpIdx is before flattening the RayDesc
400+
const unsigned kTraceRayPayloadPreOpIdx = 8;
401+
// kTraceRayPayloadOpIdx is after flattening the RayDesc
402+
const unsigned kTraceRayPayloadOpIdx = 11;
403+
const unsigned kTraceRay_PreNumOp = 9;
404+
const unsigned kTraceRay_NumOp = 12;
400405

401406
// AllocateRayQuery
402407
const unsigned kAllocateRayQueryRayFlagsIdx = 1;
@@ -407,6 +412,10 @@ const unsigned kCallShaderPayloadOpIdx = 2;
407412

408413
// TraceRayInline.
409414
const unsigned kTraceRayInlineRayDescOpIdx = 5;
415+
// kTraceRayInlinePayloadPreOpIdx is before flattening the RayDesc
416+
const unsigned kTraceRayInlinePayloadPreOpIdx = 6;
417+
// kTraceRayInlinePayloadOpIdx is after flattening the RayDesc
418+
const unsigned kTraceRayInlinePayloadOpIdx = 9;
410419

411420
// ReportIntersection.
412421
const unsigned kReportIntersectionAttributeOpIdx = 3;
@@ -435,11 +444,19 @@ const unsigned kAnnotateNodeRecordHandleNodeRecordPropIdx = 2;
435444

436445
// HitObject::MakeMiss
437446
const unsigned kHitObjectMakeMiss_NumOp = 8;
438-
const unsigned kHitObjectMakeMissRayDescOpIdx = 4;
447+
const unsigned kHitObjectMakeMiss_RayDescOpIdx = 4;
439448

440449
// HitObject::TraceRay
441450
const unsigned kHitObjectTraceRay_RayDescOpIdx = 8;
442-
const unsigned kHitObjectTraceRay_NumOp = 10;
451+
// kHitObjectTraceRay_PayloadPreOpIdx is before flattening the RayDesc
452+
const unsigned kHitObjectTraceRay_PayloadPreOpIdx = 9;
453+
// kHitObjectTraceRay_PayloadOpIdx is after flattening the RayDesc
454+
const unsigned kHitObjectTraceRay_PayloadOpIdx = 12;
455+
const unsigned kHitObjectTraceRay_PreNumOp = 10;
456+
const unsigned kHitObjectTraceRay_NumOp = 13;
457+
458+
// HitObject::Invoke
459+
const unsigned kHitObjectInvoke_PayloadOpIdx = 2;
443460

444461
// HitObject::FromRayQuery
445462
const unsigned kHitObjectFromRayQuery_WithAttrs_AttributeOpIdx = 4;

lib/HLSL/HLOperationLower.cpp

Lines changed: 86 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -5720,37 +5720,24 @@ Value *TranslateCallShader(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
57205720
return Builder.CreateCall(F, {opArg, ShaderIndex, Parameter});
57215721
}
57225722

5723-
static unsigned LoadRayDescElementsIntoArgs(Value **Args, hlsl::OP *OP,
5724-
IRBuilder<> &Builder,
5725-
Value *RayDescPtr, unsigned Index) {
5726-
// struct RayDesc
5727-
//{
5728-
// float3 Origin;
5729-
// float TMin;
5730-
// float3 Direction;
5731-
// float TMax;
5732-
//};
5733-
Value *ZeroIdx = OP->GetU32Const(0);
5734-
Value *Origin = Builder.CreateGEP(RayDescPtr, {ZeroIdx, ZeroIdx});
5735-
Origin = Builder.CreateLoad(Origin);
5736-
Args[Index++] = Builder.CreateExtractElement(Origin, (uint64_t)0);
5737-
Args[Index++] = Builder.CreateExtractElement(Origin, 1);
5738-
Args[Index++] = Builder.CreateExtractElement(Origin, 2);
5739-
5740-
Value *TMinPtr = Builder.CreateGEP(RayDescPtr, {ZeroIdx, OP->GetU32Const(1)});
5741-
Args[Index++] = Builder.CreateLoad(TMinPtr);
5742-
5743-
Value *DirectionPtr =
5744-
Builder.CreateGEP(RayDescPtr, {ZeroIdx, OP->GetU32Const(2)});
5745-
Value *Direction = Builder.CreateLoad(DirectionPtr);
5746-
5747-
Args[Index++] = Builder.CreateExtractElement(Direction, (uint64_t)0);
5748-
Args[Index++] = Builder.CreateExtractElement(Direction, 1);
5749-
Args[Index++] = Builder.CreateExtractElement(Direction, 2);
5750-
5751-
Value *TMaxPtr = Builder.CreateGEP(RayDescPtr, {ZeroIdx, OP->GetU32Const(3)});
5752-
Args[Index++] = Builder.CreateLoad(TMaxPtr);
5753-
return Index;
5723+
static void TransferRayDescArgs(Value **Args, hlsl::OP *OP,
5724+
IRBuilder<> &Builder, CallInst *CI,
5725+
unsigned &Index, unsigned &HLIndex) {
5726+
// Extract elements from flattened ray desc arguments in HL op.
5727+
// float3 Origin;
5728+
Value *origin = CI->getArgOperand(HLIndex++);
5729+
Args[Index++] = Builder.CreateExtractElement(origin, (uint64_t)0);
5730+
Args[Index++] = Builder.CreateExtractElement(origin, 1);
5731+
Args[Index++] = Builder.CreateExtractElement(origin, 2);
5732+
// float TMin;
5733+
Args[Index++] = CI->getArgOperand(HLIndex++);
5734+
// float3 Direction;
5735+
Value *direction = CI->getArgOperand(HLIndex++);
5736+
Args[Index++] = Builder.CreateExtractElement(direction, (uint64_t)0);
5737+
Args[Index++] = Builder.CreateExtractElement(direction, 1);
5738+
Args[Index++] = Builder.CreateExtractElement(direction, 2);
5739+
// float TMax;
5740+
Args[Index++] = CI->getArgOperand(HLIndex++);
57545741
}
57555742

57565743
Value *TranslateTraceRay(CallInst *CI, IntrinsicOp IOP, OP::OpCode OpCode,
@@ -5759,21 +5746,24 @@ Value *TranslateTraceRay(CallInst *CI, IntrinsicOp IOP, OP::OpCode OpCode,
57595746
bool &Translated) {
57605747
hlsl::OP *OP = &Helper.hlslOP;
57615748

5762-
Value *RayDesc = CI->getArgOperand(HLOperandIndex::kTraceRayRayDescOpIdx);
5763-
Value *PayLoad = CI->getArgOperand(HLOperandIndex::kTraceRayPayLoadOpIdx);
5764-
57655749
Value *Args[DXIL::OperandIndex::kTraceRayNumOp];
57665750
Args[0] = OP->GetU32Const(static_cast<unsigned>(OpCode));
5767-
for (unsigned i = 1; i < HLOperandIndex::kTraceRayRayDescOpIdx; i++)
5768-
Args[i] = CI->getArgOperand(i);
5751+
unsigned Index = 1, HLIndex = 1;
5752+
while (HLIndex < HLOperandIndex::kTraceRayRayDescOpIdx)
5753+
Args[Index++] = CI->getArgOperand(HLIndex++);
57695754

57705755
IRBuilder<> Builder(CI);
5771-
LoadRayDescElementsIntoArgs(Args, OP, Builder, RayDesc,
5772-
DXIL::OperandIndex::kTraceRayRayDescOpIdx);
5756+
TransferRayDescArgs(Args, OP, Builder, CI, Index, HLIndex);
5757+
DXASSERT_NOMSG(HLIndex == CI->getNumArgOperands() - 1);
5758+
DXASSERT_NOMSG(Index == DXIL::OperandIndex::kTraceRayPayloadOpIdx);
5759+
5760+
Value *Payload = CI->getArgOperand(HLIndex++);
5761+
Args[Index++] = Payload;
57735762

5774-
Args[DXIL::OperandIndex::kTraceRayPayloadOpIdx] = PayLoad;
5763+
DXASSERT_NOMSG(HLIndex == CI->getNumArgOperands());
5764+
DXASSERT_NOMSG(Index == DXIL::OperandIndex::kTraceRayNumOp);
57755765

5776-
Type *Ty = PayLoad->getType();
5766+
Type *Ty = Payload->getType();
57775767
Function *F = OP->GetOpFunc(OpCode, Ty);
57785768

57795769
return Builder.CreateCall(F, Args);
@@ -5817,33 +5807,16 @@ Value *TranslateTraceRayInline(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
58175807

58185808
Value *Args[DXIL::OperandIndex::kTraceRayInlineNumOp];
58195809
Args[0] = opArg;
5820-
for (unsigned i = 1; i < HLOperandIndex::kTraceRayInlineRayDescOpIdx; i++) {
5821-
Args[i] = CI->getArgOperand(i);
5822-
}
5810+
unsigned Index = 1, HLIndex = 1;
5811+
while (HLIndex < HLOperandIndex::kTraceRayInlineRayDescOpIdx)
5812+
Args[Index++] = CI->getArgOperand(HLIndex++);
58235813

58245814
IRBuilder<> Builder(CI);
5825-
unsigned hlIndex = HLOperandIndex::kTraceRayInlineRayDescOpIdx;
5826-
unsigned index = DXIL::OperandIndex::kTraceRayInlineRayDescOpIdx;
5827-
5828-
// struct RayDesc
5829-
//{
5830-
// float3 Origin;
5831-
Value *origin = CI->getArgOperand(hlIndex++);
5832-
Args[index++] = Builder.CreateExtractElement(origin, (uint64_t)0);
5833-
Args[index++] = Builder.CreateExtractElement(origin, 1);
5834-
Args[index++] = Builder.CreateExtractElement(origin, 2);
5835-
// float TMin;
5836-
Args[index++] = CI->getArgOperand(hlIndex++);
5837-
// float3 Direction;
5838-
Value *direction = CI->getArgOperand(hlIndex++);
5839-
Args[index++] = Builder.CreateExtractElement(direction, (uint64_t)0);
5840-
Args[index++] = Builder.CreateExtractElement(direction, 1);
5841-
Args[index++] = Builder.CreateExtractElement(direction, 2);
5842-
// float TMax;
5843-
Args[index++] = CI->getArgOperand(hlIndex++);
5844-
//};
5845-
5846-
DXASSERT_NOMSG(index == DXIL::OperandIndex::kTraceRayInlineNumOp);
5815+
DXASSERT_NOMSG(HLIndex == HLOperandIndex::kTraceRayInlineRayDescOpIdx);
5816+
DXASSERT_NOMSG(Index == DXIL::OperandIndex::kTraceRayInlineRayDescOpIdx);
5817+
TransferRayDescArgs(Args, hlslOP, Builder, CI, Index, HLIndex);
5818+
DXASSERT_NOMSG(HLIndex == CI->getNumArgOperands());
5819+
DXASSERT_NOMSG(Index == DXIL::OperandIndex::kTraceRayInlineNumOp);
58475820

58485821
Function *F = hlslOP->GetOpFunc(opcode, Builder.getVoidTy());
58495822

@@ -6197,55 +6170,49 @@ Value *TranslateUnpack(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
61976170

61986171
// Shader Execution Reordering.
61996172
namespace {
6200-
Value *TranslateHitObjectMake(CallInst *CI, IntrinsicOp IOP, OP::OpCode Opcode,
6201-
HLOperationLowerHelper &Helper,
6202-
HLObjectOperationLowerHelper *ObjHelper,
6203-
bool &Translated) {
6173+
Value *TranslateHitObjectMakeNop(CallInst *CI, IntrinsicOp IOP,
6174+
OP::OpCode Opcode,
6175+
HLOperationLowerHelper &Helper,
6176+
HLObjectOperationLowerHelper *ObjHelper,
6177+
bool &Translated) {
62046178
hlsl::OP *HlslOP = &Helper.hlslOP;
62056179
IRBuilder<> Builder(CI);
6206-
unsigned SrcIdx = 1;
6207-
Value *HitObjectPtr = CI->getArgOperand(SrcIdx++);
6208-
if (Opcode == OP::OpCode::HitObject_MakeNop) {
6209-
Value *HitObject = TrivialDxilOperation(
6210-
Opcode, {nullptr}, Type::getVoidTy(CI->getContext()), CI, HlslOP);
6211-
Builder.CreateStore(HitObject, HitObjectPtr);
6212-
DXASSERT(
6213-
CI->use_empty(),
6214-
"Default ctor return type is a Clang artifact. Value must not be used");
6215-
return nullptr;
6216-
}
6180+
Value *HitObjectPtr = CI->getArgOperand(1);
6181+
Value *HitObject = TrivialDxilOperation(
6182+
Opcode, {nullptr}, Type::getVoidTy(CI->getContext()), CI, HlslOP);
6183+
Builder.CreateStore(HitObject, HitObjectPtr);
6184+
DXASSERT(
6185+
CI->use_empty(),
6186+
"Default ctor return type is a Clang artifact. Value must not be used");
6187+
return nullptr;
6188+
}
62176189

6190+
Value *TranslateHitObjectMakeMiss(CallInst *CI, IntrinsicOp IOP,
6191+
OP::OpCode Opcode,
6192+
HLOperationLowerHelper &Helper,
6193+
HLObjectOperationLowerHelper *ObjHelper,
6194+
bool &Translated) {
62186195
DXASSERT_NOMSG(CI->getNumArgOperands() ==
62196196
HLOperandIndex::kHitObjectMakeMiss_NumOp);
6220-
Value *RayFlags = CI->getArgOperand(SrcIdx++);
6221-
Value *MissShaderIdx = CI->getArgOperand(SrcIdx++);
6222-
DXASSERT_NOMSG(SrcIdx == HLOperandIndex::kHitObjectMakeMissRayDescOpIdx);
6223-
Value *RayDescOrigin = CI->getArgOperand(SrcIdx++);
6224-
Value *RayDescOriginX =
6225-
Builder.CreateExtractElement(RayDescOrigin, (uint64_t)0);
6226-
Value *RayDescOriginY =
6227-
Builder.CreateExtractElement(RayDescOrigin, (uint64_t)1);
6228-
Value *RayDescOriginZ =
6229-
Builder.CreateExtractElement(RayDescOrigin, (uint64_t)2);
6230-
6231-
Value *RayDescTMin = CI->getArgOperand(SrcIdx++);
6232-
Value *RayDescDirection = CI->getArgOperand(SrcIdx++);
6233-
Value *RayDescDirectionX =
6234-
Builder.CreateExtractElement(RayDescDirection, (uint64_t)0);
6235-
Value *RayDescDirectionY =
6236-
Builder.CreateExtractElement(RayDescDirection, (uint64_t)1);
6237-
Value *RayDescDirectionZ =
6238-
Builder.CreateExtractElement(RayDescDirection, (uint64_t)2);
6239-
6240-
Value *RayDescTMax = CI->getArgOperand(SrcIdx++);
6197+
hlsl::OP *OP = &Helper.hlslOP;
6198+
IRBuilder<> Builder(CI);
6199+
Value *Args[DXIL::OperandIndex::kHitObjectMakeMiss_NumOp];
6200+
Args[0] = nullptr; // Filled in by TrivialDxilOperation
6201+
6202+
unsigned DestIdx = 1, SrcIdx = 1;
6203+
Value *HitObjectPtr = CI->getArgOperand(SrcIdx++);
6204+
Args[DestIdx++] = CI->getArgOperand(SrcIdx++); // RayFlags
6205+
Args[DestIdx++] = CI->getArgOperand(SrcIdx++); // MissShaderIdx
6206+
6207+
DXASSERT_NOMSG(SrcIdx == HLOperandIndex::kHitObjectMakeMiss_RayDescOpIdx);
6208+
DXASSERT_NOMSG(DestIdx ==
6209+
DXIL::OperandIndex::kHitObjectMakeMiss_RayDescOpIdx);
6210+
TransferRayDescArgs(Args, OP, Builder, CI, DestIdx, SrcIdx);
62416211
DXASSERT_NOMSG(SrcIdx == CI->getNumArgOperands());
6212+
DXASSERT_NOMSG(DestIdx == DXIL::OperandIndex::kHitObjectMakeMiss_NumOp);
62426213

6243-
Value *OutHitObject = TrivialDxilOperation(
6244-
Opcode,
6245-
{nullptr, RayFlags, MissShaderIdx, RayDescOriginX, RayDescOriginY,
6246-
RayDescOriginZ, RayDescTMin, RayDescDirectionX, RayDescDirectionY,
6247-
RayDescDirectionZ, RayDescTMax},
6248-
Helper.voidTy, CI, HlslOP);
6214+
Value *OutHitObject =
6215+
TrivialDxilOperation(Opcode, Args, Helper.voidTy, CI, OP);
62496216
Builder.CreateStore(OutHitObject, HitObjectPtr);
62506217
return nullptr;
62516218
}
@@ -6348,10 +6315,9 @@ Value *TranslateHitObjectTraceRay(CallInst *CI, IntrinsicOp IOP,
63486315
hlsl::OP *OP = &Helper.hlslOP;
63496316
IRBuilder<> Builder(CI);
63506317

6351-
const unsigned DxilNumArgs = DxilInst_HitObject_TraceRay::arg_payload + 1;
63526318
DXASSERT_NOMSG(CI->getNumArgOperands() ==
63536319
HLOperandIndex::kHitObjectTraceRay_NumOp);
6354-
Value *Args[DxilNumArgs];
6320+
Value *Args[DXIL::OperandIndex::kHitObjectTraceRay_NumOp];
63556321
Value *OpArg = OP->GetU32Const(static_cast<unsigned>(OpCode));
63566322
Args[0] = OpArg;
63576323

@@ -6363,13 +6329,19 @@ Value *TranslateHitObjectTraceRay(CallInst *CI, IntrinsicOp IOP,
63636329
Args[DestIdx] = CI->getArgOperand(SrcIdx);
63646330
}
63656331

6366-
Value *RayDescPtr = CI->getArgOperand(SrcIdx++);
6367-
DestIdx = LoadRayDescElementsIntoArgs(Args, OP, Builder, RayDescPtr, DestIdx);
6332+
DXASSERT_NOMSG(SrcIdx == HLOperandIndex::kHitObjectTraceRay_RayDescOpIdx);
6333+
DXASSERT_NOMSG(DestIdx ==
6334+
DXIL::OperandIndex::kHitObjectTraceRay_RayDescOpIdx);
6335+
TransferRayDescArgs(Args, OP, Builder, CI, DestIdx, SrcIdx);
6336+
DXASSERT_NOMSG(SrcIdx == CI->getNumArgOperands() - 1);
6337+
DXASSERT_NOMSG(DestIdx ==
6338+
DXIL::OperandIndex::kHitObjectTraceRay_PayloadOpIdx);
6339+
63686340
Value *Payload = CI->getArgOperand(SrcIdx++);
63696341
Args[DestIdx++] = Payload;
63706342

63716343
DXASSERT_NOMSG(SrcIdx == CI->getNumArgOperands());
6372-
DXASSERT_NOMSG(DestIdx == DxilNumArgs);
6344+
DXASSERT_NOMSG(DestIdx == DXIL::OperandIndex::kHitObjectTraceRay_NumOp);
63736345

63746346
Function *F = OP->GetOpFunc(OpCode, Payload->getType());
63756347

@@ -7402,7 +7374,7 @@ IntrinsicLower gLowerTable[] = {
74027374
DXIL::OpCode::NumOpCodes},
74037375
{IntrinsicOp::MOP_InterlockedUMin, TranslateMopAtomicBinaryOperation,
74047376
DXIL::OpCode::NumOpCodes},
7405-
{IntrinsicOp::MOP_DxHitObject_MakeNop, TranslateHitObjectMake,
7377+
{IntrinsicOp::MOP_DxHitObject_MakeNop, TranslateHitObjectMakeNop,
74067378
DXIL::OpCode::HitObject_MakeNop},
74077379
{IntrinsicOp::IOP_DxMaybeReorderThread, TranslateMaybeReorderThread,
74087380
DXIL::OpCode::MaybeReorderThread},
@@ -7462,7 +7434,7 @@ IntrinsicLower gLowerTable[] = {
74627434
{IntrinsicOp::MOP_DxHitObject_LoadLocalRootTableConstant,
74637435
TranslateHitObjectLoadLocalRootTableConstant,
74647436
DXIL::OpCode::HitObject_LoadLocalRootTableConstant},
7465-
{IntrinsicOp::MOP_DxHitObject_MakeMiss, TranslateHitObjectMake,
7437+
{IntrinsicOp::MOP_DxHitObject_MakeMiss, TranslateHitObjectMakeMiss,
74667438
DXIL::OpCode::HitObject_MakeMiss},
74677439
{IntrinsicOp::MOP_DxHitObject_SetShaderTableIndex,
74687440
TranslateHitObjectSetShaderTableIndex,

0 commit comments

Comments
 (0)