microsoft / microsoft/DirectXShaderCompiler
[SPIR-V] Crash observed while processing TraceRay intrinsic when the payload argument is a MemberExpr
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 3.7k
- Forks
- 900
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 44
Description
Description
We observed a crash in DXC compiling lib6_6 raytracing code to SpirV. The crash happens in the SpirvEmitter.cpp:13780 after this codeblock:
if (const auto *implCastExpr = dyn_cast<CastExpr>(args[7])) {
if (const auto *arg = dyn_cast<DeclRefExpr>(implCastExpr->getSubExpr())) {
if (const auto *varDecl = dyn_cast<VarDecl>(arg->getDecl())) {
rayPayloadType = varDecl->getType();
rayPayloadArg = varDecl;
const auto rayPayloadPair = rayPayloadMap.find(rayPayloadType);
// Check if same type of rayPayload stage variable was already
// created, if so re-use
if (rayPayloadPair == rayPayloadMap.end()) {
int numPayloadVars = rayPayloadMap.size();
rayPayloadStageVar = declIdMapper.createRayTracingNVStageVar(
spv::StorageClass::RayPayloadNV, varDecl);
// Decorate unique location id for each created stage var
spvBuilder.decorateLocation(rayPayloadStageVar, numPayloadVars);
rayPayloadLocInst = spvBuilder.getConstantInt(
astContext.UnsignedIntTy, llvm::APInt(32, numPayloadVars));
rayPayloadMap[rayPayloadType] =
std::make_pair(rayPayloadStageVar, rayPayloadLocInst);
} else {
rayPayloadStageVar = rayPayloadPair->second.first;
rayPayloadLocInst = rayPayloadPair->second.second;
}
}
}
}
assert(rayPayloadStageVar && rayPayloadArg);
In debug builds, the assert fires.
Steps to Reproduce
Here is a minimal HLSL repro snipped
RaytracingAccelerationStructure Scene : register(t0);
struct MyPayload
{
uint hit;
float t;
};
struct SomeType
{
MyPayload rayPayload;
};
[shader("raygeneration")]
void RayGen()
{
SomeType InstanceOfSomeType;
// Initialize payload
InstanceOfSomeType.rayPayload.hit = 0;
InstanceOfSomeType.rayPayload.t = -1.0f;
RayDesc ray;
ray.Origin = float3(0.0f, 0.0f, 0.0f);
ray.Direction = float3(0.0f, 0.0f, 1.0f);
ray.TMin = 0.0f;
ray.TMax = 1.0e38f;
// Payload passed as a MEMBER EXPRESSION (inout)
TraceRay(
Scene,
RAY_FLAG_NONE,
0xFF, // InstanceInclusionMask
0, // RayContributionToHitGroupIndex
1, // MultiplierForGeometryContributionToHitGroupIndex
0, // MissShaderIndex
ray,
InstanceOfSomeType.rayPayload // <--------------------------- This MemberExpr causes a crash/assert in SpirvEmitter
);
}
[shader("miss")]
void Miss(inout MyPayload payload)
{
payload.hit = 0;
payload.t = -1.0f;
}
[shader("closesthit")]
void ClosestHit(inout MyPayload payload, in BuiltInTriangleIntersectionAttributes attribs)
{
payload.hit = 1;
payload.t = RayTCurrent();
}
command line: dxc.exe -T lib_6_6 -spirv repo.hlsl
Actual Behavior
Internal Compiler error (the assert shown above terminates the compilation).
Environment
- DXC version 1.10(5194-4687c52d)(1.9.0.15194) - 1.9.0.15194 (main, 4687c52d6)
- Host Operating System Windows 11 24h2
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with SpirvEmitter.cpp around line 13780 and run the supplied minimal HLSL repro with dxc.exe -T lib_6_6 -spirv repo.hlsl. TraceRay receives a MemberExpr payload, so inspect the shown payload-handling path and its assertion. Done means the repro compiles without the internal compiler error or debug assertion.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 52/100