diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -737,6 +737,8 @@ bool ConstraintInfo::doesHold(CmpInst::Predicate Pred, Value *A, Value *B) const { + if (Pred == CmpInst::ICMP_ULE && A == Constant::getNullValue(A->getType())) + return true; auto R = getConstraintForSolving(Pred, A, B); return R.isValid(*this) && getCS(R.IsSigned).isConditionImplied(R.Coefficients); diff --git a/llvm/test/Transforms/ConstraintElimination/loops-header-tested-pointer-cmps.ll b/llvm/test/Transforms/ConstraintElimination/loops-header-tested-pointer-cmps.ll --- a/llvm/test/Transforms/ConstraintElimination/loops-header-tested-pointer-cmps.ll +++ b/llvm/test/Transforms/ConstraintElimination/loops-header-tested-pointer-cmps.ll @@ -572,15 +572,12 @@ ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] ; CHECK: for.body: ; CHECK-NEXT: [[GEP_IV:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i16 [[IV]] -; CHECK-NEXT: [[CMP_IV_UPPER:%.*]] = icmp ule ptr [[UPPER]], [[GEP_IV]] -; CHECK-NEXT: [[OR:%.*]] = or i1 false, [[CMP_IV_UPPER]] +; CHECK-NEXT: [[OR:%.*]] = or i1 false, false ; CHECK-NEXT: br i1 [[OR]], label [[TRAP]], label [[FOR_BODY_1:%.*]] ; CHECK: for.body.1: ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[IV]], 1 ; CHECK-NEXT: [[GEP_IV_1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i16 [[ADD]] -; CHECK-NEXT: [[CMP_IV_1_LOWER:%.*]] = icmp ugt ptr [[LOWER]], [[GEP_IV_1]] -; CHECK-NEXT: [[CMP_IV_1_UPPER:%.*]] = icmp ule ptr [[UPPER]], [[GEP_IV_1]] -; CHECK-NEXT: [[OR_1:%.*]] = or i1 [[CMP_IV_1_LOWER]], [[CMP_IV_1_UPPER]] +; CHECK-NEXT: [[OR_1:%.*]] = or i1 false, false ; CHECK-NEXT: br i1 [[OR_1]], label [[TRAP]], label [[FOR_LATCH]] ; CHECK: for.latch: ; CHECK-NEXT: store i8 0, ptr [[GEP_IV]], align 4 diff --git a/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis.ll b/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis.ll --- a/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis.ll +++ b/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis.ll @@ -20,8 +20,7 @@ ; CHECK-NEXT: [[C:%.*]] = icmp eq i16 [[IV]], [[LEN]] ; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] ; CHECK: for.body: -; CHECK-NEXT: [[T_2:%.*]] = icmp ult i16 [[IV]], [[A]] -; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] +; CHECK-NEXT: [[AND:%.*]] = and i1 true, true ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] ; CHECK: loop.latch: ; CHECK-NEXT: call void @use(i16 [[IV]]) diff --git a/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll b/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll --- a/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll +++ b/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll @@ -145,13 +145,7 @@ ; CHECK: for.cond.cleanup: ; CHECK-NEXT: ret void ; CHECK: for.body: -; CHECK-NEXT: [[I_010:%.*]] = phi i64 [ [[INC:%.*]], [[OPERATOR_ACC_EXIT:%.*]] ], [ 0, [[ENTRY:%.*]] ] -; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ugt i64 [[SUB_PTR_DIV_I_I]], [[I_010]] -; CHECK-NEXT: br i1 [[CMP_NOT_I]], label [[OPERATOR_ACC_EXIT]], label [[IF_THEN_I:%.*]] -; CHECK: if.then.i: -; CHECK-NEXT: tail call void @abort() #[[ATTR1:[0-9]+]] -; CHECK-NEXT: unreachable -; CHECK: operator_acc.exit: +; CHECK-NEXT: [[I_010:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i64 [[I_010]] ; CHECK-NEXT: [[TMP2:%.*]] = load double, ptr [[ADD_PTR_I]], align 8 ; CHECK-NEXT: [[ADD:%.*]] = fadd double [[TMP2]], 1.000000e+00