From 23d1d5eb566dbd10a81d9ce2dc67ad1548110b08 Mon Sep 17 00:00:00 2001 From: Nadav Rotem Date: Wed, 22 May 2013 19:28:41 +0000 Subject: [PATCH] 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 --- lib/Target/X86/X86ISelLowering.cpp | 28 +++++++++++++++------- test/CodeGen/X86/chain_order.ll | 38 ++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 test/CodeGen/X86/chain_order.ll diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 769f90172ba..bdb7ea6869c 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -5109,15 +5109,27 @@ static SDValue EltsFromConsecutiveLoads(EVT VT, SmallVectorImpl &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 00000000000..056fd2741fa --- /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 +} + -- 2.34.1