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

Evan Cheng evan.cheng at apple.com
Wed Apr 21 14:31:09 PDT 2010


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.

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