Invert the TargetLowering flag that controls divide by consant expansion.
[oota-llvm.git] / lib / CodeGen / SelectionDAG / DAGCombiner.cpp
index 75f1c18a730fa040a8baf33e94fdd98cec0dd0ff..6c1d22c2bab7ec7189d58e7c1ad7de1e759f6154 100644 (file)
@@ -292,7 +292,7 @@ static ms magic64(int64_t d) {
   const uint64_t two63 = 9223372036854775808ULL; // 2^63
   struct ms mag;
   
-  ad = llabs(d);
+  ad = d >= 0 ? d : -d;
   t = two63 + ((uint64_t)d >> 63);
   anc = t - 1 - t%ad;   // absolute value of nc
   p = 63;               // initialize p
@@ -745,8 +745,7 @@ SDOperand DAGCombiner::visitMUL(SDNode *N) {
     return N1;
   // fold (mul x, -1) -> 0-x
   if (N1C && N1C->isAllOnesValue())
-    return DAG.getNode(ISD::SUB, N->getValueType(0), 
-                       DAG.getConstant(0, N->getValueType(0)), N0);
+    return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), N0);
   // fold (mul x, (1 << c)) -> x << c
   if (N1C && isPowerOf2_64(N1C->getValue()))
     return DAG.getNode(ISD::SHL, N->getValueType(0), N0,
@@ -777,20 +776,49 @@ SDOperand DAGCombiner::visitSDIV(SDNode *N) {
   if (N0C && N1C && !N1C->isNullValue())
     return DAG.getConstant(N0C->getSignExtended() / N1C->getSignExtended(),
                            N->getValueType(0));
+  // fold (sdiv X, 1) -> X
+  if (N1C && N1C->getSignExtended() == 1LL)
+    return N0;
+  // fold (sdiv X, -1) -> 0-X
+  if (N1C && N1C->isAllOnesValue())
+    return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), N0);
   // 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);
+  // fold (sdiv X, pow2) -> (add (sra X, log(pow2)), (srl X, sizeof(X)-1))
+  if (N1C && N1C->getValue() && !TLI.isIntDivCheap() && 
+      (isPowerOf2_64(N1C->getSignExtended()) || 
+       isPowerOf2_64(-N1C->getSignExtended()))) {
+    // If dividing by powers of two is cheap, then don't perform the following
+    // fold.
+    if (TLI.isPow2DivCheap())
+      return SDOperand();
+    int64_t pow2 = N1C->getSignExtended();
+    int64_t abs2 = pow2 > 0 ? pow2 : -pow2;
+    SDOperand SRL = DAG.getNode(ISD::SRL, VT, N0,
+                                DAG.getConstant(MVT::getSizeInBits(VT)-1,
+                                                TLI.getShiftAmountTy()));
+    WorkList.push_back(SRL.Val);
+    SDOperand SGN = DAG.getNode(ISD::ADD, VT, N0, SRL);
+    WorkList.push_back(SGN.Val);
+    SDOperand SRA = DAG.getNode(ISD::SRA, VT, SGN, 
+                                DAG.getConstant(Log2_64(abs2),
+                                                TLI.getShiftAmountTy()));
+    // If we're dividing by a positive value, we're done.  Otherwise, we must
+    // negate the result.
+    if (pow2 > 0)
+      return SRA;
+    WorkList.push_back(SRA.Val);
+    return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), SRA);
+  }
   // if integer divide is expensive and we satisfy the requirements, emit an
   // alternate sequence.
-  // FIXME: This currently opts out powers of two, since targets can often be
-  // more clever in those cases.  In an idea world, we would have some way to
-  // detect that too.
-  if (N1C && !isPowerOf2_64(N1C->getSignExtended()) && 
-      (N1C->getSignExtended() < -1 || N1C->getSignExtended() > 1) &&
-      TLI.isOperationLegal(ISD::MULHS, VT) && TLI.isIntDivExpensive()) {
+  if (N1C && (N1C->getSignExtended() < -1 || N1C->getSignExtended() > 1) && 
+      !TLI.isIntDivCheap() &&
+      TLI.isOperationLegal(ISD::MULHS, VT) && TLI.isTypeLegal(VT)) {
     return BuildSDIV(N);
   }
   return SDOperand();
@@ -814,7 +842,7 @@ SDOperand DAGCombiner::visitUDIV(SDNode *N) {
                                        TLI.getShiftAmountTy()));
   // fold (udiv x, c) -> alternate
   if (N1C && N1C->getValue() && TLI.isOperationLegal(ISD::MULHU, VT) &&
-      TLI.isIntDivExpensive())
+      TLI.isTypeLegal(VT) && !TLI.isIntDivCheap())
     return BuildUDIV(N);
   return SDOperand();
 }
@@ -2555,7 +2583,7 @@ SDOperand DAGCombiner::BuildSDIV(SDNode *N) {
   assert((VT == MVT::i32 || VT == MVT::i64) && 
          "BuildSDIV only operates on i32 or i64!");
   
-  int64_t d = cast<ConstantSDNode>(N->getOperand(1))->getValue();
+  int64_t d = cast<ConstantSDNode>(N->getOperand(1))->getSignExtended();
   ms magics = (VT == MVT::i32) ? magic32(d) : magic64(d);
   
   // Multiply the numerator (operand 0) by the magic value