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

Eli Friedman eli.friedman at gmail.com
Wed Apr 21 15:10:25 PDT 2010


On Wed, Apr 21, 2010 at 2:31 PM, Evan Cheng <evan.cheng at apple.com> wrote:
>
> On Apr 19, 2010, at 1:55 PM, Eli Friedman wrote:
>
>> 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?
>
> It should be possible assuming it's done right. LegalizeType does it.

You can promote a rotate, but you can't promote a rotate to a rotate.

-Eli

> Evan
>>
>> -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