[llvm-commits] [llvm] r101808 - in /llvm/trunk/lib: CodeGen/SelectionDAG/DAGCombiner.cpp Target/X86/X86ISelLowering.cpp

Eli Friedman eli.friedman at gmail.com
Mon Apr 19 13:55:23 PDT 2010


On Mon, Apr 19, 2010 at 12:29 PM, Evan Cheng <evan.cheng at apple.com> wrote:
> Author: evancheng
> Date: Mon Apr 19 14:29:22 2010
> New Revision: 101808
>
> URL: http://llvm.org/viewvc/llvm-project?rev=101808&view=rev
> Log:
> More progress on promoting i16 operations to i32 for x86. Work in progress.

Is it really correct to try and promote a rotate?  Won't that change the result?

-Eli

> Modified:
>    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=101808&r1=101807&r2=101808&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Apr 19 14:29:22 2010
> @@ -130,6 +130,8 @@
>     bool CombineToPostIndexedLoadStore(SDNode *N);
>
>     SDValue PromoteIntBinOp(SDValue Op);
> +    SDValue PromoteExtend(SDValue Op);
> +    bool PromoteLoad(SDValue Op);
>
>     /// combine - call the node-specific routine that knows how to fold each
>     /// particular type of node. If that doesn't do anything, try the
> @@ -167,6 +169,8 @@
>     SDValue visitSHL(SDNode *N);
>     SDValue visitSRA(SDNode *N);
>     SDValue visitSRL(SDNode *N);
> +    SDValue visitROTL(SDNode *N);
> +    SDValue visitROTR(SDNode *N);
>     SDValue visitCTLZ(SDNode *N);
>     SDValue visitCTTZ(SDNode *N);
>     SDValue visitCTPOP(SDNode *N);
> @@ -633,25 +637,44 @@
>   return true;
>  }
>
> +static SDValue SExtPromoteOperand(SDValue Op, EVT PVT, SelectionDAG &DAG,
> +                                  const TargetLowering &TLI);
> +static SDValue ZExtPromoteOperand(SDValue Op, EVT PVT, SelectionDAG &DAG,
> +                                  const TargetLowering &TLI);
> +
>  static SDValue PromoteOperand(SDValue Op, EVT PVT, SelectionDAG &DAG,
>                               const TargetLowering &TLI) {
> +  DebugLoc dl = Op.getDebugLoc();
>   if (LoadSDNode *LD = dyn_cast<LoadSDNode>(Op)) {
> -    return DAG.getExtLoad(ISD::EXTLOAD, Op.getDebugLoc(), PVT,
> +    ISD::LoadExtType ExtType =
> +      ISD::isNON_EXTLoad(LD) ? ISD::EXTLOAD : LD->getExtensionType();
> +    return DAG.getExtLoad(ExtType, dl, PVT,
>                           LD->getChain(), LD->getBasePtr(),
>                           LD->getSrcValue(), LD->getSrcValueOffset(),
>                           LD->getMemoryVT(), LD->isVolatile(),
>                           LD->isNonTemporal(), LD->getAlignment());
>   }
>
> -  unsigned Opc = ISD::ANY_EXTEND;
> -  if (Op.getOpcode() == ISD::Constant)
> +  unsigned Opc = Op.getOpcode();
> +  if (Opc == ISD::AssertSext)
> +    return DAG.getNode(ISD::AssertSext, dl, PVT,
> +                       SExtPromoteOperand(Op.getOperand(0), PVT, DAG, TLI),
> +                       Op.getOperand(1));
> +  else if (Opc == ISD::AssertZext)
> +    return DAG.getNode(ISD::AssertZext, dl, PVT,
> +                       ZExtPromoteOperand(Op.getOperand(0), PVT, DAG, TLI),
> +                       Op.getOperand(1));
> +
> +  unsigned ExtOpc = ISD::ANY_EXTEND;
> +  if (Opc == ISD::Constant)
>     // Zero extend things like i1, sign extend everything else.  It shouldn't
>     // matter in theory which one we pick, but this tends to give better code?
>     // See DAGTypeLegalizer::PromoteIntRes_Constant.
> -    Opc = Op.getValueType().isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
> -  if (!TLI.isOperationLegal(Opc, PVT))
> +    ExtOpc =
> +      Op.getValueType().isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
> +  if (!TLI.isOperationLegal(ExtOpc, PVT))
>     return SDValue();
> -  return DAG.getNode(Opc, Op.getDebugLoc(), PVT, Op);
> +  return DAG.getNode(ExtOpc, dl, PVT, Op);
>  }
>
>  static SDValue SExtPromoteOperand(SDValue Op, EVT PVT, SelectionDAG &DAG,
> @@ -727,6 +750,80 @@
>   return SDValue();
>  }
>
> +SDValue DAGCombiner::PromoteExtend(SDValue Op) {
> +  if (!LegalOperations)
> +    return SDValue();
> +
> +  EVT VT = Op.getValueType();
> +  if (VT.isVector() || !VT.isInteger())
> +    return SDValue();
> +
> +  // If operation type is 'undesirable', e.g. i16 on x86, consider
> +  // promoting it.
> +  unsigned Opc = Op.getOpcode();
> +  if (TLI.isTypeDesirableForOp(Opc, VT))
> +    return SDValue();
> +
> +  EVT PVT = VT;
> +  // Consult target whether it is a good idea to promote this operation and
> +  // what's the right type to promote it to.
> +  if (TLI.IsDesirableToPromoteOp(Op, PVT)) {
> +    assert(PVT != VT && "Don't know what type to promote to!");
> +    // fold (aext (aext x)) -> (aext x)
> +    // fold (aext (zext x)) -> (zext x)
> +    // fold (aext (sext x)) -> (sext x)
> +    return DAG.getNode(Op.getOpcode(), Op.getDebugLoc(), VT, Op.getOperand(0));
> +  }
> +  return SDValue();
> +}
> +
> +bool DAGCombiner::PromoteLoad(SDValue Op) {
> +  if (!LegalOperations)
> +    return false;
> +
> +  EVT VT = Op.getValueType();
> +  if (VT.isVector() || !VT.isInteger())
> +    return false;
> +
> +  // If operation type is 'undesirable', e.g. i16 on x86, consider
> +  // promoting it.
> +  unsigned Opc = Op.getOpcode();
> +  if (TLI.isTypeDesirableForOp(Opc, VT))
> +    return false;
> +
> +  EVT PVT = VT;
> +  // Consult target whether it is a good idea to promote this operation and
> +  // what's the right type to promote it to.
> +  if (TLI.IsDesirableToPromoteOp(Op, PVT)) {
> +    assert(PVT != VT && "Don't know what type to promote to!");
> +
> +    DebugLoc dl = Op.getDebugLoc();
> +    SDNode *N = Op.getNode();
> +    LoadSDNode *LD = cast<LoadSDNode>(N);
> +    ISD::LoadExtType ExtType =
> +      ISD::isNON_EXTLoad(LD) ? ISD::EXTLOAD : LD->getExtensionType();
> +    SDValue NewLD = DAG.getExtLoad(ExtType, dl, PVT,
> +                                   LD->getChain(), LD->getBasePtr(),
> +                                   LD->getSrcValue(), LD->getSrcValueOffset(),
> +                                   LD->getMemoryVT(), LD->isVolatile(),
> +                                   LD->isNonTemporal(), LD->getAlignment());
> +    SDValue Result = DAG.getNode(ISD::TRUNCATE, dl, VT, NewLD);
> +
> +    DEBUG(dbgs() << "\nReplacing.x ";
> +          N->dump(&DAG);
> +          dbgs() << "\nWith: ";
> +          Result.getNode()->dump(&DAG);
> +          dbgs() << '\n');
> +    WorkListRemover DeadNodes(*this);
> +    DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Result, &DeadNodes);
> +    DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), NewLD.getValue(1), &DeadNodes);
> +    removeFromWorkList(N);
> +    DAG.DeleteNode(N);
> +    return true;
> +  }
> +  return false;
> +}
> +
>
>  //===----------------------------------------------------------------------===//
>  //  Main DAG Combiner implementation
> @@ -856,6 +953,8 @@
>   case ISD::SHL:                return visitSHL(N);
>   case ISD::SRA:                return visitSRA(N);
>   case ISD::SRL:                return visitSRL(N);
> +  case ISD::ROTL:               return visitROTL(N);
> +  case ISD::ROTR:               return visitROTR(N);
>   case ISD::CTLZ:               return visitCTLZ(N);
>   case ISD::CTTZ:               return visitCTTZ(N);
>   case ISD::CTPOP:              return visitCTPOP(N);
> @@ -2975,6 +3074,14 @@
>   return PromoteIntBinOp(SDValue(N, 0));
>  }
>
> +SDValue DAGCombiner::visitROTL(SDNode *N) {
> +  return PromoteIntBinOp(SDValue(N, 0));
> +}
> +
> +SDValue DAGCombiner::visitROTR(SDNode *N) {
> +  return PromoteIntBinOp(SDValue(N, 0));
> +}
> +
>  SDValue DAGCombiner::visitCTLZ(SDNode *N) {
>   SDValue N0 = N->getOperand(0);
>   EVT VT = N->getValueType(0);
> @@ -3369,7 +3476,7 @@
>       DAG.SignBitIsZero(N0))
>     return DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), VT, N0);
>
> -  return SDValue();
> +  return PromoteExtend(SDValue(N, 0));
>  }
>
>  SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
> @@ -3532,7 +3639,7 @@
>                                    N0.getOperand(1)));
>   }
>
> -  return SDValue();
> +  return PromoteExtend(SDValue(N, 0));
>  }
>
>  SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
> @@ -3668,7 +3775,7 @@
>       return SCC;
>   }
>
> -  return SDValue();
> +  return PromoteExtend(SDValue(N, 0));
>  }
>
>  /// GetDemandedBits - See if the specified operand can be simplified with the
> @@ -5270,6 +5377,8 @@
>   if (CombineToPreIndexedLoadStore(N) || CombineToPostIndexedLoadStore(N))
>     return SDValue(N, 0);
>
> +  if (PromoteLoad(SDValue(N, 0)))
> +    return SDValue(N, 0);
>   return SDValue();
>  }
>
>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=101808&r1=101807&r2=101808&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Apr 19 14:29:22 2010
> @@ -9966,9 +9966,15 @@
>   switch (Opc) {
>   default:
>     return true;
> +  case ISD::LOAD:
> +  case ISD::SIGN_EXTEND:
> +  case ISD::ZERO_EXTEND:
> +  case ISD::ANY_EXTEND:
>   case ISD::SHL:
>   case ISD::SRA:
>   case ISD::SRL:
> +  case ISD::ROTL:
> +  case ISD::ROTR:
>   case ISD::SUB:
>   case ISD::ADD:
>   case ISD::MUL:
> @@ -9990,27 +9996,47 @@
>   if (VT != MVT::i16)
>     return false;
>
> -  bool Commute = true;
> +  bool Promote = false;
> +  bool Commute = false;
>   switch (Op.getOpcode()) {
> -  default: return false;
> +  default: break;
> +  case ISD::LOAD: {
> +    LoadSDNode *LD = cast<LoadSDNode>(Op);
> +    // If the non-extending load has a single use and it's not live out, then it
> +    // might be folded.
> +    if (LD->getExtensionType() == ISD::NON_EXTLOAD &&
> +        Op.hasOneUse() &&
> +        Op.getNode()->use_begin()->getOpcode() != ISD::CopyToReg)
> +      return false;
> +    Promote = true;
> +    break;
> +  }
> +  case ISD::SIGN_EXTEND:
> +  case ISD::ZERO_EXTEND:
> +  case ISD::ANY_EXTEND:
> +    Promote = true;
> +    break;
>   case ISD::SHL:
>   case ISD::SRA:
> -  case ISD::SRL: {
> +  case ISD::SRL:
> +  case ISD::ROTL:
> +  case ISD::ROTR: {
>     SDValue N0 = Op.getOperand(0);
>     // Look out for (store (shl (load), x)).
>     if (isa<LoadSDNode>(N0) && N0.hasOneUse() &&
>         Op.hasOneUse() && Op.getNode()->use_begin()->getOpcode() == ISD::STORE)
>       return false;
> +    Promote = true;
>     break;
>   }
> -  case ISD::SUB:
> -    Commute = false;
> -    // fallthrough
>   case ISD::ADD:
>   case ISD::MUL:
>   case ISD::AND:
>   case ISD::OR:
> -  case ISD::XOR: {
> +  case ISD::XOR:
> +    Commute = true;
> +    // fallthrough
> +  case ISD::SUB: {
>     SDValue N0 = Op.getOperand(0);
>     SDValue N1 = Op.getOperand(1);
>     if (!Commute && isa<LoadSDNode>(N1))
> @@ -10020,11 +10046,12 @@
>       return false;
>     if ((isa<LoadSDNode>(N1) && N1.hasOneUse()) && !isa<ConstantSDNode>(N0))
>       return false;
> +    Promote = true;
>   }
>   }
>
>   PVT = MVT::i32;
> -  return true;
> +  return Promote;
>  }
>
>  //===----------------------------------------------------------------------===//
>
>
> _______________________________________________
> 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