[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