Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -2205,19 +2205,32 @@ SignOrUnsignWrap = ScalarEvolution::maskFlags(Flags, SignOrUnsignMask); - if (SignOrUnsignWrap != SignOrUnsignMask && Type == scAddExpr && - Ops.size() == 2 && isa(Ops[0])) { + if (SignOrUnsignWrap != SignOrUnsignMask && + (Type == scAddExpr || Type == scMulExpr) && Ops.size() == 2 && + isa(Ops[0])) { - // (A + C) --> (A + C) if the addition does not sign overflow - // (A + C) --> (A + C) if the addition does not unsign overflow + auto Opcode = [&] { + switch (Type) { + case scAddExpr: + return Instruction::Add; + case scMulExpr: + return Instruction::Mul; + default: + llvm_unreachable("Unexpected SCEV op."); + } + }(); const APInt &C = cast(Ops[0])->getAPInt(); + + // (A C) --> (A C) if the op doesn't sign overflow. if (!(SignOrUnsignWrap & SCEV::FlagNSW)) { auto NSWRegion = ConstantRange::makeGuaranteedNoWrapRegion( - Instruction::Add, C, OBO::NoSignedWrap); + Opcode, C, OBO::NoSignedWrap); if (NSWRegion.contains(SE->getSignedRange(Ops[1]))) Flags = ScalarEvolution::setFlags(Flags, SCEV::FlagNSW); } + + // (A C) --> (A C) if the op doesn't unsign overflow. if (!(SignOrUnsignWrap & SCEV::FlagNUW)) { auto NUWRegion = ConstantRange::makeGuaranteedNoWrapRegion( Instruction::Add, C, OBO::NoUnsignedWrap); Index: llvm/test/Analysis/Delinearization/a.ll =================================================================== --- llvm/test/Analysis/Delinearization/a.ll +++ llvm/test/Analysis/Delinearization/a.ll @@ -10,7 +10,7 @@ ; AddRec: {{{(28 + (4 * (-4 + (3 * %m)) * %o) + %A),+,(8 * %m * %o)}<%for.i>,+,(12 * %o)}<%for.j>,+,20}<%for.k> ; CHECK: Base offset: %A ; CHECK: ArrayDecl[UnknownSize][%m][%o] with elements of 4 bytes. -; CHECK: ArrayRef[{3,+,2}<%for.i>][{-4,+,3}<%for.j>][{7,+,5}<%for.k>] +; CHECK: ArrayRef[{3,+,2}<%for.i>][{-4,+,3}<%for.j>][{7,+,5}<%for.k>] define void @foo(i64 %n, i64 %m, i64 %o, i32* nocapture %A) #0 { entry: Index: llvm/test/Analysis/ScalarEvolution/sext-mul.ll =================================================================== --- llvm/test/Analysis/ScalarEvolution/sext-mul.ll +++ llvm/test/Analysis/ScalarEvolution/sext-mul.ll @@ -1,7 +1,7 @@ ; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s ; CHECK: %tmp9 = shl i64 %tmp8, 33 -; CHECK-NEXT: --> {{.*}} Exits: (-8589934592 + (8589934592 * (zext i32 %arg2 to i64))) +; CHECK-NEXT: --> {{.*}} Exits: (-8589934592 + (8589934592 * (zext i32 %arg2 to i64))) ; CHECK: %tmp10 = ashr exact i64 %tmp9, 32 ; CHECK-NEXT: --> {{.*}} Exits: (sext i32 (-2 + (2 * %arg2)) to i64) ; CHECK: %tmp11 = getelementptr inbounds i32, i32* %arg, i64 %tmp10 @@ -48,9 +48,9 @@ } ; CHECK: %t10 = ashr exact i128 %t9, 1 -; CHECK-NEXT: --> {{.*}} Exits: (sext i127 (-633825300114114700748351602688 + (633825300114114700748351602688 * (zext i32 %arg5 to i127))) to i128) +; CHECK-NEXT: --> {{.*}} Exits: (sext i127 (-633825300114114700748351602688 + (633825300114114700748351602688 * (zext i32 %arg5 to i127))) to i128) ; CHECK: %t14 = or i128 %t10, 1 -; CHECK-NEXT: --> {{.*}} Exits: (1 + (sext i127 (-633825300114114700748351602688 + (633825300114114700748351602688 * (zext i32 %arg5 to i127))) to i128)) +; CHECK-NEXT: --> {{.*}} Exits: (1 + (sext i127 (-633825300114114700748351602688 + (633825300114114700748351602688 * (zext i32 %arg5 to i127))) to i128)) ; CHECK: Loop %bb7: backedge-taken count is (-1 + (zext i32 %arg5 to i128)) ; CHECK-NEXT: Loop %bb7: max backedge-taken count is -1 ; CHECK-NEXT: Loop %bb7: Predicated backedge-taken count is (-1 + (zext i32 %arg5 to i128)) Index: llvm/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll +++ llvm/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll @@ -20,7 +20,7 @@ ; CHECK: add nuw nsw i64 %indvars.iv, 1 ; CHECK: sub nsw i64 %indvars.iv, 2 ; CHECK: sub nsw i64 4, %indvars.iv -; CHECK: mul nsw i64 %indvars.iv, 8 +; CHECK: mul nuw nsw i64 %indvars.iv, 8 for.body170: ; preds = %for.body170, %for.body153 %i2.19 = phi i32 [ %add249, %for.body170 ], [ 0, %for.body153 ]