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
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');
; 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:
; 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:
; 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:
; 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:
; 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()
; 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()
; 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
;