summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNadav Rotem <nrotem@apple.com>2013-05-22 19:28:41 +0000
committerNadav Rotem <nrotem@apple.com>2013-05-22 19:28:41 +0000
commit23d1d5eb566dbd10a81d9ce2dc67ad1548110b08 (patch)
treeb687c6c0a3b4fb2475edc0af43d596f96452f2ae
parent9e8dbe0d2de41d9f993d07f438f5f967fdfd9974 (diff)
downloadllvm-23d1d5eb566dbd10a81d9ce2dc67ad1548110b08.tar.gz
llvm-23d1d5eb566dbd10a81d9ce2dc67ad1548110b08.tar.bz2
llvm-23d1d5eb566dbd10a81d9ce2dc67ad1548110b08.tar.xz
X86: Fix a bug in EltsFromConsecutiveLoads. We can't generate new loads without chains.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182507 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp28
-rw-r--r--test/CodeGen/X86/chain_order.ll38
2 files changed, 58 insertions, 8 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 769f90172b..bdb7ea6869 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -5109,15 +5109,27 @@ static SDValue EltsFromConsecutiveLoads(EVT VT, SmallVectorImpl<SDValue> &Elts,
// load of the entire vector width starting at the base pointer. If we found
// consecutive loads for the low half, generate a vzext_load node.
if (LastLoadedElt == NumElems - 1) {
+ SDValue NewLd = SDValue();
if (DAG.InferPtrAlignment(LDBase->getBasePtr()) >= 16)
- return DAG.getLoad(VT, DL, LDBase->getChain(), LDBase->getBasePtr(),
- LDBase->getPointerInfo(),
- LDBase->isVolatile(), LDBase->isNonTemporal(),
- LDBase->isInvariant(), 0);
- return DAG.getLoad(VT, DL, LDBase->getChain(), LDBase->getBasePtr(),
- LDBase->getPointerInfo(),
- LDBase->isVolatile(), LDBase->isNonTemporal(),
- LDBase->isInvariant(), LDBase->getAlignment());
+ NewLd = DAG.getLoad(VT, DL, LDBase->getChain(), LDBase->getBasePtr(),
+ LDBase->getPointerInfo(),
+ LDBase->isVolatile(), LDBase->isNonTemporal(),
+ LDBase->isInvariant(), 0);
+ NewLd = DAG.getLoad(VT, DL, LDBase->getChain(), LDBase->getBasePtr(),
+ LDBase->getPointerInfo(),
+ LDBase->isVolatile(), LDBase->isNonTemporal(),
+ LDBase->isInvariant(), LDBase->getAlignment());
+
+ if (LDBase->hasAnyUseOfValue(1)) {
+ SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
+ SDValue(LDBase, 1),
+ SDValue(NewLd.getNode(), 1));
+ DAG.ReplaceAllUsesOfValueWith(SDValue(LDBase, 1), NewChain);
+ DAG.UpdateNodeOperands(NewChain.getNode(), SDValue(LDBase, 1),
+ SDValue(NewLd.getNode(), 1));
+ }
+
+ return NewLd;
}
if (NumElems == 4 && LastLoadedElt == 1 &&
DAG.getTargetLoweringInfo().isTypeLegal(MVT::v2i64)) {
diff --git a/test/CodeGen/X86/chain_order.ll b/test/CodeGen/X86/chain_order.ll
new file mode 100644
index 0000000000..056fd2741f
--- /dev/null
+++ b/test/CodeGen/X86/chain_order.ll
@@ -0,0 +1,38 @@
+; RUN: llc < %s -mcpu=corei7-avx -mtriple=x86_64-linux | FileCheck %s
+
+;CHECK: cftx020
+;CHECK: vmovsd (%rdi), %xmm{{.*}}
+;CHECK: vmovsd 16(%rdi), %xmm{{.*}}
+;CHECK: vmovhpd 8(%rdi), %xmm{{.*}}
+;CHECK: vmovsd 24(%rdi), %xmm{{.*}}
+;CHECK: vmovupd %xmm{{.*}}, (%rdi)
+;CHECK: vmovupd %xmm{{.*}}, 16(%rdi)
+;CHECK: ret
+
+; A test from pifft (after SLP-vectorization) that fails when we drop the chain on newly merged loads.
+define void @cftx020(double* nocapture %a) {
+entry:
+ %0 = load double* %a, align 8
+ %arrayidx1 = getelementptr inbounds double* %a, i64 2
+ %1 = load double* %arrayidx1, align 8
+ %arrayidx2 = getelementptr inbounds double* %a, i64 1
+ %2 = load double* %arrayidx2, align 8
+ %arrayidx3 = getelementptr inbounds double* %a, i64 3
+ %3 = load double* %arrayidx3, align 8
+ %4 = insertelement <2 x double> undef, double %0, i32 0
+ %5 = insertelement <2 x double> %4, double %3, i32 1
+ %6 = insertelement <2 x double> undef, double %1, i32 0
+ %7 = insertelement <2 x double> %6, double %2, i32 1
+ %8 = fadd <2 x double> %5, %7
+ %9 = bitcast double* %a to <2 x double>*
+ store <2 x double> %8, <2 x double>* %9, align 8
+ %10 = insertelement <2 x double> undef, double %0, i32 0
+ %11 = insertelement <2 x double> %10, double %2, i32 1
+ %12 = insertelement <2 x double> undef, double %1, i32 0
+ %13 = insertelement <2 x double> %12, double %3, i32 1
+ %14 = fsub <2 x double> %11, %13
+ %15 = bitcast double* %arrayidx1 to <2 x double>*
+ store <2 x double> %14, <2 x double>* %15, align 8
+ ret void
+}
+