[llvm-commits] [llvm] r128759 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp test/CodeGen/ARM/fp-arg-shuffle.ll

Eli Friedman eli.friedman at gmail.com
Fri Apr 1 20:46:56 PDT 2011


On Fri, Apr 1, 2011 at 7:40 PM, Cameron Zwarich <zwarich at apple.com> wrote:
> Author: zwarich
> Date: Fri Apr  1 21:40:43 2011
> New Revision: 128759
>
> URL: http://llvm.org/viewvc/llvm-project?rev=128759&view=rev
> Log:
> Do some peephole optimizations to remove pointless VMOVs from Neon to integer
> registers that arise from argument shuffling with the soft float ABI. These
> instructions are particularly slow on Cortex A8. This fixes one half of
> <rdar://problem/8674845>.
>
> Added:
>    llvm/trunk/test/CodeGen/ARM/fp-arg-shuffle.ll
> Modified:
>    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
>
> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=128759&r1=128758&r2=128759&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Apr  1 21:40:43 2011
> @@ -5561,6 +5561,37 @@
>   SDValue InDouble = N->getOperand(0);
>   if (InDouble.getOpcode() == ARMISD::VMOVDRR)
>     return DCI.CombineTo(N, InDouble.getOperand(0), InDouble.getOperand(1));
> +
> +  // vmovrrd(load f64) -> (load i32), (load i32)
> +  SDNode *InNode = InDouble.getNode();
> +  if (ISD::isNormalLoad(InNode) && InNode->hasOneUse() &&
> +      InNode->getValueType(0) == MVT::f64 &&
> +      InNode->getOperand(1).getOpcode() == ISD::FrameIndex &&
> +      !cast<LoadSDNode>(InNode)->isVolatile()) {
> +    // TODO: Should this be done for non-FrameIndex operands?
> +    LoadSDNode *LD = cast<LoadSDNode>(InNode);
> +
> +    SelectionDAG &DAG = DCI.DAG;
> +    DebugLoc DL = LD->getDebugLoc();
> +    SDValue BasePtr = LD->getBasePtr();
> +    SDValue NewLD1 = DAG.getLoad(MVT::i32, DL, LD->getChain(), BasePtr,
> +                                 LD->getPointerInfo(), LD->isVolatile(),
> +                                 LD->isNonTemporal(), LD->getAlignment());
> +
> +    SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
> +                                    DAG.getConstant(4, MVT::i32));
> +    SDValue NewLD2 = DAG.getLoad(MVT::i32, DL, NewLD1.getValue(1), OffsetPtr,
> +                                 LD->getPointerInfo(), LD->isVolatile(),
> +                                 LD->isNonTemporal(),
> +                                 std::min(4U, LD->getAlignment() / 2));
> +
> +    DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewLD2.getValue(1));
> +    SDValue Result = DCI.CombineTo(N, NewLD1, NewLD2);
> +    DCI.RemoveFromWorklist(LD);
> +    DAG.DeleteNode(LD);

The reason why RemoveFromWorklist didn't exist is that you don't need
it; unlike in IR, you don't have to erase a dead instruction.  (The
nature of the DAG datastructure is that a node with no uses is
automatically dead.)

-Eli




More information about the llvm-commits mailing list