[llvm] [DirectX] Fix RawBuffer Loads of double vectors (PR #224695)
Farzon Lotfi via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 21 17:00:25 PDT 2026
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/224695
>From 788ce9e1b9da8d0b94174ab3b27dc31bd71c5097 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Fri, 18 Sep 2026 13:35:51 -0400
Subject: [PATCH 1/2] [DirectX] Fix RawBuffer Loads of double vectors
fixes https://github.com/llvm/llvm-project/issues/224684
We need to do the same change we did for Raw Buffer Stores (https://github.com/llvm/llvm-project/issues/223558) in https://github.com/llvm/llvm-project/pull/224136 by Create add with the byte index offsets because were were looking at the wrong argument.
---
.../Target/DirectX/DXILIntrinsicExpansion.cpp | 6 ++++-
.../CodeGen/DirectX/RawBufferLoadDouble.ll | 23 +++++++++++++++++++
.../load-rawbuffer-wide-double.ll | 22 ++++++++++++++++++
llvm/test/CodeGen/DirectX/TextureLoad.ll | 4 ++--
4 files changed, 52 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/CodeGen/DirectX/ResourceAccess/load-rawbuffer-wide-double.ll
diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
index 2a1416deccc3a..dce8a1ec9f92a 100644
--- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
+++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
@@ -813,7 +813,11 @@ static bool expandBufferLoadIntrinsic(CallInst *Orig, bool IsRaw) {
if (IsRaw) {
LoadIntrinsic = Intrinsic::dx_resource_load_rawbuffer;
Value *Tmp = Builder.getInt32(4 * Base * 2);
- Args.push_back(Builder.CreateAdd(Orig->getOperand(2), Tmp));
+ Value *Offset = Orig->getOperand(2);
+ Args.push_back(Offset);
+ unsigned AddressArg = isa<PoisonValue>(Offset) ? 1 : 2;
+ if (Base != 0)
+ Args[AddressArg] = Builder.CreateAdd(Args[AddressArg], Tmp);
}
Value *Load = Builder.CreateIntrinsic(LoadType, LoadIntrinsic, Args);
diff --git a/llvm/test/CodeGen/DirectX/RawBufferLoadDouble.ll b/llvm/test/CodeGen/DirectX/RawBufferLoadDouble.ll
index 6c7d8c2598330..32da2b79a0aa9 100644
--- a/llvm/test/CodeGen/DirectX/RawBufferLoadDouble.ll
+++ b/llvm/test/CodeGen/DirectX/RawBufferLoadDouble.ll
@@ -71,6 +71,29 @@ define void @loadv2f64(i32 %index) {
ret void
}
+define void @loadv4f64_byte(i32 %index) {
+ ; CHECK: [[B:%.*]] = call target("dx.RawBuffer", i8, 0, 0)
+ ; CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t(
+ ; CHECK-SAME: i32 0, i32 0, i32 1, i32 0, ptr null)
+ %buffer = call target("dx.RawBuffer", i8, 0, 0)
+ @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t(
+ i32 0, i32 0, i32 1, i32 0, ptr null)
+
+ ; CHECK63: call { <4 x double>, i1 } @llvm.dx.resource.load.rawbuffer
+ ; CHECK63-SAME: target("dx.RawBuffer", i8, 0, 0) [[B]], i32 %index, i32 poison)
+
+ ; CHECK62: [[LOW:%.*]] = call { <4 x i32>, i1 } @llvm.dx.resource.load.rawbuffer
+ ; CHECK62-SAME: target("dx.RawBuffer", i8, 0, 0) [[B]], i32 %index, i32 poison)
+ ; CHECK62: [[NEXTINDEX:%.*]] = add i32 %index, 16
+ ; CHECK62: [[HIGH:%.*]] = call { <4 x i32>, i1 } @llvm.dx.resource.load.rawbuffer
+ ; CHECK62-SAME: target("dx.RawBuffer", i8, 0, 0) [[B]], i32 [[NEXTINDEX]], i32 poison)
+ %load0 = call { <4 x double>, i1 } @llvm.dx.resource.load.rawbuffer(
+ target("dx.RawBuffer", i8, 0, 0) %buffer, i32 %index, i32 poison)
+
+ %data0 = extractvalue { <4 x double>, i1 } %load0, 0
+ ret void
+}
+
; show we properly handle extracting the check bit
define void @loadf64WithCheckBit(i32 %index) {
; check the handle from binding is unchanged
diff --git a/llvm/test/CodeGen/DirectX/ResourceAccess/load-rawbuffer-wide-double.ll b/llvm/test/CodeGen/DirectX/ResourceAccess/load-rawbuffer-wide-double.ll
new file mode 100644
index 0000000000000..9227837527e50
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ResourceAccess/load-rawbuffer-wide-double.ll
@@ -0,0 +1,22 @@
+; RUN: opt -S -dxil-resource-access -dxil-intrinsic-expansion \
+; RUN: -mtriple=dxil-pc-shadermodel6.2-compute %s | FileCheck %s
+
+define <8 x double> @loadv8f64_byte(i32 %index) {
+ %buffer = call target("dx.RawBuffer", i8, 0, 0)
+ @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, ptr null)
+
+ ; CHECK-NOT: @llvm.dx.resource.getpointer
+ %ptr = call ptr @llvm.dx.resource.getpointer(
+ target("dx.RawBuffer", i8, 0, 0) %buffer, i32 %index)
+
+ ; CHECK: [[LOAD0:%.*]] = call { <4 x i32>, i1 } [[LOAD_INTRINSIC:@llvm\.dx\.resource\.load\.rawbuffer[^(]*]]([[BUFFER_TY:target\("dx\.RawBuffer", i8, 0, 0\)]] %buffer, i32 %index, i32 poison)
+ ; CHECK: %[[INDEX16:.*]] = add i32 %index, 16
+ ; CHECK: [[LOAD16:%.*]] = call { <4 x i32>, i1 } [[LOAD_INTRINSIC]]([[BUFFER_TY]] %buffer, i32 %[[INDEX16]], i32 poison)
+ ; CHECK: %[[INDEX32:.*]] = add i32 %index, 32
+ ; CHECK: [[LOAD32:%.*]] = call { <4 x i32>, i1 } [[LOAD_INTRINSIC]]([[BUFFER_TY]] %buffer, i32 %[[INDEX32]], i32 poison)
+ ; CHECK: %[[INDEX48:.*]] = add i32 %[[INDEX32]], 16
+ ; CHECK: [[LOAD48:%.*]] = call { <4 x i32>, i1 } [[LOAD_INTRINSIC]]([[BUFFER_TY]] %buffer, i32 %[[INDEX48]], i32 poison)
+ %data = load <8 x double>, ptr %ptr
+
+ ret <8 x double> %data
+}
diff --git a/llvm/test/CodeGen/DirectX/TextureLoad.ll b/llvm/test/CodeGen/DirectX/TextureLoad.ll
index 29329f4bf9896..1ce81929b1f9e 100644
--- a/llvm/test/CodeGen/DirectX/TextureLoad.ll
+++ b/llvm/test/CodeGen/DirectX/TextureLoad.ll
@@ -266,7 +266,7 @@ define void @load_rwtexture2d_float4_explicit_lod(<2 x i32> %coords) {
define void @load_rwtexture2darray_float4(<3 x i32> %coords) {
%texture = call target("dx.Texture", <4 x float>, 1, 0, 0, 7)
@llvm.dx.resource.handlefrombinding.tdx.Texture_v4f32_1_0_0_7t(
- i32 0, i32 0, i32 1, i32 0, ptr null)
+ i32 0, i32 1, i32 1, i32 0, ptr null)
; CHECK: %[[COORD0:.*]] = extractelement <3 x i32> %coords, i32 0
; CHECK: %[[COORD1:.*]] = extractelement <3 x i32> %coords, i32 1
@@ -287,7 +287,7 @@ define void @load_rwtexture2darray_float4(<3 x i32> %coords) {
define void @load_rwtexture2darray_scalarized_coords(i32 %x, i32 %y, i32 %z) {
%texture = call target("dx.Texture", float, 1, 0, 0, 7)
@llvm.dx.resource.handlefrombinding.tdx.Texture_f32_1_0_0_7t(
- i32 0, i32 0, i32 1, i32 0, ptr null)
+ i32 0, i32 2, i32 1, i32 0, ptr null)
%coords.0 = insertelement <3 x i32> poison, i32 %x, i32 0
%coords.1 = insertelement <3 x i32> %coords.0, i32 %y, i32 1
>From 98f05e03790eeaf7ca8fdab20f07a9ceefacabd5 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Mon, 21 Sep 2026 19:59:26 -0400
Subject: [PATCH 2/2] address pr feedback
---
.../DirectX/ResourceAccess/load-rawbuffer-wide-double.ll | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/test/CodeGen/DirectX/ResourceAccess/load-rawbuffer-wide-double.ll b/llvm/test/CodeGen/DirectX/ResourceAccess/load-rawbuffer-wide-double.ll
index 9227837527e50..f4b83aa335b49 100644
--- a/llvm/test/CodeGen/DirectX/ResourceAccess/load-rawbuffer-wide-double.ll
+++ b/llvm/test/CodeGen/DirectX/ResourceAccess/load-rawbuffer-wide-double.ll
@@ -9,13 +9,13 @@ define <8 x double> @loadv8f64_byte(i32 %index) {
%ptr = call ptr @llvm.dx.resource.getpointer(
target("dx.RawBuffer", i8, 0, 0) %buffer, i32 %index)
- ; CHECK: [[LOAD0:%.*]] = call { <4 x i32>, i1 } [[LOAD_INTRINSIC:@llvm\.dx\.resource\.load\.rawbuffer[^(]*]]([[BUFFER_TY:target\("dx\.RawBuffer", i8, 0, 0\)]] %buffer, i32 %index, i32 poison)
+ ; CHECK: call { <4 x i32>, i1 } [[LOAD_INTRINSIC:@llvm\.dx\.resource\.load\.rawbuffer[^(]*]]([[BUFFER_TY:target\("dx\.RawBuffer", i8, 0, 0\)]] %buffer, i32 %index, i32 poison)
; CHECK: %[[INDEX16:.*]] = add i32 %index, 16
- ; CHECK: [[LOAD16:%.*]] = call { <4 x i32>, i1 } [[LOAD_INTRINSIC]]([[BUFFER_TY]] %buffer, i32 %[[INDEX16]], i32 poison)
+ ; CHECK: call { <4 x i32>, i1 } [[LOAD_INTRINSIC]]([[BUFFER_TY]] %buffer, i32 %[[INDEX16]], i32 poison)
; CHECK: %[[INDEX32:.*]] = add i32 %index, 32
- ; CHECK: [[LOAD32:%.*]] = call { <4 x i32>, i1 } [[LOAD_INTRINSIC]]([[BUFFER_TY]] %buffer, i32 %[[INDEX32]], i32 poison)
+ ; CHECK: call { <4 x i32>, i1 } [[LOAD_INTRINSIC]]([[BUFFER_TY]] %buffer, i32 %[[INDEX32]], i32 poison)
; CHECK: %[[INDEX48:.*]] = add i32 %[[INDEX32]], 16
- ; CHECK: [[LOAD48:%.*]] = call { <4 x i32>, i1 } [[LOAD_INTRINSIC]]([[BUFFER_TY]] %buffer, i32 %[[INDEX48]], i32 poison)
+ ; CHECK: call { <4 x i32>, i1 } [[LOAD_INTRINSIC]]([[BUFFER_TY]] %buffer, i32 %[[INDEX48]], i32 poison)
%data = load <8 x double>, ptr %ptr
ret <8 x double> %data
More information about the llvm-commits
mailing list