[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Chris Lattner clattner at apple.com
Mon Jun 25 23:46:29 PDT 2007


<dag combiner part>

Another great change.


> @@ -856,6 +844,10 @@
>    ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
>    ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
>    MVT::ValueType VT = N0.getValueType();
> +
> +  // fold vector ops
> +  SDOperand FoldedVOp = SimplifyVBinOp(N);
> +  if (FoldedVOp.Val) return FoldedVOp;

I'm concerned that this adds a significant amount of control flow for  
non-vector operations.  What do you think of:

   // fold vector ops
   if (MVT::isVector(N->getValueType(VT))) {
     SDOperand FoldedVOp = SimplifyVBinOp(N);
     if (FoldedVOp.Val) return FoldedVOp;
   }

for each of these?

> @@ -1098,6 +1106,11 @@
>    SDOperand RMUL = ReassociateOps(ISD::MUL, N0, N1);
>    if (RMUL.Val != 0)
>      return RMUL;
> +
> +  // If either operand is undef, the result is undef
> +  if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF)
> +    return DAG.getNode(ISD::UNDEF, VT);
> +
>    return SDOperand();
>  }

This isn't safe for multiply.  In particular, undef*X could be well  
defined to be 0 if X is dynamically always zero.  As such, this  
should return Zero.  Note that this should return vector zero (or  
disable the xform) in the vector case.

This xform is safe for add/sub, because there is no defined value  
that (when combined with an undef) can produce a defined result.

> @@ -1162,6 +1179,11 @@
>      SDOperand Op = BuildSDIV(N);
>      if (Op.Val) return Op;
>    }
> +
> +  // If either operand is undef, the result is undef
> +  if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF)
> +    return DAG.getNode(ISD::UNDEF, VT);
> +
>    return SDOperand();
>  }

This is not safe for sdiv/udiv.  Safe xforms are:

   // undef / X -> 0
   // X / undef -> undef

If in doubt, plz check instcombine.

> @@ -1229,6 +1260,10 @@
>      return Sub;
>    }
>
> +  // If either operand is undef, the result is undef
> +  if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF)
> +    return DAG.getNode(ISD::UNDEF, VT);
> +
>    return SDOperand();
>  }

// undef % X -> 0
// X % undef -> undef

for both srem and urem.

> @@ -1283,6 +1323,10 @@
>      return DAG.getNode(ISD::SRA, N0.getValueType(), N0,
>                         DAG.getConstant(MVT::getSizeInBits 
> (N0.getValueType())-1,
>                                         TLI.getShiftAmountTy()));
> +  // If either operand is undef, the result is undef
> +  if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF)
> +    return DAG.getNode(ISD::UNDEF, VT);

mulhs/mulhu seem to be the same as mul, they should produce zero  
instead of undef.

> @@ -1336,6 +1385,10 @@
>      return DAG.getNode(N0.getOpcode(), VT, ORNode, N0.getOperand(1));
>    }
>
> +  // If either operand is undef, the result is undef
> +  if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF)
> +    return DAG.getNode(ISD::UNDEF, VT);


I think this is dead.  The only way to get into this code is if N0- 
 >opcode == N1->opcode.

> @@ -2742,6 +2807,30 @@
>    SDOperand N0 = N->getOperand(0);
>    MVT::ValueType VT = N->getValueType(0);
>
> +  // If the input is a BUILD_VECTOR with all constant elements,  
> fold this now.
> +  // Only do this before legalize, since afterward the target may  
> be depending
> +  // on the bitconvert.

Interesting.  This is a good solution for now, but maybe this argues  
for having a "target build vector", like "target constant", which  
would be unmolested by the optimizer?

> +    MVT::ValueType VT = MVT::getVectorType(DstEltVT,
> +                                           Ops.size());
> +    return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size());

This idiom occurs in several places.  Do you think it makes sense to  
have a helper method on SelectionDAG to do this?

> +SDOperand DAGCombiner::visitCONCAT_VECTORS(SDNode *N) {
> +  // TODO: Check to see if this is a CONCAT_VECTORS of a bunch of
> +  // EXTRACT_SUBVECTOR operations.  If so, and if the  
> EXTRACT_SUBVECTOR vector
> +  // inputs come from at most two distinct vectors, turn this into  
> a shuffle
> +  // node.

Also, if they come from a single vector with the right subvectors, it  
could be a noop :)

> @@ -4177,24 +4121,28 @@
>    return SDOperand();
>  }
>
> +/// SimplifyVBinOp - Visit a binary vector operation, like ADD.
> +SDOperand DAGCombiner::SimplifyVBinOp(SDNode *N) {
> +  // After legalize, the target may be depending on adds and other
> +  // binary ops to provide legal ways to construct constants or other
> +  // things. Simplifying them may result in a loss of legality.
> +  if (AfterLegalize) return SDOperand();

It would be nice if this wasn't required :(


More tomorrow.  Thanks again for tackling this Dan!

-Chris



More information about the llvm-commits mailing list