[llvm-commits] [llvm] r122221 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

Duncan Sands baldrick at free.fr
Mon Dec 20 01:13:28 PST 2010


Hi Chris,

> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Sun Dec 19 20:05:39 2010
> @@ -548,6 +548,54 @@
>     return Res;
>   }
>
> +
> +SDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) {
> +  // Promote the overflow bit trivially.
> +  if (ResNo == 1)
> +    return PromoteIntRes_Overflow(N);
> +
> +  SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
> +  DebugLoc DL = N->getDebugLoc();
> +  unsigned SmallSize = LHS.getValueType().getSizeInBits();
> +
> +  // To determine if the result overflowed in a larger type, we extend the input
> +  // to the larger type, do the multiply, then check the high bits of the result
> +  // to see if the overflow happened.
> +  if (N->getOpcode() == ISD::SMULO) {
> +    LHS = SExtPromotedInteger(LHS);
> +    RHS = SExtPromotedInteger(RHS);
> +  } else {
> +    LHS = ZExtPromotedInteger(LHS);
> +    RHS = ZExtPromotedInteger(RHS);
> +  }
> +
> +  SDValue Mul = DAG.getNode(ISD::MUL, DL, LHS.getValueType(), LHS, RHS);
> +
> +
> +  // For an unsigned overflow, we check to see if the high part is != 0;
> +  SDValue Overflow;
> +  if (N->getOpcode() == ISD::UMULO) {
> +    SDValue Hi = DAG.getNode(ISD::SRL, DL, Mul.getValueType(), Mul,
> +                             DAG.getIntPtrConstant(SmallSize));
> +    // Overflowed if and only if this is not equal to Res.

^ Should say "is not equal to zero."

> +    Overflow = DAG.getSetCC(DL, N->getValueType(1), Hi,
> +                            DAG.getConstant(0, Hi.getValueType()), ISD::SETNE);
> +  } else {
> +    // Signed multiply overflowed if the high part is not 0 and not -1.

Actually it overflows iff the high part does not sign extend the low part (just
as in the unsigned case the high part should zero extend the low part), which is
not exactly the same thing.  Eg: a signed i8 multiply of 64 by 2 overflows, but
the high part is zero.  Eg: a signed i8 multiple of -128 by 2 overflows, but the
high part is all ones.

Ciao, Duncan.

> +    SDValue Hi = DAG.getNode(ISD::SRA, DL, Mul.getValueType(), Mul,
> +                             DAG.getIntPtrConstant(SmallSize));
> +    Hi = DAG.getNode(ISD::ADD, DL, Hi.getValueType(), Hi,
> +                     DAG.getConstant(1, Hi.getValueType()));
> +    Overflow = DAG.getSetCC(DL, N->getValueType(1), Hi,
> +                            DAG.getConstant(1, Hi.getValueType()), ISD::SETUGT);
> +  }
> +
> +  // Use the calculated overflow everywhere.
> +  ReplaceValueWith(SDValue(N, 1), Overflow);
> +  return Mul;
> +}
> +
> +
>   SDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) {
>     // Zero extend the input.
>     SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
> @@ -601,11 +649,6 @@
>     return Res;
>   }
>
> -SDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) {
> -  assert(ResNo == 1&&  "Only boolean result promotion currently supported!");
> -  return PromoteIntRes_Overflow(N);
> -}
> -
>   //===----------------------------------------------------------------------===//
>   //  Integer Operand Promotion
>   //===----------------------------------------------------------------------===//
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list