microsoft / microsoft/DirectXShaderCompiler

[SER] Passing a payload by value to HitObject::Invoke asserts in CodeGen

Open
#8,725 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug needs-triage
Dominant language
C++
Stars
3.7k
Forks
900
Avg merge
2d 11h
Merged PRs (30d)
44

Description

Description

Passing a ray payload to dx::HitObject::Invoke via an "in" (by value) function parameter crashes the compiler in CodeGen. Invoke's payload parameter is inout, so a by-value parameter is not a valid argument for it, but instead of being diagnosed in Sema this reaches CodeGen and asserts while emitting the call.

In a release build the assert is compiled out, an invalid bitcast is emitted, and the user instead sees an unhelpful validation failure.

This is not related to payload access qualifiers - it reproduces with -disable-payload-qualifiers too. It also appears specific to HitObject::Invoke: the same shader using TraceRay instead compiles fine.

This was originally reported as a comment on #6464, but that issue is about a different (PAQ analysis) crash, so splitting it out here. It is also adjacent to #7761, which covered a const payload and was made a Sema error by #7797, but that change does not cover this by-value case.

Steps to Reproduce

struct [raypayload] Payload {
  float value : write(caller, closesthit, miss) : read(caller, closesthit, miss);
};

// 'p' is an "in" (by value) parameter. Passing it to Invoke's inout payload
// parameter asserts in CodeGen.
void Function(Payload p) {
  RayDesc ray = (RayDesc)0;
  dx::HitObject obj = dx::HitObject::MakeMiss(0, 0, ray);
  dx::HitObject::Invoke(obj, p);
}

[shader("raygeneration")]
void RayGen() {
  Payload p;
  p.value = 0;
  Function(p);
}

Command line: -T lib_6_9

Changing Function(Payload p) to Function(inout Payload p) compiles successfully, which is the workaround.

Actual Behavior

With an assert-enabled build:

Internal compiler error: LLVM Assert
assert(castIsValid(op, S, Ty) && "Invalid cast!")

dxcompiler!llvm_assert
dxcompiler!llvm::CastInst::Create
dxcompiler!llvm::IRBuilder<...>::CreateCast
dxcompiler!llvm::IRBuilder<...>::CreateBitCast
dxcompiler!clang::CodeGen::CodeGenFunction::EmitCall
dxcompiler!clang::CodeGen::CodeGenFunction::EmitCall
dxcompiler!clang::CodeGen::CodeGenFunction::EmitCallExpr
dxcompiler!`anonymous namespace'::ScalarExprEmitter::VisitCallExpr
dxcompiler!clang::CodeGen::CodeGenFunction::EmitScalarExpr
dxcompiler!clang::CodeGen::CodeGenFunction::EmitAnyExpr
dxcompiler!clang::CodeGen::CodeGenFunction::EmitIgnoredExpr
dxcompiler!clang::CodeGen::CodeGenFunction::EmitStmt

A preceding assert also fires:

assert(type->isReferenceType() == E->isGLValue() && "reference binding to unmaterialized r-value!")

With a release build the same source instead produces:

error: validation errors

Function: ?RayGen@@YAXXZ: error: Instructions must be of an allowed type.
note: at 'unreachable' in block '#0' of function '?RayGen@@YAXXZ'.
Validation failed.

Expected Behavior

This should be rejected in Sema with a diagnostic explaining that the payload argument to dx::HitObject::Invoke must be an inout-compatible lvalue, rather than asserting in CodeGen or producing a validation failure.

Environment

  • DXC version: built from source at 7676b1f90 (current main), x64, Visual Studio, both Debug (assert build) and Release
  • Host Operating System: Windows 11

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by compiling the provided HLSL reproducer with -T lib_6_9 in an assert-enabled build, then trace the dx::HitObject::Invoke call through Sema and CodeGen. Compare the by-value and inout cases, and verify that the invalid argument is rejected with a diagnostic before CodeGen rather than asserting or producing a validation failure.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.