mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
[AArch64][SVE] Fix bug in lowering of fixed-length integer vector divides
The function AArch64TargetLowering::LowerFixedLengthVectorIntDivideToSVE previously assumed the operands were full vectors, but this is not always true. This function would produce bogus if the division operands are not full vectors, resulting in miscompiles when dividing 8-bit or 16-bit vectors. The fix is to perform an extend + div + truncate for non-full vectors, instead of the usual unpacking and unzipping logic. This is an additive change which reduces the non-full integer vector divisions to a pattern recognised by the existing lowering logic. For future reference, an example of code that would miscompile before this patch is below: 1 int8_t foo(unsigned N, int8_t *a, int8_t *b, int8_t *c) { 2 int8_t result = 0; 3 for (int i = 0; i < N; ++i) { 4 result += (a[i] / b[i]) / c[i]; 5 } 6 return result; 7 } Differential Revision: https://reviews.llvm.org/D100370
This commit is contained in:
parent
982c01a843
commit
0afb9c183a
@ -17222,6 +17222,16 @@ SDValue AArch64TargetLowering::LowerFixedLengthVectorIntDivideToSVE(
|
||||
EVT FixedWidenedVT = HalfVT.widenIntegerVectorElementType(*DAG.getContext());
|
||||
EVT ScalableWidenedVT = getContainerForFixedLengthVector(DAG, FixedWidenedVT);
|
||||
|
||||
// If this is not a full vector, extend, div, and truncate it.
|
||||
EVT WidenedVT = VT.widenIntegerVectorElementType(*DAG.getContext());
|
||||
if (DAG.getTargetLoweringInfo().isTypeLegal(WidenedVT)) {
|
||||
unsigned ExtendOpcode = Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
|
||||
SDValue Op0 = DAG.getNode(ExtendOpcode, dl, WidenedVT, Op.getOperand(0));
|
||||
SDValue Op1 = DAG.getNode(ExtendOpcode, dl, WidenedVT, Op.getOperand(1));
|
||||
SDValue Div = DAG.getNode(Op.getOpcode(), dl, WidenedVT, Op0, Op1);
|
||||
return DAG.getNode(ISD::TRUNCATE, dl, VT, Div);
|
||||
}
|
||||
|
||||
// Convert the operands to scalable vectors.
|
||||
SDValue Op0 = convertToScalableVector(DAG, ContainerVT, Op.getOperand(0));
|
||||
SDValue Op1 = convertToScalableVector(DAG, ContainerVT, Op.getOperand(1));
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user