[llvm] r319771 - [DAGCombine] Handle big endian correctly in CombineConsecutiveLoads

Bjorn Pettersson via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 5 06:50:05 PST 2017


Author: bjope
Date: Tue Dec  5 06:50:05 2017
New Revision: 319771

URL: http://llvm.org/viewvc/llvm-project?rev=319771&view=rev
Log:
[DAGCombine] Handle big endian correctly in CombineConsecutiveLoads

Summary:
Found out, at code inspection, that there was a fault in
DAGCombiner::CombineConsecutiveLoads for big-endian targets.

A BUILD_PAIR is always having the least significant bits of
the composite value in element 0. So when we are doing the checks
for consecutive loads, for big endian targets, we should check
if the load to elt 1 is at the lower address and the load
to elt 0 is at the higher address.

Normally this bug only resulted in missed oppurtunities for
doing the load combine. I guess that in some rare situation it
could lead to faulty combines, but I've not seen that happen.

Note that this patch actually will trigger load combine for
some big endian regression tests.
One example is test/CodeGen/PowerPC/anon_aggr.ll where we now get
  t76: i64,ch = load<LD8[FixedStack-9]
instead of
  t37: i32,ch = load<LD4[FixedStack-10]>
  t35: i32,ch = load<LD4[FixedStack-9]>
  t41: i64 = build_pair t37, t35
before legalization. Then the legalization will split the LD8
into two loads, so the end result is the same. That should
verify that the transfomation is correct now.

Reviewers: niravd, hfinkel

Reviewed By: niravd

Subscribers: nemanjai, llvm-commits

Differential Revision: https://reviews.llvm.org/D40444

Added:
    llvm/trunk/test/CodeGen/PowerPC/combine_loads_from_build_pair.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h
    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h?rev=319771&r1=319770&r2=319771&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h Tue Dec  5 06:50:05 2017
@@ -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

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=319771&r1=319770&r2=319771&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Dec  5 06:50:05 2017
@@ -8622,6 +8622,13 @@ SDValue DAGCombiner::CombineConsecutiveL
 
   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();

Added: llvm/trunk/test/CodeGen/PowerPC/combine_loads_from_build_pair.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/combine_loads_from_build_pair.ll?rev=319771&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/combine_loads_from_build_pair.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/combine_loads_from_build_pair.ll Tue Dec  5 06:50:05 2017
@@ -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
+}
+




More information about the llvm-commits mailing list