diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp index 6c66b58729e9..d1acf785d07e 100644 --- a/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -936,6 +936,10 @@ static Value *NegateValue(Value *V, Instruction *BI) { // Push the negates through the add. I->setOperand(0, NegateValue(I->getOperand(0), BI)); I->setOperand(1, NegateValue(I->getOperand(1), BI)); + if (I->getOpcode() == Instruction::Add) { + I->setHasNoUnsignedWrap(false); + I->setHasNoSignedWrap(false); + } // We must move the add instruction here, because the neg instructions do // not dominate the old add instruction in general. By moving it, we are @@ -976,6 +980,12 @@ static Value *NegateValue(Value *V, Instruction *BI) { InsertPt = TheNeg->getParent()->getParent()->getEntryBlock().begin(); } TheNeg->moveBefore(InsertPt); + if (TheNeg->getOpcode() == Instruction::Sub) { + TheNeg->setHasNoUnsignedWrap(false); + TheNeg->setHasNoSignedWrap(false); + } else { + TheNeg->andIRFlags(BI); + } return TheNeg; } diff --git a/llvm/test/Transforms/Reassociate/basictest.ll b/llvm/test/Transforms/Reassociate/basictest.ll index caaf7726514d..c557017b4c6b 100644 --- a/llvm/test/Transforms/Reassociate/basictest.ll +++ b/llvm/test/Transforms/Reassociate/basictest.ll @@ -169,7 +169,11 @@ define i32 @test11(i32 %W) { ; CHECK-NEXT: ret i32 } +declare void @mumble(i32) + define i32 @test12(i32 %X) { + %X.neg = sub nsw nuw i32 0, %X + call void @mumble(i32 %X.neg) %A = sub i32 1, %X %B = sub i32 2, %X %C = sub i32 3, %X @@ -177,8 +181,8 @@ define i32 @test12(i32 %X) { %Z = add i32 %Y, %C ret i32 %Z ; CHECK-LABEL: @test12 -; CHECK-NEXT: mul i32 %X, -3 -; CHECK-NEXT: add i32{{.*}}, 6 +; CHECK: %[[mul:.*]] = mul i32 %X, -3 +; CHECK-NEXT: add i32 %[[mul]], 6 ; CHECK-NEXT: ret i32 } diff --git a/llvm/test/Transforms/Reassociate/wrap-flags.ll b/llvm/test/Transforms/Reassociate/wrap-flags.ll index e3304b6a7bb2..f56719d32c2d 100644 --- a/llvm/test/Transforms/Reassociate/wrap-flags.ll +++ b/llvm/test/Transforms/Reassociate/wrap-flags.ll @@ -32,3 +32,14 @@ entry: %mul2 = add i32 %mul, 1 ret i32 %mul2 } + +; CHECK-LABEL: @pr23926( +; CHECK: %[[X1_neg:.*]] = sub i2 0, %X1 +; CHECK-NEXT: %[[sub_one:.*]] = add i2 %[[X1_neg]], -1 +; CHECK-NEXT: %[[add:.*]] = add i2 %[[sub_one]], %X2 +; CHECK-NEXT: ret i2 %[[add]] +define i2 @pr23926(i2 %X1, i2 %X2) { + %add = add nuw i2 %X1, 1 + %sub = sub nuw nsw i2 %X2, %add + ret i2 %sub +}