[llvm] r222613 - InstCombine: Propagate NSW/NUW for X*(1<<Y) -> X<<Y

David Majnemer david.majnemer at gmail.com
Sat Nov 22 00:57:02 PST 2014


Author: majnemer
Date: Sat Nov 22 02:57:02 2014
New Revision: 222613

URL: http://llvm.org/viewvc/llvm-project?rev=222613&view=rev
Log:
InstCombine: Propagate NSW/NUW for X*(1<<Y) -> X<<Y

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=222613&r1=222612&r2=222613&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Sat Nov 22 02:57:02 2014
@@ -295,10 +295,23 @@ Instruction *InstCombiner::visitMul(Bina
   // (1 << Y)*X --> X << Y
   {
     Value *Y;
-    if (match(Op0, m_Shl(m_One(), m_Value(Y))))
-      return BinaryOperator::CreateShl(Op1, Y);
-    if (match(Op1, m_Shl(m_One(), m_Value(Y))))
-      return BinaryOperator::CreateShl(Op0, Y);
+    BinaryOperator *BO = nullptr;
+    bool ShlNSW = false;
+    if (match(Op0, m_Shl(m_One(), m_Value(Y)))) {
+      BO = BinaryOperator::CreateShl(Op1, Y);
+      ShlNSW = cast<BinaryOperator>(Op0)->hasNoSignedWrap();
+    }
+    if (match(Op1, m_Shl(m_One(), m_Value(Y)))) {
+      BO = BinaryOperator::CreateShl(Op0, Y);
+      ShlNSW = cast<BinaryOperator>(Op1)->hasNoSignedWrap();
+    }
+    if (BO) {
+      if (I.hasNoUnsignedWrap())
+        BO->setHasNoUnsignedWrap();
+      if (I.hasNoSignedWrap() && ShlNSW)
+        BO->setHasNoSignedWrap();
+      return BO;
+    }
   }
 
   // If one of the operands of the multiply is a cast from a boolean value, then

Modified: llvm/trunk/test/Transforms/InstCombine/mul.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/mul.ll?rev=222613&r1=222612&r2=222613&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/mul.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/mul.ll Sat Nov 22 02:57:02 2014
@@ -229,3 +229,19 @@ define i32 @test25(i32 %A, i32 %B) {
         ret i32 %E
 ; CHECK: mul nsw i32 %A, %B
 }
+
+define i32 @test26(i32 %A, i32 %B) {
+; CHECK-LABEL: @test26(
+        %C = shl nsw i32 1, %B
+        %D = mul nsw i32 %A, %C
+        ret i32 %D
+; CHECK: shl nsw i32 %A, %B
+}
+
+define i32 @test27(i32 %A, i32 %B) {
+; CHECK-LABEL: @test27(
+        %C = shl i32 1, %B
+        %D = mul nuw i32 %A, %C
+        ret i32 %D
+; CHECK: shl nuw i32 %A, %B
+}





More information about the llvm-commits mailing list