From 0cceec520c6295c98b87e1b47799107a7e57e50f Mon Sep 17 00:00:00 2001 From: Richard Osborne Date: Thu, 16 Jul 2009 12:50:48 +0000 Subject: [PATCH] Combine an unaligned store of unaligned load into a memmove. llvm-svn: 75908 --- llvm/lib/Target/XCore/XCoreISelLowering.cpp | 52 +++++++++++++++++++ llvm/lib/Target/XCore/XCoreISelLowering.h | 2 + .../CodeGen/XCore/unaligned_store_combine.ll | 12 +++++ 3 files changed, 66 insertions(+) create mode 100644 llvm/test/CodeGen/XCore/unaligned_store_combine.ll diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.cpp b/llvm/lib/Target/XCore/XCoreISelLowering.cpp index 0f503bc7a644..113bfbf8dbec 100644 --- a/llvm/lib/Target/XCore/XCoreISelLowering.cpp +++ b/llvm/lib/Target/XCore/XCoreISelLowering.cpp @@ -153,6 +153,9 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) maxStoresPerMemset = 4; maxStoresPerMemmove = maxStoresPerMemcpy = 2; + + // We have target-specific dag combine patterns for the following nodes: + setTargetDAGCombine(ISD::STORE); } SDValue XCoreTargetLowering:: @@ -1049,6 +1052,55 @@ XCoreTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, return BB; } +//===----------------------------------------------------------------------===// +// Target Optimization Hooks +//===----------------------------------------------------------------------===// + +SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, + DAGCombinerInfo &DCI) const { + SelectionDAG &DAG = DCI.DAG; + DebugLoc dl = N->getDebugLoc(); + switch (N->getOpcode()) { + default: break; + case ISD::STORE: { + // Replace unaligned store of unaligned load with memmove. + StoreSDNode *ST = cast(N); + if (!DCI.isBeforeLegalize() || allowsUnalignedMemoryAccesses() || + ST->isVolatile() || ST->isIndexed()) { + break; + } + SDValue Chain = ST->getChain(); + + unsigned StoreBits = ST->getMemoryVT().getStoreSizeInBits(); + if (StoreBits % 8) { + break; + } + unsigned ABIAlignment = getTargetData()-> + getABITypeAlignment(ST->getMemoryVT().getTypeForMVT(*DAG.getContext())); + unsigned Alignment = ST->getAlignment(); + if (Alignment >= ABIAlignment) { + break; + } + + if (LoadSDNode *LD = dyn_cast(ST->getValue())) { + if (LD->hasNUsesOfValue(1, 0) && ST->getMemoryVT() == LD->getMemoryVT() && + LD->getAlignment() == Alignment && + !LD->isVolatile() && !LD->isIndexed() && + Chain.reachesChainWithoutSideEffects(SDValue(LD, 1))) { + return DAG.getMemmove(Chain, dl, ST->getBasePtr(), + LD->getBasePtr(), + DAG.getConstant(StoreBits/8, MVT::i32), + Alignment, ST->getSrcValue(), + ST->getSrcValueOffset(), LD->getSrcValue(), + LD->getSrcValueOffset()); + } + } + break; + } + } + return SDValue(); +} + //===----------------------------------------------------------------------===// // Addressing mode description hooks //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.h b/llvm/lib/Target/XCore/XCoreISelLowering.h index e7a48a97265c..4b244660ccfb 100644 --- a/llvm/lib/Target/XCore/XCoreISelLowering.h +++ b/llvm/lib/Target/XCore/XCoreISelLowering.h @@ -122,6 +122,8 @@ namespace llvm { // Expand specifics SDValue ExpandADDSUB(SDNode *Op, SelectionDAG &DAG); + + virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; }; } diff --git a/llvm/test/CodeGen/XCore/unaligned_store_combine.ll b/llvm/test/CodeGen/XCore/unaligned_store_combine.ll new file mode 100644 index 000000000000..b61cf86988a0 --- /dev/null +++ b/llvm/test/CodeGen/XCore/unaligned_store_combine.ll @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | llc -march=xcore > %t1.s +; RUN: grep "bl memmove" %t1.s | count 1 +; RUN: grep "ldc r., 8" %t1.s | count 1 + +; Unaligned load / store pair. Should be combined into a memmove +; of size 8 +define void @f(i64* %dst, i64* %src) nounwind { +entry: + %0 = load i64* %src, align 1 + store i64 %0, i64* %dst, align 1 + ret void +}