Skip to content

Commit

Permalink
[instsimplify] Assume storage for byval args doesn't overlap allocas,…
Browse files Browse the repository at this point in the history
… globals, or other byval args

This allows us to discharge many pointer comparisons based on byval arguments.

Differential Revision: https://reviews.llvm.org/D120133
  • Loading branch information
preames committed Feb 18, 2022
1 parent eae62b2 commit ff2e4c0
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 13 deletions.
22 changes: 19 additions & 3 deletions llvm/lib/Analysis/InstructionSimplify.cpp
Expand Up @@ -2555,7 +2555,19 @@ static bool HaveNonOverlappingStorage(const Value *V1, const Value *V2) {
//
// So, we'll assume that two non-empty allocas have different addresses
// for now.
return isa<AllocaInst>(V1) &&
auto isByValArg = [](const Value *V) {
const Argument *A = dyn_cast<Argument>(V);
return A && A->hasByValAttr();
};

// Byval args are backed by store which does not overlap with each other,
// allocas, or globals.
if (isByValArg(V1))
return isa<AllocaInst>(V2) || isa<GlobalVariable>(V2) || isByValArg(V2);
if (isByValArg(V2))
return isa<AllocaInst>(V1) || isa<GlobalVariable>(V1) || isByValArg(V1);

return isa<AllocaInst>(V1) &&
(isa<AllocaInst>(V2) || isa<GlobalVariable>(V2));
}

Expand Down Expand Up @@ -2659,8 +2671,12 @@ computePointerICmp(CmpInst::Predicate Pred, Value *LHS, Value *RHS,
uint64_t LHSSize, RHSSize;
ObjectSizeOpts Opts;
Opts.EvalMode = ObjectSizeOpts::Mode::Min;
Opts.NullIsUnknownSize =
NullPointerIsDefined(cast<AllocaInst>(LHS)->getFunction());
auto *F = [](Value *V) {
if (auto *I = dyn_cast<Instruction>(V))
return I->getFunction();
return cast<Argument>(V)->getParent();
}(LHS);
Opts.NullIsUnknownSize = NullPointerIsDefined(F);
if (getObjectSize(LHS, LHSSize, DL, TLI, Opts) &&
getObjectSize(RHS, RHSSize, DL, TLI, Opts) &&
!LHSOffset.isNegative() && !RHSOffset.isNegative() &&
Expand Down
16 changes: 6 additions & 10 deletions llvm/test/Transforms/InstSimplify/compare.ll
Expand Up @@ -2737,11 +2737,10 @@ define i1 @scalar_vectors_are_non_empty() {
ret i1 %res
}

; TODO: Never equal
; Never equal
define i1 @byval_args_inequal(i32* byval(i32) %a, i32* byval(i32) %b) {
; CHECK-LABEL: @byval_args_inequal(
; CHECK-NEXT: [[RES:%.*]] = icmp ne i32* [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: ret i1 [[RES]]
; CHECK-NEXT: ret i1 true
;
%res = icmp ne i32* %a, %b
ret i1 %res
Expand All @@ -2759,12 +2758,10 @@ define i1 @neg_args_adjacent(i32* byval(i32) %a, i32* byval(i32) %b) {
ret i1 %res
}

; TODO: Never equal
; Never equal
define i1 @test_byval_alloca_inequal(i32* byval(i32) %a) {
; CHECK-LABEL: @test_byval_alloca_inequal(
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[RES:%.*]] = icmp ne i32* [[A:%.*]], [[B]]
; CHECK-NEXT: ret i1 [[RES]]
; CHECK-NEXT: ret i1 true
;
%b = alloca i32
%res = icmp ne i32* %a, %b
Expand Down Expand Up @@ -2812,11 +2809,10 @@ define i1 @globals_offset_inequal() {
}


; TODO: Never equal
; Never equal
define i1 @test_byval_global_inequal(i32* byval(i32) %a) {
; CHECK-LABEL: @test_byval_global_inequal(
; CHECK-NEXT: [[RES:%.*]] = icmp ne i32* [[A:%.*]], @B
; CHECK-NEXT: ret i1 [[RES]]
; CHECK-NEXT: ret i1 true
;
%b = alloca i32
%res = icmp ne i32* %a, @B
Expand Down

0 comments on commit ff2e4c0

Please sign in to comment.