llvm / llvm/llvm-project

[HLSL] [DirectX] i64 arithmetic appears in DXIL when 64-bit integers are not present in HLSL

Open
#165,753 4 comments 0 reactions 0 assignees View on GitHub
backend:DirectX HLSL
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

In some cases, particularly when operating with structs consisting of a pair of 32-bit integers, i64 types and arithmetic instructions are introduced into the DXIL. This occurs with all target shader models, but becomes even more prevalent in shader model 6.0

https://godbolt.org/z/qWbaEMdd9

```hlsl
// compile args: -T cs_6_0 -E CSMain
struct MyUInt64 {
uint32_t low;
uint32_t high;
};
RWStructuredBuffer src;
RWStructuredBuffer dest;
MyUInt64 AddOne(MyUInt64 i) {
MyUInt64 result;
result.low = i.low + 1;
result.high = i.high + (result.low == 0);
return result;
}
[numthreads(1, 1, 1)]
void CSMain(uint3 Tid : SV_GroupThreadID) {
dest[Tid.x] = AddOne(src[Tid.x]);
}
```

```llvm
define void @CSMain() local_unnamed_addr #0 {
%1 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 0, i1 false) #1, !dbg !112
%2 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 1, i32 1, i1 false) #1, !dbg !113
%3 = call i32 @dx.op.threadIdInGroup.i32(i32 95, i32 0) #2
%4 = call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 68, %dx.types.Handle %1, i32 %3, i32 0) #1, !dbg !132
%5 = extractvalue %dx.types.ResRet.i32 %4, 0, !dbg !132
%6 = extractvalue %dx.types.ResRet.i32 %4, 1, !dbg !132
%7 = zext i32 %5 to i64, !dbg !132
%8 = zext i32 %6 to i64, !dbg !132
%9 = shl i64 %8, 32, !dbg !132
%10 = or i64 %7, %9, !dbg !132
%11 = trunc i64 %10 to i32, !dbg !133
%12 = add i32 %11, 1, !dbg !142
%13 = icmp eq i32 %12, 0, !dbg !143
%14 = select i1 %13, i64 4294967296, i64 0, !dbg !146
%15 = add i64 %14, %10, !dbg !146
%16 = and i64 %15, -4294967296, !dbg !146
%17 = zext i32 %12 to i64, !dbg !146
%18 = or disjoint i64 %16, %17, !dbg !146
%19 = trunc i64 %18 to i32, !dbg !146
%20 = lshr i64 %18, 32, !dbg !146
%21 = trunc i64 %20 to i32, !dbg !146
call void @dx.op.bufferStore.i32(i32 69, %dx.types.Handle %2, i32 %3, i32 0, i32 %19, i32 %21, i32 undef, i32 undef, i8 3), !dbg !146
ret void
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.