mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-26 12:20:42 +00:00
[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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209662 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user