[llvm] [GVN] Reuse dominating PtrToInt for PtrToAddr. (PR #209164)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 13 05:43:30 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Florian Hahn (fhahn)
<details>
<summary>Changes</summary>
A ptrtoaddr and a ptrtoint of the same pointer compute the same value
when the address width equals the pointer representation width. Reuse
a dominating ptrtoint in place of a ptrtoaddr.
This fixes a few end-to-end regressions with
https://github.com/llvm/llvm-project/pull/180244.
I am not sure if there's a better way to implement this. Initially I
tried to use the same numbering for PtrToInt and PtrToAddr, but then
there are multiple places where we need to check the direction is
correct, which seemed a bit more fragile.
---
Full diff: https://github.com/llvm/llvm-project/pull/209164.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Scalar/GVN.cpp (+24)
- (modified) llvm/test/Transforms/GVN/ptrtoaddr.ll (+46-2)
``````````diff
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 517d33bfba103..91939bb965a5c 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -3400,6 +3400,30 @@ bool GVNPass::processInstruction(Instruction *I) {
return false;
}
+ // A ptrtoaddr and a ptrtoint of the same pointer compute the same value when
+ // the address width equals the pointer representation width. Reuse a
+ // dominating ptrtoint in place of a ptrtoaddr.
+ if (auto *PTA = dyn_cast<PtrToAddrInst>(I)) {
+ const DataLayout &DL = I->getDataLayout();
+ unsigned AS = PTA->getPointerAddressSpace();
+ Value *Ptr = PTA->getPointerOperand();
+ if (DL.getAddressSizeInBits(AS) == DL.getPointerSizeInBits(AS) &&
+ !DL.hasUnstableRepresentation(AS) && Ptr->hasUseList()) {
+ unsigned Scanned = 0;
+ for (User *U : Ptr->users()) {
+ if (++Scanned >= ScanUsersLimit)
+ break;
+ auto *PTI = dyn_cast<PtrToIntInst>(U);
+ if (PTI && PTI->getType() == I->getType() && PTI != I &&
+ DT->dominates(PTI, I)) {
+ patchAndReplaceAllUsesWith(I, PTI);
+ salvageAndRemoveInstruction(I);
+ return true;
+ }
+ }
+ }
+ }
+
// If the number we were assigned was a brand new VN, then we don't
// need to do a lookup to see if the number already exists
// somewhere in the domtree: it can't!
diff --git a/llvm/test/Transforms/GVN/ptrtoaddr.ll b/llvm/test/Transforms/GVN/ptrtoaddr.ll
index a731ef433741a..c96961762194e 100644
--- a/llvm/test/Transforms/GVN/ptrtoaddr.ll
+++ b/llvm/test/Transforms/GVN/ptrtoaddr.ll
@@ -33,8 +33,7 @@ define i64 @ptrtoaddr_reuses_dominating_ptrtoint(ptr %p) {
; CHECK-LABEL: define i64 @ptrtoaddr_reuses_dominating_ptrtoint(
; CHECK-SAME: ptr [[P:%.*]]) {
; CHECK-NEXT: [[I:%.*]] = ptrtoint ptr [[P]] to i64
-; CHECK-NEXT: [[A:%.*]] = ptrtoaddr ptr [[P]] to i64
-; CHECK-NEXT: [[R:%.*]] = add i64 [[I]], [[A]]
+; CHECK-NEXT: [[R:%.*]] = add i64 [[I]], [[I]]
; CHECK-NEXT: ret i64 [[R]]
;
%i = ptrtoint ptr %p to i64
@@ -74,3 +73,48 @@ define i64 @ptrtoaddr_wrong_type(ptr %p) {
%r = add i64 %z, %a
ret i64 %r
}
+
+define i64 @ptrtoint_not_pred_from_ptrtoaddr(ptr %p, i1 %c) {
+; CHECK-LABEL: define i64 @ptrtoint_not_pred_from_ptrtoaddr(
+; CHECK-SAME: ptr [[P:%.*]], i1 [[C:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = ptrtoaddr ptr [[P]] to i64
+; CHECK-NEXT: br i1 [[C]], label %[[THEN:.*]], label %[[ELSE:.*]]
+; CHECK: [[THEN]]:
+; CHECK-NEXT: br label %[[MERGE:.*]]
+; CHECK: [[ELSE]]:
+; CHECK-NEXT: br label %[[MERGE]]
+; CHECK: [[MERGE]]:
+; CHECK-NEXT: [[I:%.*]] = ptrtoint ptr [[P]] to i64
+; CHECK-NEXT: ret i64 [[I]]
+;
+ %a = ptrtoaddr ptr %p to i64
+ br i1 %c, label %then, label %else
+
+then:
+ br label %merge
+
+else:
+ br label %merge
+
+merge:
+ %i = ptrtoint ptr %p to i64
+ ret i64 %i
+}
+
+define i64 @no_transitive_merge_of_ptrtoint_and_ptrtoaddr(ptr %p) {
+; CHECK-LABEL: define i64 @no_transitive_merge_of_ptrtoint_and_ptrtoaddr(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = ptrtoaddr ptr [[P]] to i64
+; CHECK-NEXT: [[ADDA:%.*]] = add i64 [[A]], 7
+; CHECK-NEXT: [[I:%.*]] = ptrtoint ptr [[P]] to i64
+; CHECK-NEXT: [[ADDI:%.*]] = add i64 [[I]], 7
+; CHECK-NEXT: [[R:%.*]] = add i64 [[ADDA]], [[ADDI]]
+; CHECK-NEXT: ret i64 [[R]]
+;
+ %a = ptrtoaddr ptr %p to i64
+ %adda = add i64 %a, 7
+ %i = ptrtoint ptr %p to i64
+ %addi = add i64 %i, 7
+ %r = add i64 %adda, %addi
+ ret i64 %r
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/209164
More information about the llvm-commits
mailing list