[llvm] [AMDGPU] Fix poison result on inttoptr a narrow integer to ptr addrspace(7) in LowerBufferFatPointers (PR #216966)

Arseniy Obolenskiy via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 02:54:40 PDT 2026


https://github.com/aobolensk updated https://github.com/llvm/llvm-project/pull/216966

>From 015aea162bd69cf5c015c61b4b0da8e4f2e68a41 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Tue, 18 Aug 2026 10:59:06 +0200
Subject: [PATCH 1/2] [AMDGPU][LowerBufferFatPointers] Fix poison result on
 inttoptr a narrow integer to ptr addrspace(7)

The unconditional shift by BufferOffsetWidth overshifted for narrower sources, folding to poison instead of the correctly zero-extended null resource half
---
 .../AMDGPU/AMDGPULowerBufferFatPointers.cpp   | 15 +++++---
 .../lower-buffer-fat-pointers-pointer-ops.ll  | 35 ++++++++++++++++++-
 2 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
index 59d5da21fc7d3..f202f429e69ae 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
@@ -2224,10 +2224,17 @@ PtrParts SplitPtrStructs::visitIntToPtrInst(IntToPtrInst &IP) {
   auto *RetTy = cast<StructType>(IP.getType());
   Type *RsrcTy = RetTy->getElementType(0);
   Type *OffTy = RetTy->getElementType(1);
-  Value *RsrcPart = IRB.CreateLShr(
-      Int,
-      ConstantExpr::getIntegerValue(IntTy, APInt(Width, BufferOffsetWidth)));
-  Value *RsrcInt = IRB.CreateIntCast(RsrcPart, RsrcIntTy, /*isSigned=*/false);
+  // inttoptr zero-extends, so narrow inputs contribute nothing to the resource
+  // part.
+  Value *RsrcInt;
+  if (Width <= BufferOffsetWidth) {
+    RsrcInt = Constant::getNullValue(RsrcIntTy);
+  } else {
+    Value *RsrcPart = IRB.CreateLShr(
+        Int,
+        ConstantExpr::getIntegerValue(IntTy, APInt(Width, BufferOffsetWidth)));
+    RsrcInt = IRB.CreateIntCast(RsrcPart, RsrcIntTy, /*isSigned=*/false);
+  }
   Value *Rsrc = IRB.CreateIntToPtr(RsrcInt, RsrcTy, IP.getName() + ".rsrc");
   Value *Off =
       IRB.CreateIntCast(Int, OffTy, /*IsSigned=*/false, IP.getName() + ".off");
diff --git a/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-pointer-ops.ll b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-pointer-ops.ll
index 35ff38c3cd7fa..6c117f6628196 100644
--- a/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-pointer-ops.ll
+++ b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-pointer-ops.ll
@@ -353,13 +353,46 @@ define ptr addrspace(7) @inttoptr_long(i256 %v) {
 define ptr addrspace(7) @inttoptr_offset(i32 %v) {
 ; CHECK-LABEL: define { ptr addrspace(8), i32 } @inttoptr_offset
 ; CHECK-SAME: (i32 [[V:%.*]]) {
-; CHECK-NEXT:    [[RET:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, i32 [[V]], 1
+; CHECK-NEXT:    [[RET:%.*]] = insertvalue { ptr addrspace(8), i32 } { ptr addrspace(8) null, i32 poison }, i32 [[V]], 1
 ; CHECK-NEXT:    ret { ptr addrspace(8), i32 } [[RET]]
 ;
   %ret = inttoptr i32 %v to ptr addrspace(7)
   ret ptr addrspace(7) %ret
 }
 
+define ptr addrspace(7) @inttoptr_narrow(i16 %v) {
+; CHECK-LABEL: define { ptr addrspace(8), i32 } @inttoptr_narrow
+; CHECK-SAME: (i16 [[V:%.*]]) {
+; CHECK-NEXT:    [[RET_OFF:%.*]] = zext i16 [[V]] to i32
+; CHECK-NEXT:    [[RET:%.*]] = insertvalue { ptr addrspace(8), i32 } { ptr addrspace(8) null, i32 poison }, i32 [[RET_OFF]], 1
+; CHECK-NEXT:    ret { ptr addrspace(8), i32 } [[RET]]
+;
+  %ret = inttoptr i16 %v to ptr addrspace(7)
+  ret ptr addrspace(7) %ret
+}
+
+define <2 x ptr addrspace(7)> @inttoptr_narrow_vec(<2 x i16> %v) {
+; CHECK-LABEL: define { <2 x ptr addrspace(8)>, <2 x i32> } @inttoptr_narrow_vec
+; CHECK-SAME: (<2 x i16> [[V:%.*]]) {
+; CHECK-NEXT:    [[RET_OFF:%.*]] = zext <2 x i16> [[V]] to <2 x i32>
+; CHECK-NEXT:    [[RET:%.*]] = insertvalue { <2 x ptr addrspace(8)>, <2 x i32> } { <2 x ptr addrspace(8)> splat (ptr addrspace(8) null), <2 x i32> poison }, <2 x i32> [[RET_OFF]], 1
+; CHECK-NEXT:    ret { <2 x ptr addrspace(8)>, <2 x i32> } [[RET]]
+;
+  %ret = inttoptr <2 x i16> %v to <2 x ptr addrspace(7)>
+  ret <2 x ptr addrspace(7)> %ret
+}
+
+define i64 @inttoptr_offset_roundtrip(i32 %v) {
+; CHECK-LABEL: define i64 @inttoptr_offset_roundtrip
+; CHECK-SAME: (i32 [[V:%.*]]) {
+; CHECK-NEXT:    [[RET:%.*]] = zext i32 [[V]] to i64
+; CHECK-NEXT:    ret i64 [[RET]]
+;
+  %p = inttoptr i32 %v to ptr addrspace(7)
+  %ret = ptrtoint ptr addrspace(7) %p to i64
+  ret i64 %ret
+}
+
 define ptr addrspace(7) @addrspacecast(ptr addrspace(8) %buf) {
 ; CHECK-LABEL: define { ptr addrspace(8), i32 } @addrspacecast
 ; CHECK-SAME: (ptr addrspace(8) [[BUF:%.*]]) {

>From c6057e9f657649e6c77014952d268469f603872a Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Tue, 18 Aug 2026 11:54:29 +0200
Subject: [PATCH 2/2] Address comment

---
 llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
index f202f429e69ae..528714faf08fb 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
@@ -2230,9 +2230,8 @@ PtrParts SplitPtrStructs::visitIntToPtrInst(IntToPtrInst &IP) {
   if (Width <= BufferOffsetWidth) {
     RsrcInt = Constant::getNullValue(RsrcIntTy);
   } else {
-    Value *RsrcPart = IRB.CreateLShr(
-        Int,
-        ConstantExpr::getIntegerValue(IntTy, APInt(Width, BufferOffsetWidth)));
+    Value *RsrcPart =
+        IRB.CreateLShr(Int, ConstantInt::get(IntTy, BufferOffsetWidth));
     RsrcInt = IRB.CreateIntCast(RsrcPart, RsrcIntTy, /*isSigned=*/false);
   }
   Value *Rsrc = IRB.CreateIntToPtr(RsrcInt, RsrcTy, IP.getName() + ".rsrc");



More information about the llvm-commits mailing list