[llvm] r212167 - InstCombine: Optimize x/INT_MIN to x==INT_MIN

David Majnemer david.majnemer at gmail.com
Tue Jul 1 23:42:14 PDT 2014


Author: majnemer
Date: Wed Jul  2 01:42:13 2014
New Revision: 212167

URL: http://llvm.org/viewvc/llvm-project?rev=212167&view=rev
Log:
InstCombine: Optimize x/INT_MIN to x==INT_MIN

The result of x/INT_MIN is either 0 or 1, we can just use an icmp
instead.

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

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=212167&r1=212166&r2=212167&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Wed Jul  2 01:42:13 2014
@@ -993,6 +993,10 @@ Instruction *InstCombiner::visitSDiv(Bin
   }
 
   if (Constant *RHS = dyn_cast<Constant>(Op1)) {
+    // X/INT_MIN -> X == INT_MIN
+    if (RHS->isMinSignedValue())
+      return new ZExtInst(Builder->CreateICmpEQ(Op0, Op1), I.getType());
+
     // -X/C  -->  X/-C  provided the negation doesn't overflow.
     if (SubOperator *Sub = dyn_cast<SubOperator>(Op0))
       if (match(Sub->getOperand(0), m_Zero()) && Sub->hasNoSignedWrap())

Modified: llvm/trunk/test/Transforms/InstCombine/sub.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sub.ll?rev=212167&r1=212166&r2=212167&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/sub.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/sub.ll Wed Jul  2 01:42:13 2014
@@ -450,9 +450,9 @@ define <2 x i32> @test37(<2 x i32> %A) {
   %sub = sub nsw <2 x i32> zeroinitializer, %div
   ret <2 x i32> %sub
 ; CHECK-LABEL: @test37(
-; CHECK-NEXT: [[DIV:%.*]] = sdiv <2 x i32> %A, <i32 -2147483648, i32 -2147483648>
-; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, %div
-; CHECK-NEXT: ret <2 x i32> [[SUB]]
+; CHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> %A, <i32 -2147483648, i32 -2147483648>
+; CHECK-NEXT: [[SEXT:%.*]] = sext <2 x i1> [[ICMP]] to <2 x i32>
+; CHECK-NEXT: ret <2 x i32> [[SEXT]]
 }
 
 define i32 @test38(i32 %A) {
@@ -460,7 +460,7 @@ define i32 @test38(i32 %A) {
   %sub = sub nsw i32 0, %div
   ret i32 %sub
 ; CHECK-LABEL: @test38(
-; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 %A, -2147483648
-; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[DIV]]
-; CHECK-NEXT: ret i32 [[SUB]]
+; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 %A, -2147483648
+; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[ICMP]] to i32
+; CHECK-NEXT: ret i32 [[SEXT]]
 }





More information about the llvm-commits mailing list