aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Paulsson <paulsson@linux.vnet.ibm.com>2018-11-12 08:12:20 +0000
committerJonas Paulsson <paulsson@linux.vnet.ibm.com>2018-11-12 08:12:20 +0000
commitc0ee028dc341ca586d2bf362f0c3b70b39e41c63 (patch)
tree853c357c331ef78ca43e232e32e9e19b3ffc9eeb
parent5014540a63afb4993dbff6c21e9cdf00ed4f9e36 (diff)
downloadllvm-c0ee028dc341ca586d2bf362f0c3b70b39e41c63.zip
llvm-c0ee028dc341ca586d2bf362f0c3b70b39e41c63.tar.gz
llvm-c0ee028dc341ca586d2bf362f0c3b70b39e41c63.tar.bz2
[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 llvm-svn: 346637
-rw-r--r--llvm/lib/Target/SystemZ/SystemZISelLowering.cpp19
-rw-r--r--llvm/test/CodeGen/SystemZ/vec-move-20.ll19
2 files changed, 30 insertions, 8 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 71b7af2..2aff585 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -4490,18 +4490,21 @@ static SDValue buildVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT,
// 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;
diff --git a/llvm/test/CodeGen/SystemZ/vec-move-20.ll b/llvm/test/CodeGen/SystemZ/vec-move-20.ll
new file mode 100644
index 0000000..ebf1b7db
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/vec-move-20.ll
@@ -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
+}