[llvm] r222605 - InstCombine: Preserve nsw/nuw for ((X << C2)*C1) -> (X * (C1 << C2))

David Majnemer david.majnemer at gmail.com
Fri Nov 21 20:52:52 PST 2014


Author: majnemer
Date: Fri Nov 21 22:52:52 2014
New Revision: 222605

URL: http://llvm.org/viewvc/llvm-project?rev=222605&view=rev
Log:
InstCombine: Preserve nsw/nuw for ((X << C2)*C1) -> (X * (C1 << C2))

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
    llvm/trunk/test/Transforms/InstCombine/mul.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=222605&r1=222604&r2=222605&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Fri Nov 21 22:52:52 2014
@@ -151,9 +151,18 @@ Instruction *InstCombiner::visitMul(Bina
     const APInt *IVal;
     if (match(&I, m_Mul(m_Shl(m_Value(NewOp), m_Constant(C2)),
                         m_Constant(C1))) &&
-        match(C1, m_APInt(IVal)))
-      // ((X << C1)*C2) == (X * (C2 << C1))
-      return BinaryOperator::CreateMul(NewOp, ConstantExpr::getShl(C1, C2));
+        match(C1, m_APInt(IVal))) {
+      // ((X << C2)*C1) == (X * (C1 << C2))
+      Constant *Shl = ConstantExpr::getShl(C1, C2);
+      BinaryOperator *Mul = cast<BinaryOperator>(I.getOperand(0));
+      BinaryOperator *BO = BinaryOperator::CreateMul(NewOp, Shl);
+      if (I.hasNoUnsignedWrap() && Mul->hasNoUnsignedWrap())
+        BO->setHasNoUnsignedWrap();
+      if (I.hasNoSignedWrap() && Mul->hasNoSignedWrap() &&
+          Shl->isNotMinSignedValue())
+        BO->setHasNoSignedWrap();
+      return BO;
+    }
 
     if (match(&I, m_Mul(m_Value(NewOp), m_Constant(C1)))) {
       Constant *NewCst = nullptr;

Modified: llvm/trunk/test/Transforms/InstCombine/mul.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/mul.ll?rev=222605&r1=222604&r2=222605&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/mul.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/mul.ll Fri Nov 21 22:52:52 2014
@@ -204,3 +204,19 @@ define i32 @test22(i32 %A) {
         ret i32 %B
 ; CHECK: sub nsw i32 0, %A
 }
+
+define i32 @test23(i32 %A) {
+; CHECK-LABEL: @test23(
+        %B = shl nuw i32 %A, 1
+        %C = mul nuw i32 %B, 3
+        ret i32 %C
+; CHECK: mul nuw i32 %A, 6
+}
+
+define i32 @test24(i32 %A) {
+; CHECK-LABEL: @test24(
+        %B = shl nsw i32 %A, 1
+        %C = mul nsw i32 %B, 3
+        ret i32 %C
+; CHECK: mul nsw i32 %A, 6
+}





More information about the llvm-commits mailing list