1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[IndVars] Provide eliminateIVComparison with context

We can prove more predicates when we have a context when eliminating ICmp.
As first (and very obvious) approximation we can use the ICmp instruction itself,
though in the future we are going to use a common dominator of all its users.
Need some refactoring before that.

Observed ~0.5% negative compile time impact.

Differential Revision: https://reviews.llvm.org/D98697
Reviewed By: lebedev.ri
This commit is contained in:
Max Kazantsev 2021-03-19 12:00:06 +07:00
parent 3f557c49c2
commit 13391d5a59
5 changed files with 15 additions and 22 deletions

View File

@ -261,9 +261,10 @@ void SimplifyIndvar::eliminateIVComparison(ICmpInst *ICmp, Value *IVOperand) {
const SCEV *S = SE->getSCEVAtScope(ICmp->getOperand(IVOperIdx), ICmpLoop);
const SCEV *X = SE->getSCEVAtScope(ICmp->getOperand(1 - IVOperIdx), ICmpLoop);
// If the condition is always true or always false, replace it with
// a constant value.
if (auto Ev = SE->evaluatePredicate(Pred, S, X)) {
// If the condition is always true or always false in the given context,
// replace it with a constant value.
// TODO: We can sharpen the context to common dominator of all ICmp's users.
if (auto Ev = SE->evaluatePredicateAt(Pred, S, X, ICmp)) {
ICmp->replaceAllUsesWith(ConstantInt::getBool(ICmp->getContext(), *Ev));
DeadInsts.emplace_back(ICmp);
LLVM_DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n');

View File

@ -23,7 +23,7 @@ define i32 @testDiv(i8* %p, i64* %p1) {
; CHECK-NEXT: [[I4:%.*]] = load atomic i64, i64* [[P1:%.*]] unordered, align 8
; CHECK-NEXT: [[I6:%.*]] = sub i64 [[I4]], [[INDVARS_IV_NEXT2]]
; CHECK-NEXT: store atomic i64 [[I6]], i64* [[P1]] unordered, align 8
; CHECK-NEXT: br i1 false, label [[LOOP2_EXIT_LOOPEXIT:%.*]], label [[LOOP2]]
; CHECK-NEXT: br i1 true, label [[LOOP2_EXIT_LOOPEXIT:%.*]], label [[LOOP2]]
; CHECK: loop2.exit.loopexit:
; CHECK-NEXT: br label [[LOOP2_EXIT]]
; CHECK: loop2.exit:
@ -94,7 +94,7 @@ define i32 @testRem(i8* %p, i64* %p1) {
; CHECK-NEXT: [[I4:%.*]] = load atomic i64, i64* [[P1:%.*]] unordered, align 8
; CHECK-NEXT: [[I6:%.*]] = sub i64 [[I4]], [[INDVARS_IV_NEXT]]
; CHECK-NEXT: store atomic i64 [[I6]], i64* [[P1]] unordered, align 8
; CHECK-NEXT: br i1 false, label [[LOOP2_EXIT_LOOPEXIT:%.*]], label [[LOOP2]]
; CHECK-NEXT: br i1 true, label [[LOOP2_EXIT_LOOPEXIT:%.*]], label [[LOOP2]]
; CHECK: loop2.exit.loopexit:
; CHECK-NEXT: br label [[LOOP2_EXIT]]
; CHECK: loop2.exit:

View File

@ -15,8 +15,7 @@ define void @test_signed(i32 %start) {
; CHECK-NEXT: [[CHECK:%.*]] = icmp slt i32 [[IV_NEXT]], [[IV]]
; CHECK-NEXT: br i1 [[CHECK]], label [[GUARDED]], label [[FAIL:%.*]]
; CHECK: guarded:
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], -2147483648
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
; CHECK-NEXT: br i1 true, label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
; CHECK: exit.loopexit:
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
@ -58,8 +57,7 @@ define void @test_unsigned(i32 %start) {
; CHECK-NEXT: [[CHECK:%.*]] = icmp ult i32 [[IV_NEXT]], [[IV]]
; CHECK-NEXT: br i1 [[CHECK]], label [[GUARDED]], label [[FAIL:%.*]]
; CHECK: guarded:
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 0
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
; CHECK-NEXT: br i1 true, label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
; CHECK: exit.loopexit:
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:

View File

@ -951,11 +951,9 @@ define i32 @func_25(i32 %start) {
; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[IV]], 0
; CHECK-NEXT: br i1 [[C1]], label [[CHECKED_1:%.*]], label [[FAIL:%.*]]
; CHECK: checked.1:
; CHECK-NEXT: [[C2:%.*]] = icmp ne i32 [[IV]], 0
; CHECK-NEXT: br i1 [[C2]], label [[CHECKED_2:%.*]], label [[FAIL]]
; CHECK-NEXT: br i1 true, label [[CHECKED_2:%.*]], label [[FAIL]]
; CHECK: checked.2:
; CHECK-NEXT: [[C3:%.*]] = icmp ne i32 [[IV]], 0
; CHECK-NEXT: br i1 [[C3]], label [[BACKEDGE]], label [[FAIL]]
; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[FAIL]]
; CHECK: backedge:
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 758394
; CHECK-NEXT: [[LOOP_COND:%.*]] = call i1 @cond_func()
@ -1003,11 +1001,9 @@ define i32 @func_26(i32 %start) {
; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[IV]], 0
; CHECK-NEXT: br i1 [[C1]], label [[CHECKED_1:%.*]], label [[FAIL:%.*]]
; CHECK: checked.1:
; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[IV]], 1
; CHECK-NEXT: br i1 [[C2]], label [[CHECKED_2:%.*]], label [[FAIL]]
; CHECK-NEXT: br i1 true, label [[CHECKED_2:%.*]], label [[FAIL]]
; CHECK: checked.2:
; CHECK-NEXT: [[C3:%.*]] = icmp slt i32 [[IV]], 2
; CHECK-NEXT: br i1 [[C3]], label [[BACKEDGE]], label [[FAIL]]
; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[FAIL]]
; CHECK: backedge:
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 758394
; CHECK-NEXT: [[LOOP_COND:%.*]] = call i1 @cond_func()

View File

@ -8,12 +8,10 @@ define void @test() {
; CHECK-LABEL: @test(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.cond:
; CHECK-NEXT: br i1 true, label [[FOR_BODY]], label [[FOR_END:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[A_01:%.*]] = phi i16 [ undef, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
; CHECK-NEXT: [[INC]] = add nsw i16 [[A_01]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i16 [[INC]], 2
; CHECK-NEXT: [[OR_COND:%.*]] = and i1 false, [[CMP]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
; CHECK-NEXT: br i1 false, label [[FOR_COND:%.*]], label [[FOR_END]]
; CHECK: for.end:
; CHECK-NEXT: ret void
;