[GVN] Reuse dominating PtrToInt for PtrToAddr. (#209164)

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.

PR: https://github.com/llvm/llvm-project/pull/209164
This commit is contained in:
Florian Hahn 2026-07-13 18:20:25 +01:00 committed by GitHub
parent 3122e20cfc
commit 690aacbf9d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 72 additions and 2 deletions

View file

@ -222,6 +222,7 @@ public:
LLVM_ABI uint32_t lookup(Value *V, bool Verify = true) const;
LLVM_ABI uint32_t lookupOrAddCmp(unsigned Opcode, CmpInst::Predicate Pred,
Value *LHS, Value *RHS);
LLVM_ABI uint32_t lookupPtrToInt(Value *Ptr, Type *Ty);
LLVM_ABI uint32_t phiTranslate(const BasicBlock *BB,
const BasicBlock *PhiBlock, uint32_t Num,
GVNPass &GVN);

View file

@ -750,6 +750,14 @@ uint32_t GVNPass::ValueTable::lookupOrAddCmp(unsigned Opcode,
return assignExpNewValueNum(Exp).first;
}
/// Returns the value number of ptrtoint \p Ptr to \Ty.
uint32_t GVNPass::ValueTable::lookupPtrToInt(Value *Ptr, Type *Ty) {
Expression Exp(Instruction::PtrToInt);
Exp.Ty = Ty;
Exp.VarArgs.push_back(lookupOrAdd(Ptr));
return ExpressionNumbering.lookup(Exp);
}
/// Remove all entries from the ValueTable.
void GVNPass::ValueTable::clear() {
ValueNumbering.clear();
@ -3400,6 +3408,23 @@ 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.
if (auto *PTA = dyn_cast<PtrToAddrInst>(I)) {
const DataLayout &DL = I->getDataLayout();
unsigned AS = PTA->getPointerAddressSpace();
if (DL.getAddressSizeInBits(AS) == DL.getPointerSizeInBits(AS) &&
!DL.hasUnstableRepresentation(AS)) {
uint32_t PTINum =
VN.lookupPtrToInt(PTA->getPointerOperand(), PTA->getType());
if (Value *PTI = findLeader(I->getParent(), PTINum)) {
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!

View file

@ -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
}