From 9e2fe4648453e9926348e394af0570448d0af083 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Wed, 1 Oct 2014 03:19:43 +0000 Subject: [PATCH] [x86] Teach the new vector shuffle lowering to be even more aggressive in exposing the scalar value to the broadcast DAG fragment so that we can catch even reloads and fold them into the broadcast. This is somewhat magical I'm afraid but seems to work. It is also what the old lowering did, and I've switched an old test to run both lowerings demonstrating that we get the same result. Unlike the old code, I'm not lowering f32 or f64 scalars through this path when we only have AVX1. The target patterns include pretty heinous code to re-cast those as shuffles when the scalar happens to not be spilled because AVX1 provides no broadcast mechanism from registers what-so-ever. This is terribly brittle. I'd much rather go through our generic lowering code to get this. If needed, we can add a peephole to get even more opportunities to broadcast-from-spill-slots that are exposed post-RA, but my suspicion is this just doesn't matter that much. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218734 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 30 ++++++++------------ test/CodeGen/X86/2012-07-15-broadcastfold.ll | 1 + 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 947cd01308b..a87cc804a44 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -7850,28 +7850,22 @@ static SDValue lowerVectorShuffleAsBroadcast(MVT VT, SDLoc DL, SDValue V, "a sorted mask where the broadcast " "comes from V1."); - // Check if this is a broadcast of a scalar load -- those are more widely - // supported than broadcasting in-register values. + // Check if this is a broadcast of a scalar. We special case lowering for + // scalars so that we can more effectively fold with loads. if (V.getOpcode() == ISD::BUILD_VECTOR || (V.getOpcode() == ISD::SCALAR_TO_VECTOR && BroadcastIdx == 0)) { - SDValue BroadcastV = V.getOperand(BroadcastIdx); - if (ISD::isNON_EXTLoad(BroadcastV.getNode())) { - // We can directly broadcast from memory. - return DAG.getNode(X86ISD::VBROADCAST, DL, VT, BroadcastV); - } + V = V.getOperand(BroadcastIdx); + + // If the scalar isn't a load we can't broadcast from it in AVX1, only with + // AVX2. + if (!Subtarget->hasAVX2() && !ISD::isNON_EXTLoad(V.getNode())) + return SDValue(); + } else if (BroadcastIdx != 0 || !Subtarget->hasAVX2()) { + // We can't broadcast from a vector register w/o AVX2, and we can only + // broadcast from the zero-element of a vector register. + return SDValue(); } - // We can't broadcast from a register w/o AVX2. - if (!Subtarget->hasAVX2()) - return SDValue(); - - // Check if this is a broadcast of a BUILD_VECTOR which we can always handle, - // or is a broadcast of the zero element. - if (V.getOpcode() == ISD::BUILD_VECTOR) - V = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VT, V.getOperand(BroadcastIdx)); - else if (BroadcastIdx != 0) - return SDValue(); - return DAG.getNode(X86ISD::VBROADCAST, DL, VT, V); } diff --git a/test/CodeGen/X86/2012-07-15-broadcastfold.ll b/test/CodeGen/X86/2012-07-15-broadcastfold.ll index 1c39c747cdc..519c7cac736 100644 --- a/test/CodeGen/X86/2012-07-15-broadcastfold.ll +++ b/test/CodeGen/X86/2012-07-15-broadcastfold.ll @@ -1,4 +1,5 @@ ; RUN: llc < %s -march=x86 -mcpu=corei7 -mattr=+avx2 | FileCheck %s +; RUN: llc < %s -march=x86 -mcpu=corei7 -mattr=+avx2 -x86-experimental-vector-shuffle-lowering | FileCheck %s declare x86_fastcallcc i64 @barrier()