[llvm-commits] [llvm] r50591 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/udiv-simplify-bug-0.ll test/Transforms/InstCombine/udiv-simplify-bug-1.ll

Dan Gohman gohman at apple.com
Fri May 2 14:30:02 PDT 2008


Author: djg
Date: Fri May  2 16:30:02 2008
New Revision: 50591

URL: http://llvm.org/viewvc/llvm-project?rev=50591&view=rev
Log:
Fix a mistake in the computation of leading zeros for udiv.

Added:
    llvm/trunk/test/Transforms/InstCombine/udiv-simplify-bug-0.ll
    llvm/trunk/test/Transforms/InstCombine/udiv-simplify-bug-1.ll
Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=50591&r1=50590&r2=50591&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri May  2 16:30:02 2008
@@ -1257,7 +1257,7 @@
   case ISD::UDIV: {
     // For the purposes of computing leading zeros we can conservatively
     // treat a udiv as a logical right shift by the power of 2 known to
-    // be greater than the denominator.
+    // be less than the denominator.
     APInt AllOnes = APInt::getAllOnesValue(BitWidth);
     ComputeMaskedBits(Op.getOperand(0),
                       AllOnes, KnownZero2, KnownOne2, Depth+1);
@@ -1267,8 +1267,10 @@
     KnownZero2.clear();
     ComputeMaskedBits(Op.getOperand(1),
                       AllOnes, KnownZero2, KnownOne2, Depth+1);
-    LeadZ = std::min(BitWidth,
-                     LeadZ + BitWidth - KnownOne2.countLeadingZeros());
+    unsigned RHSUnknownLeadingOnes = KnownOne2.countLeadingZeros();
+    if (RHSUnknownLeadingOnes != BitWidth)
+      LeadZ = std::min(BitWidth,
+                       LeadZ + BitWidth - RHSUnknownLeadingOnes - 1);
 
     KnownZero = APInt::getHighBitsSet(BitWidth, LeadZ) & Mask;
     return;

Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=50591&r1=50590&r2=50591&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Fri May  2 16:30:02 2008
@@ -780,7 +780,7 @@
   case Instruction::UDiv: {
     // For the purposes of computing leading zeros we can conservatively
     // treat a udiv as a logical right shift by the power of 2 known to
-    // be greater than the denominator.
+    // be less than the denominator.
     APInt AllOnes = APInt::getAllOnesValue(BitWidth);
     ComputeMaskedBits(I->getOperand(0),
                       AllOnes, KnownZero2, KnownOne2, Depth+1);
@@ -790,8 +790,10 @@
     KnownZero2.clear();
     ComputeMaskedBits(I->getOperand(1),
                       AllOnes, KnownZero2, KnownOne2, Depth+1);
-    LeadZ = std::min(BitWidth,
-                     LeadZ + BitWidth - KnownOne2.countLeadingZeros());
+    unsigned RHSUnknownLeadingOnes = KnownOne2.countLeadingZeros();
+    if (RHSUnknownLeadingOnes != BitWidth)
+      LeadZ = std::min(BitWidth,
+                       LeadZ + BitWidth - RHSUnknownLeadingOnes - 1);
 
     KnownZero = APInt::getHighBitsSet(BitWidth, LeadZ) & Mask;
     return;

Added: llvm/trunk/test/Transforms/InstCombine/udiv-simplify-bug-0.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/udiv-simplify-bug-0.ll?rev=50591&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/udiv-simplify-bug-0.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/udiv-simplify-bug-0.ll Fri May  2 16:30:02 2008
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret i64 0} | count 2
+
+define i64 @foo(i32 %x) nounwind {
+  %y = lshr i32 %x, 1
+  %r = udiv i32 %y, -1
+  %z = sext i32 %r to i64
+  ret i64 %z
+}
+define i64 @bar(i32 %x) nounwind {
+  %y = lshr i32 %x, 31
+  %r = udiv i32 %y, 3
+  %z = sext i32 %r to i64
+  ret i64 %z
+}

Added: llvm/trunk/test/Transforms/InstCombine/udiv-simplify-bug-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/udiv-simplify-bug-1.ll?rev=50591&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/udiv-simplify-bug-1.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/udiv-simplify-bug-1.ll Fri May  2 16:30:02 2008
@@ -0,0 +1,25 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis > %t1.ll
+; RUN: grep udiv %t1.ll | count 3
+; RUN: grep zext %t1.ll | count 3
+; 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
+  %z = sext i32 %r to i64
+  ret i64 %z
+}
+define i64 @qux(i32 %x, i32 %v) nounwind {
+  %y = lshr i32 %x, 31
+  %r = udiv i32 %y, %v
+  %z = sext i32 %r to i64
+  ret i64 %z
+}





More information about the llvm-commits mailing list