Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -2340,16 +2340,18 @@ // Can we use context to prove the fact we need? if (!CtxI) return false; - // We can prove that add(x, constant) doesn't wrap if isKnownPredicateAt can - // guarantee that x <= max_int - constant at the given context. - // TODO: Support other operations. - if (BinOp != Instruction::Add) - return false; auto *RHSC = dyn_cast(RHS); // TODO: Lift this limitation. if (!RHSC) return false; APInt C = RHSC->getAPInt(); + // We can prove that add(x, constant) doesn't wrap if isKnownPredicateAt can + // guarantee that x <= max_int - constant at the given context. + // TODO: Support mul. + if (BinOp == Instruction::Sub) + C = -C; + else if (BinOp != Instruction::Add) + return false; // TODO: Also lift this limitation. if (Signed && C.isNegative()) return false; Index: llvm/test/Transforms/IndVarSimplify/infer-poison-flags.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/infer-poison-flags.ll +++ llvm/test/Transforms/IndVarSimplify/infer-poison-flags.ll @@ -144,7 +144,7 @@ ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[I_NEXT]] = sub nsw i32 [[I]], -1 +; CHECK-NEXT: [[I_NEXT]] = sub nuw nsw i32 [[I]], -1 ; CHECK-NEXT: store i32 [[I]], ptr @A, align 4 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1000 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]