Index: llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -64,7 +64,7 @@ STATISTIC(NumSRems, "Number of srem converted to urem"); STATISTIC(NumOverflows, "Number of overflow checks removed"); -static cl::opt DontProcessAdds("cvp-dont-process-adds", cl::init(true)); +static cl::opt DontAddNoWrapFlags("cvp-dont-add-nowrap-flags", cl::init(true)); namespace { @@ -607,53 +607,53 @@ return true; } -static bool processAdd(BinaryOperator *AddOp, LazyValueInfo *LVI) { +static bool processBinOp(BinaryOperator *BinOp, LazyValueInfo *LVI) { using OBO = OverflowingBinaryOperator; - if (DontProcessAdds) + if (DontAddNoWrapFlags) return false; - if (AddOp->getType()->isVectorTy()) + if (BinOp->getType()->isVectorTy()) return false; - bool NSW = AddOp->hasNoSignedWrap(); - bool NUW = AddOp->hasNoUnsignedWrap(); + bool NSW = BinOp->hasNoSignedWrap(); + bool NUW = BinOp->hasNoUnsignedWrap(); if (NSW && NUW) return false; - BasicBlock *BB = AddOp->getParent(); + BasicBlock *BB = BinOp->getParent(); - Value *LHS = AddOp->getOperand(0); - Value *RHS = AddOp->getOperand(1); + Value *LHS = BinOp->getOperand(0); + Value *RHS = BinOp->getOperand(1); - ConstantRange LRange = LVI->getConstantRange(LHS, BB, AddOp); + ConstantRange RRange = LVI->getConstantRange(RHS, BB, BinOp); - // Initialize RRange only if we need it. If we know that guaranteed no wrap - // range for the given LHS range is empty don't spend time calculating the - // range for the RHS. - Optional RRange; - auto LazyRRange = [&] () { - if (!RRange) - RRange = LVI->getConstantRange(RHS, BB, AddOp); - return RRange.getValue(); + // Initialize LRange only if we need it. If we know that guaranteed no wrap + // range for the given RHS range is empty don't spend time calculating the + // range for the LHS. + Optional LRange; + auto LazyLRange = [&] () { + if (!LRange) + LRange = LVI->getConstantRange(LHS, BB, BinOp); + return LRange.getValue(); }; bool Changed = false; if (!NUW) { ConstantRange NUWRange = ConstantRange::makeGuaranteedNoWrapRegion( - BinaryOperator::Add, LRange, OBO::NoUnsignedWrap); + BinOp->getOpcode(), RRange, OBO::NoUnsignedWrap); if (!NUWRange.isEmptySet()) { - bool NewNUW = NUWRange.contains(LazyRRange()); - AddOp->setHasNoUnsignedWrap(NewNUW); + bool NewNUW = NUWRange.contains(LazyLRange()); + BinOp->setHasNoUnsignedWrap(NewNUW); Changed |= NewNUW; } } if (!NSW) { ConstantRange NSWRange = ConstantRange::makeGuaranteedNoWrapRegion( - BinaryOperator::Add, LRange, OBO::NoSignedWrap); + BinOp->getOpcode(), RRange, OBO::NoSignedWrap); if (!NSWRange.isEmptySet()) { - bool NewNSW = NSWRange.contains(LazyRRange()); - AddOp->setHasNoSignedWrap(NewNSW); + bool NewNSW = NSWRange.contains(LazyLRange()); + BinOp->setHasNoSignedWrap(NewNSW); Changed |= NewNSW; } } @@ -729,7 +729,8 @@ BBChanged |= processAShr(cast(II), LVI); break; case Instruction::Add: - BBChanged |= processAdd(cast(II), LVI); + case Instruction::Sub: + BBChanged |= processBinOp(cast(II), LVI); break; } } Index: llvm/trunk/test/Transforms/CorrelatedValuePropagation/add.ll =================================================================== --- llvm/trunk/test/Transforms/CorrelatedValuePropagation/add.ll +++ llvm/trunk/test/Transforms/CorrelatedValuePropagation/add.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -correlated-propagation -cvp-dont-process-adds=false -S | FileCheck %s +; RUN: opt < %s -correlated-propagation -cvp-dont-add-nowrap-flags=false -S | FileCheck %s ; CHECK-LABEL: @test0( define void @test0(i32 %a) { Index: llvm/trunk/test/Transforms/CorrelatedValuePropagation/sub.ll =================================================================== --- llvm/trunk/test/Transforms/CorrelatedValuePropagation/sub.ll +++ llvm/trunk/test/Transforms/CorrelatedValuePropagation/sub.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -correlated-propagation -cvp-dont-process-adds=false -S | FileCheck %s +; RUN: opt < %s -correlated-propagation -cvp-dont-add-nowrap-flags=false -S | FileCheck %s define void @test0(i32 %a) { ; CHECK-LABEL: @test0( @@ -7,7 +7,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 100 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], 1 +; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[A]], 1 ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -30,7 +30,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 100 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], 1 +; CHECK-NEXT: [[SUB:%.*]] = sub nuw i32 [[A]], 1 ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -76,7 +76,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -1 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], 1 +; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[A]], 1 ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -99,7 +99,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 2147483647 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], 1 +; CHECK-NEXT: [[SUB:%.*]] = sub nuw i32 [[A]], 1 ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -163,7 +163,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = and i1 [[CMP_1]], [[FLAG:%.*]] ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], 1 +; CHECK-NEXT: [[SUB:%.*]] = sub nuw i32 [[A]], 1 ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -191,7 +191,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = and i1 [[CMP_1]], [[CMP_2]] ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], 1 +; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[A]], 1 ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -250,7 +250,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = and i1 [[CMP_1]], [[CMP_3]] ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], 1 +; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[A]], 1 ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -279,7 +279,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = and i1 [[CMP_1]], [[FLAG:%.*]] ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], 1 +; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[A]], 1 ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -307,7 +307,7 @@ ; CHECK-NEXT: [[WITHIN:%.*]] = and i1 [[WITHIN_1]], [[WITHIN_2]] ; CHECK-NEXT: br i1 [[WITHIN]], label [[THEN:%.*]], label [[ELSE:%.*]] ; CHECK: then: -; CHECK-NEXT: [[I_MINUS_6:%.*]] = sub i32 [[I]], 6 +; CHECK-NEXT: [[I_MINUS_6:%.*]] = sub nuw nsw i32 [[I]], 6 ; CHECK-NEXT: ret i32 [[I_MINUS_6]] ; CHECK: else: ; CHECK-NEXT: ret i32 0 @@ -336,7 +336,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = or i1 [[CMP_1]], [[FLAG:%.*]] ; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], 1 +; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[A]], 1 ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -364,7 +364,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = or i1 [[CMP_1]], [[CMP_2]] ; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], 1 +; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[A]], 1 ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -423,7 +423,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = or i1 [[CMP_1]], [[CMP_3]] ; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], 1 +; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[A]], 1 ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -452,7 +452,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = or i1 [[CMP_1]], [[FLAG:%.*]] ; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], 1 +; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[A]], 1 ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -483,7 +483,7 @@ ; CHECK-NEXT: [[X:%.*]] = load atomic i32, i32* [[A:%.*]] unordered, align 8 ; CHECK-NEXT: fence acquire ; CHECK-NEXT: [[ACC_CURR]] = sub i32 [[ACC]], [[X]] -; CHECK-NEXT: [[IV_NEXT]] = sub i32 [[IV]], -1 +; CHECK-NEXT: [[IV_NEXT]] = sub nsw i32 [[IV]], -1 ; CHECK-NEXT: [[NVAL:%.*]] = load atomic i32, i32* [[N:%.*]] unordered, align 8 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_NEXT]], [[NVAL]] ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]] @@ -514,7 +514,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 100 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 1, [[A]] +; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 1, [[A]] ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -537,7 +537,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 10000 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 -2, [[A]] +; CHECK-NEXT: [[SUB:%.*]] = sub nuw i32 -2, [[A]] ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -560,7 +560,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 100 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 -1, [[A]] +; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 -1, [[A]] ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void