Turn sdivs into udivs when we can prove the sign bits are clear. This
authorChris Lattner <sabre@nondot.org>
Fri, 7 Oct 2005 06:10:46 +0000 (06:10 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 7 Oct 2005 06:10:46 +0000 (06:10 +0000)
implements CodeGen/PowerPC/div-2.ll

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23659 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp

index 3c5219181bfad4c4c9c3371d5b1c48c6c0c3227f..86ee932eab2650f46d6dd6edde1995c539d7c72f 100644 (file)
@@ -501,6 +501,7 @@ SDOperand DAGCombiner::visitMUL(SDNode *N) {
 SDOperand DAGCombiner::visitSDIV(SDNode *N) {
   SDOperand N0 = N->getOperand(0);
   SDOperand N1 = N->getOperand(1);
+  MVT::ValueType VT = N->getValueType(0);
   ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0.Val);
   ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val);
 
@@ -508,6 +509,15 @@ SDOperand DAGCombiner::visitSDIV(SDNode *N) {
   if (N0C && N1C && !N1C->isNullValue())
     return DAG.getConstant(N0C->getSignExtended() / N1C->getSignExtended(),
                            N->getValueType(0));
+
+  // If we know the sign bits of both operands are zero, strength reduce to a
+  // udiv instead.  Handles (X&15) /s 4 -> X&15 >> 2
+  uint64_t SignBit = 1ULL << (MVT::getSizeInBits(VT)-1);
+  if (MaskedValueIsZero(N1, SignBit, TLI) &&
+      MaskedValueIsZero(N0, SignBit, TLI))
+    return DAG.getNode(ISD::UDIV, N1.getValueType(), N0, N1);
+  
+  
   return SDOperand();
 }
 
index 28215ad59b50b09bc3eee06eb9745d3579c3aa55..12cfe0077f9e86d044084f053f3406c50cc626e0 100644 (file)
@@ -1556,6 +1556,17 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
       return N1;
     }
     break;
+  case ISD::SDIV: {
+    if (CombinerEnabled) break;
+    
+    // If we know the sign bits of both operands are zero, strength reduce to a
+    // udiv instead.  Handles (X&15) /s 4 -> X&15 >> 2
+    uint64_t SignBit = 1ULL << (MVT::getSizeInBits(VT)-1);
+    if (MaskedValueIsZero(N2, SignBit, TLI) &&
+        MaskedValueIsZero(N1, SignBit, TLI))
+      return getNode(ISD::UDIV, VT, N1, N2);
+    break;
+  }   
 
   case ISD::AND:
   case ISD::OR: