Skip to content

[DirectX] llvm.lifetime.start/.end non-i8* pointers causing Invalid record validation error #147395

Open
@Icohedron

Description

@Icohedron

The problem

DXIL bitcode containing llvm.lifetime.start/end intrinsics emitted by Clang can fail to validate under the DXIL validator (dxv) due to error Invalid record located here: https://github.com/microsoft/DirectXShaderCompiler/blob/main/lib/Bitcode/Reader/BitcodeReader.cpp#L4722

Debugging the cause of the error with lldb, I have found that nullptr is being returned here:
https://github.com/microsoft/DirectXShaderCompiler/blob/a11702ef0a393a9e0b78f982f9f0fa66d919c867/lib/Bitcode/Reader/BitcodeReader.cpp#L836-L837

    if (Ty && Ty != V->getType())
      return nullptr;

because Ty is i8* and V->getType() is not equal to Ty.

Reproducing the problem

Sample shader that reproduces the problem:

// compile args: -E CSMain -T cs_6_6
uint2 Foo(uint2 a[2], uint i) {
  return a[i];
}
cbuffer Constants {
  uint2 arr[2];
}
RWStructuredBuffer<uint> output;
[numthreads(1, 1, 1)]
void CSMain(uint3 Tid : SV_DispatchThreadID) {
  output[0] = Foo(arr, Tid.x).x;
}

https://godbolt.org/z/haz47M8fz

Validation error:

Invalid record
Validation failed.

due to the lifetime intrinsic:

 %1 = alloca [4 x i32], align 8
 call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %1), !dbg !100

The BitcodeReader expects V->getType() to be an i8*, but it is currently a [4 x i32]*.

Solution

The ptr operand of every llvm.lifetime.* intrinsic should be bitcast to i8* in DXILPrepare.cpp (or DXILLegalizePass.cpp?)

Metadata

Metadata

Assignees

Type

Projects

Status

Planning

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions