[llvm] [AMDGPU] Fix miscompile from stale value cache in LowerBufferFatPointers (PR #216962)

via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 02:21:29 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Arseniy Obolenskiy (aobolensk)

<details>
<summary>Changes</summary>

ConvertedForStore cached a p7->int conversion per Value across the whole function, so a second store of the same fat pointer in a non-dominating block reused an instruction from the first block, breaking dominance

---
Full diff: https://github.com/llvm/llvm-project/pull/216962.diff


2 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp (+2-12) 
- (modified) llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-p7-in-memory.ll (+38) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
index 59d5da21fc7d3..2c9c0190e4b76 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
@@ -435,8 +435,6 @@ class StoreFatPtrsAsIntsAndExpandMemcpyVisitor
     : public InstVisitor<StoreFatPtrsAsIntsAndExpandMemcpyVisitor, bool> {
   BufferFatPtrToIntTypeMap *TypeMap;
 
-  ValueToValueMapTy ConvertedForStore;
-
   IRBuilder<InstSimplifyFolder> IRB;
 
   // Used for memcpy() lowering.
@@ -476,14 +474,8 @@ Value *StoreFatPtrsAsIntsAndExpandMemcpyVisitor::fatPtrsToInts(
     Value *V, Type *From, Type *To, const Twine &Name) {
   if (From == To)
     return V;
-  ValueToValueMapTy::iterator Find = ConvertedForStore.find(V);
-  if (Find != ConvertedForStore.end())
-    return Find->second;
-  if (isBufferFatPtrOrVector(From)) {
-    Value *Cast = IRB.CreatePtrToInt(V, To, Name + ".int");
-    ConvertedForStore[V] = Cast;
-    return Cast;
-  }
+  if (isBufferFatPtrOrVector(From))
+    return IRB.CreatePtrToInt(V, To, Name + ".int");
   if (From->getNumContainedTypes() == 0)
     return V;
   // Structs, arrays, and other compound types.
@@ -506,7 +498,6 @@ Value *StoreFatPtrsAsIntsAndExpandMemcpyVisitor::fatPtrsToInts(
       Ret = IRB.CreateInsertValue(Ret, NewField, Idx);
     }
   }
-  ConvertedForStore[V] = Ret;
   return Ret;
 }
 
@@ -560,7 +551,6 @@ bool StoreFatPtrsAsIntsAndExpandMemcpyVisitor::processFunction(
   for (WeakTrackingVH VH : make_early_inc_range(CanBecomeLoops)) {
     Changed |= visit(cast<Instruction>(VH));
   }
-  ConvertedForStore.clear();
   this->TTI = nullptr;
   this->SE = nullptr;
   return Changed;
diff --git a/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-p7-in-memory.ll b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-p7-in-memory.ll
index 497f99903e266..071666e4a6d75 100644
--- a/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-p7-in-memory.ll
+++ b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-p7-in-memory.ll
@@ -107,3 +107,41 @@ define void @complex_copy(ptr %a, ptr %b) {
   store {[2 x ptr addrspace(7)], i32, ptr addrspace(7)} %x, ptr %b
   ret void
 }
+
+;; The conversion of %p for the store in %then must not be reused by the
+;; store in %else, since neither block dominates the other.
+define void @two_stores_same_value(i1 %cond, ptr addrspace(7) %p, ptr %a, ptr %b) {
+; CHECK-LABEL: define void @two_stores_same_value
+; CHECK-SAME: (i1 [[COND:%.*]], { ptr addrspace(8), i32 } [[P:%.*]], ptr [[A:%.*]], ptr [[B:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[P_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[P]], 0
+; CHECK-NEXT:    [[P_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[P]], 1
+; CHECK-NEXT:    br i1 [[COND]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    [[P_INT_RSRC:%.*]] = ptrtoint ptr addrspace(8) [[P_RSRC]] to i160
+; CHECK-NEXT:    [[TMP0:%.*]] = shl nuw i160 [[P_INT_RSRC]], 32
+; CHECK-NEXT:    [[P_INT_OFF:%.*]] = zext i32 [[P_OFF]] to i160
+; CHECK-NEXT:    [[P_INT:%.*]] = or i160 [[TMP0]], [[P_INT_OFF]]
+; CHECK-NEXT:    store i160 [[P_INT]], ptr [[A]], align 32
+; CHECK-NEXT:    br label [[EXIT:%.*]]
+; CHECK:       else:
+; CHECK-NEXT:    [[P_INT1_RSRC:%.*]] = ptrtoint ptr addrspace(8) [[P_RSRC]] to i160
+; CHECK-NEXT:    [[TMP1:%.*]] = shl nuw i160 [[P_INT1_RSRC]], 32
+; CHECK-NEXT:    [[P_INT1_OFF:%.*]] = zext i32 [[P_OFF]] to i160
+; CHECK-NEXT:    [[P_INT1:%.*]] = or i160 [[TMP1]], [[P_INT1_OFF]]
+; CHECK-NEXT:    store i160 [[P_INT1]], ptr [[B]], align 32
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br i1 %cond, label %then, label %else
+then:
+  store ptr addrspace(7) %p, ptr %a
+  br label %exit
+else:
+  store ptr addrspace(7) %p, ptr %b
+  br label %exit
+exit:
+  ret void
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/216962


More information about the llvm-commits mailing list