[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:
parent
3122e20cfc
commit
690aacbf9d
3 changed files with 72 additions and 2 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue