diff options
author | Bill Schmidt <wschmidt@linux.vnet.ibm.com> | 2014-05-27 15:57:51 +0000 |
---|---|---|
committer | Bill Schmidt <wschmidt@linux.vnet.ibm.com> | 2014-05-27 15:57:51 +0000 |
commit | 71dddd51d928945d5ceb7e84322f2fe8244054d2 (patch) | |
tree | f9f6ca3db859efd130d529071979c3b48e5ec1ef | |
parent | 74bae981a521a292930ec1b074ed1ae1546a7f60 (diff) | |
download | bcm5719-llvm-71dddd51d928945d5ceb7e84322f2fe8244054d2.tar.gz bcm5719-llvm-71dddd51d928945d5ceb7e84322f2fe8244054d2.zip |
[PATCH] Correct type used for VADD_SPLAT optimization on PowerPC
In PPCISelLowering.cpp: PPCTargetLowering::LowerBUILD_VECTOR(), there
is an optimization for certain patterns to generate one or two vector
splats followed by a vector add or subtract. This operation is
represented by a VADD_SPLAT in the selection DAG. Prior to this
patch, it was possible for the VADD_SPLAT to be assigned the wrong
data type, causing incorrect code generation. This patch corrects the
problem.
Specifically, the code previously assigned the value type of the
BUILD_VECTOR node to the newly generated VADD_SPLAT node. This is
correct much of the time, but not always. The problem is that the
call to isConstantSplat() may return a SplatBitSize that is not the
same as the number of bits in the original element vector type. The
correct type to assign is a vector type with the same element bit size
as SplatBitSize.
The included test case shows an example of this, where the
BUILD_VECTOR node has a type of v16i8. The vector to be built is {0,
16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16}. isConstantSplat
detects that we can generate a splat of 16 for type v8i16, which is
the type we must assign to the VADD_SPLAT node. If we do not, we
generate a vspltisb of 8 and a vaddubm, which generates the incorrect
result {16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16}. The correct code generation is a vspltish of 8 and a vadduhm.
This patch also corrected code generation for
CodeGen/PowerPC/2008-07-10-SplatMiscompile.ll, which had been marked
as an XFAIL, so we can remove the XFAIL from the test case.
llvm-svn: 209662
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 12 | ||||
-rw-r--r-- | llvm/test/CodeGen/PowerPC/2008-07-10-SplatMiscompile.ll | 1 | ||||
-rw-r--r-- | llvm/test/CodeGen/PowerPC/splat-bug.ll | 18 |
3 files changed, 26 insertions, 5 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 214c8692060..cf4c9e61a58 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -5531,10 +5531,14 @@ SDValue PPCTargetLowering::LowerBUILD_VECTOR(SDValue Op, // we convert to a pseudo that will be expanded later into one of // the above forms. SDValue Elt = DAG.getConstant(SextVal, MVT::i32); - EVT VT = Op.getValueType(); - int Size = VT == MVT::v16i8 ? 1 : (VT == MVT::v8i16 ? 2 : 4); - SDValue EltSize = DAG.getConstant(Size, MVT::i32); - return DAG.getNode(PPCISD::VADD_SPLAT, dl, VT, Elt, EltSize); + EVT VT = (SplatSize == 1 ? MVT::v16i8 : + (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32)); + SDValue EltSize = DAG.getConstant(SplatSize, MVT::i32); + SDValue RetVal = DAG.getNode(PPCISD::VADD_SPLAT, dl, VT, Elt, EltSize); + if (VT == Op.getValueType()) + return RetVal; + else + return DAG.getNode(ISD::BITCAST, dl, Op.getValueType(), RetVal); } // If this is 0x8000_0000 x 4, turn into vspltisw + vslw. If it is diff --git a/llvm/test/CodeGen/PowerPC/2008-07-10-SplatMiscompile.ll b/llvm/test/CodeGen/PowerPC/2008-07-10-SplatMiscompile.ll index 00a402e0e48..8802b97d2a6 100644 --- a/llvm/test/CodeGen/PowerPC/2008-07-10-SplatMiscompile.ll +++ b/llvm/test/CodeGen/PowerPC/2008-07-10-SplatMiscompile.ll @@ -1,6 +1,5 @@ ; RUN: llc < %s -march=ppc32 -mcpu=g5 | grep vadduhm ; RUN: llc < %s -march=ppc32 -mcpu=g5 | grep vsubuhm -; XFAIL: * define <4 x i32> @test() nounwind { ret <4 x i32> < i32 4293066722, i32 4293066722, i32 4293066722, i32 4293066722> diff --git a/llvm/test/CodeGen/PowerPC/splat-bug.ll b/llvm/test/CodeGen/PowerPC/splat-bug.ll new file mode 100644 index 00000000000..4b5250b259f --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/splat-bug.ll @@ -0,0 +1,18 @@ +; RUN: llc -mcpu=ppc64 -O0 -fast-isel=false < %s | FileCheck %s + +; Checks for a previous bug where vspltisb/vaddubm were issued in place +; of vsplitsh/vadduhm. + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +@a = external global <16 x i8> + +define void @foo() nounwind ssp { +; CHECK: foo: + store <16 x i8> <i8 0, i8 16, i8 0, i8 16, i8 0, i8 16, i8 0, i8 16, i8 0, i8 16, i8 0, i8 16, i8 0, i8 16, i8 0, i8 16>, <16 x i8>* @a +; CHECK: vspltish [[REG:[0-9]+]], 8 +; CHECK: vadduhm {{[0-9]+}}, [[REG]], [[REG]] + ret void +} + |