[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