diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 084e7fbaa268a..abad4e0059481 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3160,7 +3160,7 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp, return replaceInstUsesWith(Cmp, Cond); } const APInt *C2; - if (Cmp.isEquality() || !match(Y, m_APInt(C2))) + if (!match(Y, m_APInt(C2))) return nullptr; // Fold icmp pred (add X, C2), C. @@ -3184,8 +3184,9 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp, return new ICmpInst(Pred, X, ConstantInt::get(Ty, NewC)); } - if (ICmpInst::isUnsigned(Pred) && Add->hasNoSignedWrap() && - C.isNonNegative() && (C - *C2).isNonNegative() && + if (!Cmp.isEquality() && ICmpInst::isUnsigned(Pred) && + Add->hasNoSignedWrap() && C.isNonNegative() && + (C - *C2).isNonNegative() && computeConstantRange(X, /*ForSigned=*/true).add(*C2).isAllNonNegative()) return new ICmpInst(ICmpInst::getSignedPredicate(Pred), X, ConstantInt::get(Ty, C - *C2)); @@ -3205,6 +3206,9 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp, return new ICmpInst(ICmpInst::ICMP_UGE, X, ConstantInt::get(Ty, Lower)); } + if (Cmp.isEquality()) + return nullptr; + // This set of folds is intentionally placed after folds that use no-wrapping // flags because those folds are likely better for later analysis/codegen. const APInt SMax = APInt::getSignedMaxValue(Ty->getScalarSizeInBits()); diff --git a/llvm/test/Analysis/ValueTracking/phi-known-bits.ll b/llvm/test/Analysis/ValueTracking/phi-known-bits.ll index 436aadbc25de6..d2fa99237a4ac 100644 --- a/llvm/test/Analysis/ValueTracking/phi-known-bits.ll +++ b/llvm/test/Analysis/ValueTracking/phi-known-bits.ll @@ -1119,7 +1119,7 @@ define i32 @issue_124275_wrong_br_direction(i32 noundef %inp) { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = xor i32 [[INP:%.*]], -2 ; CHECK-NEXT: [[XOR_INP_NEG:%.*]] = add i32 [[TMP0]], 1 -; CHECK-NEXT: [[CMP_NE_NOT:%.*]] = icmp eq i32 [[XOR_INP_NEG]], 0 +; CHECK-NEXT: [[CMP_NE_NOT:%.*]] = icmp eq i32 [[INP]], 1 ; CHECK-NEXT: br i1 [[CMP_NE_NOT]], label [[B1:%.*]], label [[B0:%.*]] ; CHECK: B0: ; CHECK-NEXT: [[PHI_B0:%.*]] = phi i32 [ [[PHI_B1:%.*]], [[B1]] ], [ [[XOR_INP_NEG]], [[ENTRY:%.*]] ] diff --git a/llvm/test/Transforms/InstCombine/saturating-add-sub.ll b/llvm/test/Transforms/InstCombine/saturating-add-sub.ll index cfd679c0cc592..cc8ed078d4229 100644 --- a/llvm/test/Transforms/InstCombine/saturating-add-sub.ll +++ b/llvm/test/Transforms/InstCombine/saturating-add-sub.ll @@ -2350,4 +2350,15 @@ define i8 @fold_add_umax_to_usub_multiuse(i8 %a) { ret i8 %sel } +define i32 @add_check_zero(i32 %num) { +; CHECK-LABEL: @add_check_zero( +; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[NUM:%.*]], i32 1) +; CHECK-NEXT: ret i32 [[COND]] +; + %add = add i32 %num, 1 + %cmp = icmp eq i32 %add, 0 + %cond = select i1 %cmp, i32 -1, i32 %add + ret i32 %cond +} + declare void @usei8(i8) diff --git a/llvm/test/Transforms/InstCombine/uaddo.ll b/llvm/test/Transforms/InstCombine/uaddo.ll index ae7a07ec8000c..89a9569bdb7c3 100644 --- a/llvm/test/Transforms/InstCombine/uaddo.ll +++ b/llvm/test/Transforms/InstCombine/uaddo.ll @@ -158,7 +158,7 @@ define i1 @uaddo_1(i8 %x, ptr %p) { ; CHECK-LABEL: @uaddo_1( ; CHECK-NEXT: [[A:%.*]] = add i8 [[X:%.*]], 1 ; CHECK-NEXT: store i8 [[A]], ptr [[P:%.*]], align 1 -; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A]], 0 +; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[X]], -1 ; CHECK-NEXT: ret i1 [[C]] ; %a = add i8 %x, 1 diff --git a/llvm/test/Transforms/LoopVectorize/induction.ll b/llvm/test/Transforms/LoopVectorize/induction.ll index 5a5b06de69552..36688665f3bd3 100644 --- a/llvm/test/Transforms/LoopVectorize/induction.ll +++ b/llvm/test/Transforms/LoopVectorize/induction.ll @@ -3183,7 +3183,7 @@ define i32 @testoverflowcheck() { ; IND-NEXT: [[INC4_I:%.*]] = phi i8 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC_I:%.*]], [[COND_END_I]] ] ; IND-NEXT: [[AND_I:%.*]] = and i32 [[BC_MERGE_RDX]], [[TMP0]] ; IND-NEXT: [[INC_I]] = add i8 [[INC4_I]], 1 -; IND-NEXT: [[TOBOOL_I:%.*]] = icmp eq i8 [[INC_I]], 0 +; IND-NEXT: [[TOBOOL_I:%.*]] = icmp eq i8 [[INC4_I]], -1 ; IND-NEXT: br i1 [[TOBOOL_I]], label [[LOOPEXIT]], label [[COND_END_I]], !llvm.loop [[LOOP33:![0-9]+]] ; IND: loopexit: ; IND-NEXT: [[AND_I_LCSSA:%.*]] = phi i32 [ [[AND_I]], [[COND_END_I]] ], [ [[TMP7]], [[MIDDLE_BLOCK]] ] @@ -3225,7 +3225,7 @@ define i32 @testoverflowcheck() { ; UNROLL-NEXT: [[INC4_I:%.*]] = phi i8 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC_I:%.*]], [[COND_END_I]] ] ; UNROLL-NEXT: [[AND_I:%.*]] = and i32 [[BC_MERGE_RDX]], [[TMP0]] ; UNROLL-NEXT: [[INC_I]] = add i8 [[INC4_I]], 1 -; UNROLL-NEXT: [[TOBOOL_I:%.*]] = icmp eq i8 [[INC_I]], 0 +; UNROLL-NEXT: [[TOBOOL_I:%.*]] = icmp eq i8 [[INC4_I]], -1 ; UNROLL-NEXT: br i1 [[TOBOOL_I]], label [[LOOPEXIT]], label [[COND_END_I]], !llvm.loop [[LOOP33:![0-9]+]] ; UNROLL: loopexit: ; UNROLL-NEXT: [[AND_I_LCSSA:%.*]] = phi i32 [ [[AND_I]], [[COND_END_I]] ], [ [[TMP7]], [[MIDDLE_BLOCK]] ] @@ -3315,7 +3315,7 @@ define i32 @testoverflowcheck() { ; INTERLEAVE-NEXT: [[INC4_I:%.*]] = phi i8 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC_I:%.*]], [[COND_END_I]] ] ; INTERLEAVE-NEXT: [[AND_I:%.*]] = and i32 [[BC_MERGE_RDX]], [[TMP0]] ; INTERLEAVE-NEXT: [[INC_I]] = add i8 [[INC4_I]], 1 -; INTERLEAVE-NEXT: [[TOBOOL_I:%.*]] = icmp eq i8 [[INC_I]], 0 +; INTERLEAVE-NEXT: [[TOBOOL_I:%.*]] = icmp eq i8 [[INC4_I]], -1 ; INTERLEAVE-NEXT: br i1 [[TOBOOL_I]], label [[LOOPEXIT]], label [[COND_END_I]], !llvm.loop [[LOOP33:![0-9]+]] ; INTERLEAVE: loopexit: ; INTERLEAVE-NEXT: [[AND_I_LCSSA:%.*]] = phi i32 [ [[AND_I]], [[COND_END_I]] ], [ [[TMP7]], [[MIDDLE_BLOCK]] ] @@ -5399,7 +5399,7 @@ define i32 @PR32419(i32 %a, i16 %b) { ; INTERLEAVE-NEXT: [[VAR4:%.*]] = phi i32 [ [[TMP50]], [[FOR_COND]] ], [ 0, [[FOR_BODY]] ] ; INTERLEAVE-NEXT: [[VAR6]] = or i32 [[VAR0]], [[VAR4]] ; INTERLEAVE-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 -; INTERLEAVE-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], 0 +; INTERLEAVE-NEXT: [[COND:%.*]] = icmp eq i32 [[I]], -1 ; INTERLEAVE-NEXT: br i1 [[COND]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP47:![0-9]+]] ; INTERLEAVE: for.end: ; INTERLEAVE-NEXT: [[VAR7:%.*]] = phi i32 [ [[VAR6]], [[FOR_INC]] ], [ poison, [[MIDDLE_BLOCK]] ] diff --git a/llvm/test/Transforms/PhaseOrdering/deletion-of-loops-that-became-side-effect-free.ll b/llvm/test/Transforms/PhaseOrdering/deletion-of-loops-that-became-side-effect-free.ll index 641f216302146..df78f3d8fd54a 100644 --- a/llvm/test/Transforms/PhaseOrdering/deletion-of-loops-that-became-side-effect-free.ll +++ b/llvm/test/Transforms/PhaseOrdering/deletion-of-loops-that-became-side-effect-free.ll @@ -96,35 +96,10 @@ while.end: } define dso_local zeroext i1 @is_not_empty_variant3(ptr %p) { -; O3-LABEL: @is_not_empty_variant3( -; O3-NEXT: entry: -; O3-NEXT: [[TOBOOL_NOT4_I:%.*]] = icmp ne ptr [[P:%.*]], null -; O3-NEXT: ret i1 [[TOBOOL_NOT4_I]] -; -; O2-LABEL: @is_not_empty_variant3( -; O2-NEXT: entry: -; O2-NEXT: [[TOBOOL_NOT4_I:%.*]] = icmp ne ptr [[P:%.*]], null -; O2-NEXT: ret i1 [[TOBOOL_NOT4_I]] -; -; O1-LABEL: @is_not_empty_variant3( -; O1-NEXT: entry: -; O1-NEXT: [[TOBOOL_NOT4_I:%.*]] = icmp eq ptr [[P:%.*]], null -; O1-NEXT: br i1 [[TOBOOL_NOT4_I]], label [[COUNT_NODES_VARIANT3_EXIT:%.*]], label [[WHILE_BODY_I:%.*]] -; O1: while.body.i: -; O1-NEXT: [[SIZE_06_I:%.*]] = phi i64 [ [[INC_I:%.*]], [[WHILE_BODY_I]] ], [ 0, [[ENTRY:%.*]] ] -; O1-NEXT: [[P_ADDR_05_I:%.*]] = phi ptr [ [[TMP0:%.*]], [[WHILE_BODY_I]] ], [ [[P]], [[ENTRY]] ] -; O1-NEXT: [[CMP_I:%.*]] = icmp ne i64 [[SIZE_06_I]], -1 -; O1-NEXT: call void @llvm.assume(i1 [[CMP_I]]) -; O1-NEXT: [[TMP0]] = load ptr, ptr [[P_ADDR_05_I]], align 8 -; O1-NEXT: [[INC_I]] = add i64 [[SIZE_06_I]], 1 -; O1-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp eq ptr [[TMP0]], null -; O1-NEXT: br i1 [[TOBOOL_NOT_I]], label [[COUNT_NODES_VARIANT3_EXIT_LOOPEXIT:%.*]], label [[WHILE_BODY_I]], !llvm.loop [[LOOP0:![0-9]+]] -; O1: count_nodes_variant3.exit.loopexit: -; O1-NEXT: [[PHI_CMP:%.*]] = icmp ne i64 [[INC_I]], 0 -; O1-NEXT: br label [[COUNT_NODES_VARIANT3_EXIT]] -; O1: count_nodes_variant3.exit: -; O1-NEXT: [[SIZE_0_LCSSA_I:%.*]] = phi i1 [ false, [[ENTRY]] ], [ [[PHI_CMP]], [[COUNT_NODES_VARIANT3_EXIT_LOOPEXIT]] ] -; O1-NEXT: ret i1 [[SIZE_0_LCSSA_I]] +; ALL-LABEL: @is_not_empty_variant3( +; ALL-NEXT: entry: +; ALL-NEXT: [[TOBOOL_NOT4_I:%.*]] = icmp ne ptr [[P:%.*]], null +; ALL-NEXT: ret i1 [[TOBOOL_NOT4_I]] ; entry: %p.addr = alloca ptr, align 8 @@ -182,3 +157,7 @@ declare void @llvm.assume(i1 noundef) !1 = !{!"llvm.loop.mustprogress"} !2 = distinct !{!2, !1} !3 = distinct !{!3, !1} +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; O1: {{.*}} +; O2: {{.*}} +; O3: {{.*}}