Chris prefers icmp/select over udiv!
authorNick Lewycky <nicholas@mxc.ca>
Thu, 27 Nov 2008 22:41:10 +0000 (22:41 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Thu, 27 Nov 2008 22:41:10 +0000 (22:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60187 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp
test/Transforms/InstCombine/2008-11-27-UDivNegative.ll [new file with mode: 0644]
test/Transforms/InstCombine/udiv-simplify-bug-1.ll

index 661b0475cc59d25c399596e581766c7bc4360d92..9214b6bbd1156110d61ff415268cb62da1857ea8 100644 (file)
@@ -2882,13 +2882,21 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
   if (Instruction *Common = commonIDivTransforms(I))
     return Common;
 
-  // X udiv C^2 -> X >> C
-  // Check to see if this is an unsigned division with an exact power of 2,
-  // if so, convert to a right shift.
   if (ConstantInt *C = dyn_cast<ConstantInt>(Op1)) {
+    // X udiv C^2 -> X >> C
+    // Check to see if this is an unsigned division with an exact power of 2,
+    // if so, convert to a right shift.
     if (C->getValue().isPowerOf2())  // 0 not included in isPowerOf2
       return BinaryOperator::CreateLShr(Op0, 
                ConstantInt::get(Op0->getType(), C->getValue().logBase2()));
+
+    // X udiv C, where C >= signbit
+    if (C->getValue().isNegative()) {
+      Value *IC = InsertNewInstBefore(new ICmpInst(ICmpInst::ICMP_ULT, Op0, C),
+                                      I);
+      return SelectInst::Create(IC, Constant::getNullValue(I.getType()),
+                                ConstantInt::get(I.getType(), 1));
+    }
   }
 
   // X udiv (C1 << N), where C1 is "1<<C2"  -->  X >> (N+C2)
diff --git a/test/Transforms/InstCombine/2008-11-27-UDivNegative.ll b/test/Transforms/InstCombine/2008-11-27-UDivNegative.ll
new file mode 100644 (file)
index 0000000..6a6b5f3
--- /dev/null
@@ -0,0 +1,6 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep div
+
+define i8 @test(i8 %x) readnone nounwind {
+  %A = udiv i8 %x, 250
+  ret i8 %A
+}
index 6e76bcfd75336458023be694e4860f0654e699a1..0036760ba50ee5abbbd43c274d7e36ae2f1ce903 100644 (file)
@@ -1,16 +1,11 @@
 ; RUN: llvm-as < %s | opt -instcombine | llvm-dis > %t1.ll
-; RUN: grep udiv %t1.ll | count 3
-; RUN: grep zext %t1.ll | count 3
+; RUN: grep udiv %t1.ll | count 2
+; RUN: grep zext %t1.ll | count 2
 ; PR2274
 
 ; The udiv instructions shouldn't be optimized away, and the
 ; sext instructions should be optimized to zext.
 
-define i64 @foo(i32 %x) nounwind {
-  %r = udiv i32 %x, -1
-  %z = sext i32 %r to i64
-  ret i64 %z
-}
 define i64 @bar(i32 %x) nounwind {
   %y = lshr i32 %x, 30
   %r = udiv i32 %y, 3