[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