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

Evan Cheng evan.cheng at apple.com
Mon Apr 19 12:29:22 PDT 2010


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.

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;
 }
 
 //===----------------------------------------------------------------------===//





More information about the llvm-commits mailing list