[llvm] r346637 - [SystemZ] Replicate the load with most uses in buildVector()

Jonas Paulsson via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 12 00:12:20 PST 2018


Author: jonpa
Date: Mon Nov 12 00:12:20 2018
New Revision: 346637

URL: http://llvm.org/viewvc/llvm-project?rev=346637&view=rev
Log:
[SystemZ] Replicate the load with most uses in buildVector()

Iterate over all elements and count the number of uses among them for each
used load. Then make sure to REPLICATE the load which has the most uses in
order to minimize the number of needed element insertions.

Review: Ulrich Weigand
https://reviews.llvm.org/D54322

Added:
    llvm/trunk/test/CodeGen/SystemZ/vec-move-20.ll
Modified:
    llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp

Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp?rev=346637&r1=346636&r2=346637&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp Mon Nov 12 00:12:20 2018
@@ -4490,18 +4490,21 @@ static SDValue buildVector(SelectionDAG
     // avoid a false dependency on any previous contents of the vector
     // register.
 
-    // Use a VLREP if at least one element is a load.
-    unsigned LoadElIdx = UINT_MAX;
+    // Use a VLREP if at least one element is a load. Make sure to replicate
+    // the load with the most elements having its value.
+    std::map<const SDNode*, unsigned> UseCounts;
+    SDNode *LoadMaxUses = nullptr;
     for (unsigned I = 0; I < NumElements; ++I)
       if (Elems[I].getOpcode() == ISD::LOAD &&
           cast<LoadSDNode>(Elems[I])->isUnindexed()) {
-        LoadElIdx = I;
-        break;
+        SDNode *Ld = Elems[I].getNode();
+        UseCounts[Ld]++;
+        if (LoadMaxUses == nullptr || UseCounts[LoadMaxUses] < UseCounts[Ld])
+          LoadMaxUses = Ld;
       }
-    if (LoadElIdx != UINT_MAX) {
-      Result = DAG.getNode(SystemZISD::REPLICATE, DL, VT, Elems[LoadElIdx]);
-      Done[LoadElIdx] = true;
-      ReplicatedVal = Elems[LoadElIdx];
+    if (LoadMaxUses != nullptr) {
+      ReplicatedVal = SDValue(LoadMaxUses, 0);
+      Result = DAG.getNode(SystemZISD::REPLICATE, DL, VT, ReplicatedVal);
     } else {
       // Try to use VLVGP.
       unsigned I1 = NumElements / 2 - 1;

Added: llvm/trunk/test/CodeGen/SystemZ/vec-move-20.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/vec-move-20.ll?rev=346637&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/vec-move-20.ll (added)
+++ llvm/trunk/test/CodeGen/SystemZ/vec-move-20.ll Mon Nov 12 00:12:20 2018
@@ -0,0 +1,19 @@
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
+
+; Test a vector which is built with elements from two loads replicates the
+; load with most elements having its value.
+
+; CHECK:      vlef
+; CHECK-NOT:  vlvgf
+
+define void @update(i32* %src1, i32* %src2, <4 x i32>* %dst) {
+bb:
+  %tmp = load i32, i32* %src1
+  %tmp1 = load i32, i32* %src2
+  %tmp2 = insertelement <4 x i32> undef, i32 %tmp, i32 0
+  %tmp3 = insertelement <4 x i32> %tmp2, i32 %tmp1, i32 1
+  %tmp4 = insertelement <4 x i32> %tmp3, i32 %tmp1, i32 2
+  %tmp5 = insertelement <4 x i32> %tmp4, i32 %tmp1, i32 3
+  store <4 x i32> %tmp5, <4 x i32>* %dst
+  ret void
+}




More information about the llvm-commits mailing list