[llvm] ca07de4 - [IR] Only follow ptr/ptr-vector sources in stripAndAccumulateConstantOffsets bitcasts (#203356)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 17 00:34:31 PDT 2026


Author: Anshil Gandhi
Date: 2026-06-17T07:34:26Z
New Revision: ca07de42aa11307d2f54036d7097e3caad5961ff

URL: https://github.com/llvm/llvm-project/commit/ca07de42aa11307d2f54036d7097e3caad5961ff
DIFF: https://github.com/llvm/llvm-project/commit/ca07de42aa11307d2f54036d7097e3caad5961ff.diff

LOG: [IR] Only follow ptr/ptr-vector sources in stripAndAccumulateConstantOffsets bitcasts (#203356)

stripAndAccumulateConstantOffsets used to walk through every bitcast
operand. If the operand was not a pointer (e.g. a same-sized byte type
such as b64 reinterpreted as ptr), the walk could continue and violate
the invariant that the stripped value remains ptr or ptr-vector.

Align with stripPointerCastsAndOffsets: only look through bitcasts whose
source type is a pointer or pointer vector; keep addrspacecast as its
own case.

This commit is needed in PR #177908, and fixes issue
https://github.com/llvm/llvm-project/issues/203695.

Assisted by Cursor

Added: 
    llvm/test/Transforms/InferAlignment/bitcast.ll

Modified: 
    llvm/lib/IR/Value.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index f944f546670de..d3f90bd81bbe2 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -784,17 +784,21 @@ const Value *Value::stripAndAccumulateConstantOffsets(
         }
       }
       V = GEP->getPointerOperand();
-    } else if (Operator::getOpcode(V) == Instruction::BitCast ||
-               Operator::getOpcode(V) == Instruction::AddrSpaceCast) {
+    } else if (Operator::getOpcode(V) == Instruction::BitCast) {
+      const Value *Src = cast<Operator>(V)->getOperand(0);
+      if (!Src->getType()->isPtrOrPtrVectorTy())
+        return V;
+      V = Src;
+    } else if (Operator::getOpcode(V) == Instruction::AddrSpaceCast) {
       V = cast<Operator>(V)->getOperand(0);
     } else if (auto *GA = dyn_cast<GlobalAlias>(V)) {
       if (!GA->isInterposable())
         V = GA->getAliasee();
     } else if (const auto *Call = dyn_cast<CallBase>(V)) {
-        if (const Value *RV = Call->getReturnedArgOperand())
-          V = RV;
-        if (AllowInvariantGroup && Call->isLaunderOrStripInvariantGroup())
-          V = Call->getArgOperand(0);
+      if (const Value *RV = Call->getReturnedArgOperand())
+        V = RV;
+      if (AllowInvariantGroup && Call->isLaunderOrStripInvariantGroup())
+        V = Call->getArgOperand(0);
     } else if (auto *Int2Ptr = dyn_cast<Operator>(V)) {
       // Try to accumulate across (inttoptr (add (ptrtoint p), off)).
       if (!AllowNonInbounds || !LookThroughIntToPtr || !Int2Ptr ||

diff  --git a/llvm/test/Transforms/InferAlignment/bitcast.ll b/llvm/test/Transforms/InferAlignment/bitcast.ll
new file mode 100644
index 0000000000000..f77f244a19377
--- /dev/null
+++ b/llvm/test/Transforms/InferAlignment/bitcast.ll
@@ -0,0 +1,14 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=infer-alignment -S | FileCheck %s
+
+define void @bitcast_b64_to_p1(b64 %b) {
+; CHECK-LABEL: define void @bitcast_b64_to_p1(
+; CHECK-SAME: b64 [[B:%.*]]) {
+; CHECK-NEXT:    [[P:%.*]] = bitcast b64 [[B]] to ptr addrspace(1)
+; CHECK-NEXT:    store i64 0, ptr addrspace(1) [[P]], align 4
+; CHECK-NEXT:    ret void
+;
+  %p = bitcast b64 %b to ptr addrspace(1)
+  store i64 0, ptr addrspace(1) %p
+  ret void
+}


        


More information about the llvm-commits mailing list