diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/CodeGen/ISDOpcodes.h | 3 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 7 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/combine_loads_from_build_pair.ll | 19 |
3 files changed, 28 insertions, 1 deletions
diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h index 9e4865ff2c2..d256849be9a 100644 --- a/llvm/include/llvm/CodeGen/ISDOpcodes.h +++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h @@ -186,7 +186,8 @@ namespace ISD { /// BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways. /// Given two values of the same integer value type, this produces a value /// twice as big. Like EXTRACT_ELEMENT, this can only be used before - /// legalization. + /// legalization. The lower part of the composite value should be in + /// element 0 and the upper part should be in element 1. BUILD_PAIR, /// MERGE_VALUES - This node takes multiple discrete operands and returns diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 507ae5b5fb7..7f02a643c0a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -8622,6 +8622,13 @@ SDValue DAGCombiner::CombineConsecutiveLoads(SDNode *N, EVT VT) { LoadSDNode *LD1 = dyn_cast<LoadSDNode>(getBuildPairElt(N, 0)); LoadSDNode *LD2 = dyn_cast<LoadSDNode>(getBuildPairElt(N, 1)); + + // A BUILD_PAIR is always having the least significant part in elt 0 and the + // most significant part in elt 1. So when combining into one large load, we + // need to consider the endianness. + if (DAG.getDataLayout().isBigEndian()) + std::swap(LD1, LD2); + if (!LD1 || !LD2 || !ISD::isNON_EXTLoad(LD1) || !LD1->hasOneUse() || LD1->getAddressSpace() != LD2->getAddressSpace()) return SDValue(); diff --git a/llvm/test/CodeGen/PowerPC/combine_loads_from_build_pair.ll b/llvm/test/CodeGen/PowerPC/combine_loads_from_build_pair.ll new file mode 100644 index 00000000000..df687b67e1d --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/combine_loads_from_build_pair.ll @@ -0,0 +1,19 @@ +; RUN: llc -verify-machineinstrs -O0 -mcpu=g4 -mtriple=powerpc-apple-darwin8 < %s -debug -stop-after=machineverifier 2>&1 | FileCheck %s + +define i64 @func1(i64 %p1, i64 %p2, i64 %p3, i64 %p4, { i64, i8* } %struct) { +; Verify that we get a combine on the build_pair, creating a LD8 load somewhere +; between "Initial selection DAG" and "Optimized lowered selection DAG". +; The target is big-endian, and stack grows towards higher addresses, +; so we expect the LD8 to load from the address used in the original HIBITS +; load. +; CHECK-LABEL: Initial selection DAG: +; CHECK-DAG: [[LOBITS:t[0-9]+]]: i32,ch = load<LD4[FixedStack-2]> +; CHECK-DAG: [[HIBITS:t[0-9]+]]: i32,ch = load<LD4[FixedStack-1]> +; CHECK: Combining: t{{[0-9]+}}: i64 = build_pair [[LOBITS]], [[HIBITS]] +; CHECK-NEXT: into +; CHECK-SAME: load<LD8[FixedStack-1] +; CHECK-LABEL: Optimized lowered selection DAG: + %result = extractvalue {i64, i8* } %struct, 0 + ret i64 %result +} + |

