[GVN] Intersect the IR flags when CSE'ing two instructions
authorDavid Majnemer <david.majnemer@gmail.com>
Wed, 24 Jun 2015 21:52:25 +0000 (21:52 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Wed, 24 Jun 2015 21:52:25 +0000 (21:52 +0000)
We performed a simple, but incomplete, intersection when it came time to
CSE instructions.  It didn't handle, for example, the 'exact' flag.

This fixes PR23922.

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

lib/Transforms/Scalar/GVN.cpp
test/Transforms/GVN/pr12979.ll

index 6aee033b5dc5ed10739ac302b81c9c318713565f..e93833c32f4445c48a58ceccab753f702874f0db 100644 (file)
@@ -1783,13 +1783,9 @@ static void patchReplacementInstruction(Instruction *I, Value *Repl) {
   // being replaced.
   BinaryOperator *Op = dyn_cast<BinaryOperator>(I);
   BinaryOperator *ReplOp = dyn_cast<BinaryOperator>(Repl);
-  if (Op && ReplOp && isa<OverflowingBinaryOperator>(Op) &&
-      isa<OverflowingBinaryOperator>(ReplOp)) {
-    if (ReplOp->hasNoSignedWrap() && !Op->hasNoSignedWrap())
-      ReplOp->setHasNoSignedWrap(false);
-    if (ReplOp->hasNoUnsignedWrap() && !Op->hasNoUnsignedWrap())
-      ReplOp->setHasNoUnsignedWrap(false);
-  }
+  if (Op && ReplOp)
+    ReplOp->andIRFlags(Op);
+
   if (Instruction *ReplInst = dyn_cast<Instruction>(Repl)) {
     // FIXME: If both the original and replacement value are part of the
     // same control-flow region (meaning that the execution of one
index 0198a56513ea907851fae71ce99a91c8c968f1a8..919c22de02acc47f99e1ef65dfb967163597003d 100644 (file)
@@ -77,3 +77,17 @@ define i32 @test7(i32 %x, i32 %y) {
   %foo = add i32 %add1, %add2
   ret i32 %foo
 }
+
+declare void @mumble(i2, i2)
+
+define void @test8(i2 %x) {
+; CHECK-LABEL: @test8(
+; CHECK:      %[[ashr:.*]] = ashr i2 %x, 1
+; CHECK-NEXT: call void @mumble(i2 %[[ashr]], i2 %[[ashr]])
+; CHECK-NEXT: ret void
+
+  %ashr0 = ashr exact i2 %x, 1
+  %ashr1 = ashr i2 %x, 1
+  call void @mumble(i2 %ashr0, i2 %ashr1)
+  ret void
+}