[ValueTracking] Handle more non-trivial conditions in isKnownNonZero()
authorNikita Popov <nikita.ppv@gmail.com>
Sat, 26 Dec 2020 14:22:20 +0000 (15:22 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Sat, 26 Dec 2020 14:48:04 +0000 (15:48 +0100)
In 35676a4f9a536a2aab768af63ddbb15bc722d7f9 I've added handling for
non-trivial dominating conditions that imply non-zero on the true
branch. This adds the same support for the false branch.

The changes in pr45360.ll change block ordering and naming, but
don't change the control flow. The urem is still guaraded by a
non-zero check correctly.

llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/IndVarSimplify/X86/pr45360.ll
llvm/test/Transforms/InstCombine/known-non-zero.ll

index fdbb7f49cf18666eb1918ae2623ccdac7b51138b..29091806cff3b7fb41299434c4593ec0f525a1fe 100644 (file)
@@ -2111,7 +2111,7 @@ static bool isKnownNonNullFromDominatingCondition(const Value *V,
     bool NonNullIfTrue;
     if (cmpExcludesZero(Pred, RHS))
       NonNullIfTrue = true;
-    else if (Pred == ICmpInst::ICMP_EQ && match(RHS, m_Zero()))
+    else if (cmpExcludesZero(CmpInst::getInversePredicate(Pred), RHS))
       NonNullIfTrue = false;
     else
       continue;
index a100f7b4e8222365dd42c889e5f976a0d018c1c9..e86277adf936960a80ed0e077ed2aedd1b604bbf 100644 (file)
@@ -21,29 +21,29 @@ define dso_local i32 @main() {
 ; CHECK-NEXT:  bb:
 ; CHECK-NEXT:    [[I6:%.*]] = load i32, i32* @a, align 4
 ; CHECK-NEXT:    [[I24:%.*]] = load i32, i32* @b, align 4
-; CHECK-NEXT:    [[D_PROMOTED8:%.*]] = load i32, i32* @d, align 4
-; CHECK-NEXT:    br label [[BB19:%.*]]
-; CHECK:       bb19:
-; CHECK-NEXT:    [[I8_LCSSA9:%.*]] = phi i32 [ [[D_PROMOTED8]], [[BB:%.*]] ], [ [[I8:%.*]], [[BB27:%.*]] ]
-; CHECK-NEXT:    [[I8]] = and i32 [[I8_LCSSA9]], [[I6]]
+; CHECK-NEXT:    [[D_PROMOTED9:%.*]] = load i32, i32* @d, align 4
+; CHECK-NEXT:    br label [[BB1:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[I8_LCSSA10:%.*]] = phi i32 [ [[D_PROMOTED9]], [[BB:%.*]] ], [ [[I8:%.*]], [[BB19_PREHEADER:%.*]] ]
+; CHECK-NEXT:    [[I8]] = and i32 [[I8_LCSSA10]], [[I6]]
 ; CHECK-NEXT:    [[I21:%.*]] = icmp eq i32 [[I8]], 0
-; CHECK-NEXT:    br i1 [[I21]], label [[BB27_THREAD:%.*]], label [[BB27]]
-; CHECK:       bb27.thread:
+; CHECK-NEXT:    br i1 [[I21]], label [[BB13_PREHEADER_BB27_THREAD_SPLIT_CRIT_EDGE:%.*]], label [[BB19_PREHEADER]]
+; CHECK:       bb19.preheader:
+; CHECK-NEXT:    [[I26:%.*]] = urem i32 [[I24]], [[I8]]
+; CHECK-NEXT:    store i32 [[I26]], i32* @e, align 4
+; CHECK-NEXT:    [[I30_NOT:%.*]] = icmp eq i32 [[I26]], 0
+; CHECK-NEXT:    br i1 [[I30_NOT]], label [[BB32_LOOPEXIT:%.*]], label [[BB1]]
+; CHECK:       bb13.preheader.bb27.thread.split_crit_edge:
 ; CHECK-NEXT:    store i32 -1, i32* @f, align 4
 ; CHECK-NEXT:    store i32 0, i32* @d, align 4
 ; CHECK-NEXT:    store i32 0, i32* @c, align 4
 ; CHECK-NEXT:    br label [[BB32:%.*]]
-; CHECK:       bb27:
-; CHECK-NEXT:    [[I26:%.*]] = urem i32 [[I24]], [[I8]]
-; CHECK-NEXT:    store i32 [[I26]], i32* @e, align 4
-; CHECK-NEXT:    [[I30:%.*]] = icmp eq i32 [[I26]], 0
-; CHECK-NEXT:    br i1 [[I30]], label [[BB32_LOOPEXIT:%.*]], label [[BB19]]
 ; CHECK:       bb32.loopexit:
 ; CHECK-NEXT:    store i32 -1, i32* @f, align 4
 ; CHECK-NEXT:    store i32 [[I8]], i32* @d, align 4
 ; CHECK-NEXT:    br label [[BB32]]
 ; CHECK:       bb32:
-; CHECK-NEXT:    [[C_SINK:%.*]] = phi i32* [ @c, [[BB32_LOOPEXIT]] ], [ @e, [[BB27_THREAD]] ]
+; CHECK-NEXT:    [[C_SINK:%.*]] = phi i32* [ @c, [[BB32_LOOPEXIT]] ], [ @e, [[BB13_PREHEADER_BB27_THREAD_SPLIT_CRIT_EDGE]] ]
 ; CHECK-NEXT:    store i32 0, i32* [[C_SINK]], align 4
 ; CHECK-NEXT:    ret i32 0
 ;
index ac2dfaa9089e1077f986786cbf2379d0f95711b1..3ad1ebe55b2ce844b22d0f366c784d8a2131eea1 100644 (file)
@@ -232,7 +232,7 @@ define i64 @test_sle_zero(i64 %x) {
 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i64 [[X:%.*]], 1
 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[NON_ZERO:%.*]]
 ; CHECK:       non_zero:
-; CHECK-NEXT:    [[CTZ:%.*]] = call i64 @llvm.ctlz.i64(i64 [[X]], i1 false), [[RNG0]]
+; CHECK-NEXT:    [[CTZ:%.*]] = call i64 @llvm.ctlz.i64(i64 [[X]], i1 true), [[RNG0]]
 ; CHECK-NEXT:    ret i64 [[CTZ]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret i64 -1
@@ -255,7 +255,7 @@ define i64 @test_sge_neg_ten(i64 %x) {
 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i64 [[X:%.*]], -11
 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[NON_ZERO:%.*]]
 ; CHECK:       non_zero:
-; CHECK-NEXT:    [[CTZ:%.*]] = call i64 @llvm.ctlz.i64(i64 [[X]], i1 false), [[RNG0]]
+; CHECK-NEXT:    [[CTZ:%.*]] = call i64 @llvm.ctlz.i64(i64 [[X]], i1 true), [[RNG0]]
 ; CHECK-NEXT:    ret i64 [[CTZ]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret i64 -1