[Reassociate] Don't propogate flags when creating negations
authorDavid Majnemer <david.majnemer@gmail.com>
Wed, 24 Jun 2015 21:27:36 +0000 (21:27 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Wed, 24 Jun 2015 21:27:36 +0000 (21:27 +0000)
Reassociate mutated existing instructions in order to form negations
which would create additional reassociate opportunities.

This fixes PR23926.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240593 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/Reassociate.cpp
test/Transforms/Reassociate/basictest.ll
test/Transforms/Reassociate/wrap-flags.ll

index 6c66b58729e9a5d08691f4c42038fc28cf30fd49..d1acf785d07ec7e01003346cde9d878fddfac10f 100644 (file)
@@ -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;
   }
 
index caaf7726514dee35d4f4957d52dd629a8849f9c7..c557017b4c6be36ee5d2d7596046a1dfa272809d 100644 (file)
@@ -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
 }
 
index e3304b6a7bb249f7fa21d45cfd83a4167e2dbe6f..f56719d32c2d47b219ef82b97e655d7c57ef7b92 100644 (file)
@@ -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
+}