InstCombine: Propagate NSW for -X * -Y -> X * Y
authorDavid Majnemer <david.majnemer@gmail.com>
Sat, 22 Nov 2014 07:25:19 +0000 (07:25 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sat, 22 Nov 2014 07:25:19 +0000 (07:25 +0000)
llvm-svn: 222612

llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
llvm/test/Transforms/InstCombine/mul.ll

index 5ea25bf..78f585f 100644 (file)
@@ -237,9 +237,16 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
     }
   }
 
-  if (Value *Op0v = dyn_castNegVal(Op0))     // -X * -Y = X*Y
-    if (Value *Op1v = dyn_castNegVal(Op1))
-      return BinaryOperator::CreateMul(Op0v, Op1v);
+  if (Value *Op0v = dyn_castNegVal(Op0)) {   // -X * -Y = X*Y
+    if (Value *Op1v = dyn_castNegVal(Op1)) {
+      BinaryOperator *BO = BinaryOperator::CreateMul(Op0v, Op1v);
+      if (I.hasNoSignedWrap() &&
+          match(Op0, m_NSWSub(m_Value(), m_Value())) &&
+          match(Op1, m_NSWSub(m_Value(), m_Value())))
+        BO->setHasNoSignedWrap();
+      return BO;
+    }
+  }
 
   // (X / Y) *  Y = X - (X % Y)
   // (X / Y) * -Y = (X % Y) - X
index 469ca5a..a782cfd 100644 (file)
@@ -220,3 +220,12 @@ define i32 @test24(i32 %A) {
         ret i32 %C
 ; CHECK: mul nsw i32 %A, 6
 }
+
+define i32 @test25(i32 %A, i32 %B) {
+; CHECK-LABEL: @test25(
+        %C = sub nsw i32 0, %A
+        %D = sub nsw i32 0, %B
+        %E = mul nsw i32 %C, %D
+        ret i32 %E
+; CHECK: mul nsw i32 %A, %B
+}