[llvm] [IR] Only follow ptr/ptr-vector sources in stripAndAccumulateConstantOffsets bitcasts (PR #203356)
Anshil Gandhi via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 17 00:03:11 PDT 2026
https://github.com/gandhi56 updated https://github.com/llvm/llvm-project/pull/203356
>From dce928c03d46dbc29fc33a15588256de16840452 Mon Sep 17 00:00:00 2001
From: Anshil Gandhi <Anshil.Gandhi at amd.com>
Date: Thu, 11 Jun 2026 11:59:14 -0500
Subject: [PATCH] [IR] Only follow ptr (or ptr-vector) sources in
stripAndAccumulateConstantOffsets bitcasts
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.
---
llvm/lib/IR/Value.cpp | 16 ++++++++++------
llvm/test/Transforms/InferAlignment/bitcast.ll | 14 ++++++++++++++
2 files changed, 24 insertions(+), 6 deletions(-)
create mode 100644 llvm/test/Transforms/InferAlignment/bitcast.ll
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