[llvm] [InferAS] infer noop inttoptr/ptrtoint in constant expression (PR #177809)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 24 16:54:40 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Luo Yuanke (LuoYuanke)
<details>
<summary>Changes</summary>
The algorithm of infer address space is to update the address space
of a pointer and insert it's user to the work list, so that the
address space can be propagated to the pointer's user. However
inttoptr/ptrtoint is not associated with directly def/use, so the
address space inferred in ptrtoint may not be propagated to inttoptr.
This patch is to precede the ptrtoint before inttoptr in advance,
so that address space can be propagated from ptrtoint to inttoptr.
---
Full diff: https://github.com/llvm/llvm-project/pull/177809.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp (+21-5)
- (added) llvm/test/Transforms/InferAddressSpaces/NVPTX/inttoptr_constexpr.ll (+34)
``````````diff
diff --git a/llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp b/llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp
index 03efc156df1e8..5e6a5a4effe49 100644
--- a/llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp
+++ b/llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp
@@ -521,12 +521,26 @@ void InferAddressSpacesImpl::appendsFlatAddressExpressionToPostorderStack(
DenseSet<Value *> &Visited) const {
assert(V->getType()->isPtrOrPtrVectorTy());
+ auto PushConstantExpr = [&](Value *Val) {
+ // The inttoptr can't the pointer operand from its user operand. When The
+ // pointer operand changes, it won't insert inttoptr into WorkList when
+ // update address space. We push its pointer operand ahead of inttoptr to
+ // make sure the pointer operand's address space can be updated first.
+ Operator *AddrExpr = dyn_cast<Operator>(Val);
+ if (AddrExpr && AddrExpr->getOpcode() == Instruction::IntToPtr) {
+ for (Value *PtrOperand : getPointerOperands(*AddrExpr, *DL, TTI)) {
+ appendsFlatAddressExpressionToPostorderStack(PtrOperand, PostorderStack,
+ Visited);
+ }
+ }
+ PostorderStack.emplace_back(Val, false);
+ };
// Generic addressing expressions may be hidden in nested constant
// expressions.
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
// TODO: Look in non-address parts, like icmp operands.
if (isAddressExpression(*CE, *DL, TTI) && Visited.insert(CE).second)
- PostorderStack.emplace_back(CE, false);
+ PushConstantExpr(CE);
return;
}
@@ -534,13 +548,13 @@ void InferAddressSpacesImpl::appendsFlatAddressExpressionToPostorderStack(
if (V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
isAddressExpression(*V, *DL, TTI)) {
if (Visited.insert(V).second) {
- PostorderStack.emplace_back(V, false);
+ PushConstantExpr(V);
if (auto *Op = dyn_cast<Operator>(V))
for (auto &O : Op->operands())
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(O))
if (isAddressExpression(*CE, *DL, TTI) && Visited.insert(CE).second)
- PostorderStack.emplace_back(CE, false);
+ PushConstantExpr(CE);
}
}
}
@@ -607,6 +621,7 @@ InferAddressSpacesImpl::collectFlatAddressExpressions(Function &F) const {
if (PostorderStack.back().getInt()) {
if (TopVal->getType()->getPointerAddressSpace() == FlatAddrSpace)
Postorder.push_back(TopVal);
+
PostorderStack.pop_back();
continue;
}
@@ -883,8 +898,9 @@ static Value *cloneConstantExprWithNewAddressSpace(
if (CE->getOpcode() == Instruction::IntToPtr) {
assert(isNoopPtrIntCastPair(cast<Operator>(CE), *DL, TTI));
Constant *Src = cast<ConstantExpr>(CE->getOperand(0))->getOperand(0);
- assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
- return Src;
+ if (Src->getType() == TargetType)
+ return Src;
+ return ConstantExpr::getAddrSpaceCast(Src, TargetType);
}
// Computes the operands of the new constant expression.
diff --git a/llvm/test/Transforms/InferAddressSpaces/NVPTX/inttoptr_constexpr.ll b/llvm/test/Transforms/InferAddressSpaces/NVPTX/inttoptr_constexpr.ll
new file mode 100644
index 0000000000000..5275b777a550c
--- /dev/null
+++ b/llvm/test/Transforms/InferAddressSpaces/NVPTX/inttoptr_constexpr.ll
@@ -0,0 +1,34 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -mtriple=nvptx64-nvidia-cuda -passes=infer-address-spaces %s | FileCheck %s
+
+ at g = addrspace(1) global i32 0, align 4
+
+define void @test() {
+; CHECK-LABEL: define void @test() {
+; CHECK-NEXT: store i32 0, ptr inttoptr (i64 xor (i64 ptrtoint (ptr addrspacecast (ptr addrspace(1) @g to ptr) to i64), i64 7) to ptr), align 4
+; CHECK-NEXT: ret void
+;
+ store i32 0, ptr inttoptr (i64
+ xor (i64
+ ptrtoint (ptr
+ addrspacecast (ptr addrspace(1) @g to ptr)
+ to i64),
+ i64 7)
+ to ptr)
+
+ ret void
+}
+
+define void @test1() {
+; CHECK-LABEL: define void @test1() {
+; CHECK-NEXT: store i32 0, ptr addrspace(1) @g, align 4
+; CHECK-NEXT: ret void
+;
+ store i32 0, ptr inttoptr (i64
+ ptrtoint (ptr
+ addrspacecast (ptr addrspace(1) @g to ptr)
+ to i64)
+ to ptr)
+
+ ret void
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/177809
More information about the llvm-commits
mailing list