mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
[SelectionDAG] When scalarizing trunc, don't assert for legal operands.
r212242 introduced a legalizer hook, originally to let AArch64 widen v1i{32,16,8} rather than scalarize, because the legalizer expected, when scalarizing the result of a conversion operation, to already have scalarized the operands. On AArch64, v1i64 is legal, so that commit ensured operations such as v1i32 = trunc v1i64 wouldn't assert. It did that by choosing to widen v1 types whenever possible. However, v1i1 types, for which there's no legal widened type, would still trigger the assert. This commit fixes that, by only scalarizing a trunc's result when the operand has already been scalarized, and introducing an extract_elt otherwise. This is similar to r205625. Fixes PR20777. llvm-svn: 220937
This commit is contained in:
parent
2d821f95ed
commit
38c0bf429c
@ -237,7 +237,23 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) {
|
|||||||
SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(SDNode *N) {
|
SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(SDNode *N) {
|
||||||
// Get the dest type - it doesn't always match the input type, e.g. int_to_fp.
|
// Get the dest type - it doesn't always match the input type, e.g. int_to_fp.
|
||||||
EVT DestVT = N->getValueType(0).getVectorElementType();
|
EVT DestVT = N->getValueType(0).getVectorElementType();
|
||||||
SDValue Op = GetScalarizedVector(N->getOperand(0));
|
SDValue Op = N->getOperand(0);
|
||||||
|
EVT OpVT = Op.getValueType();
|
||||||
|
SDLoc DL(N);
|
||||||
|
// The result needs scalarizing, but it's not a given that the source does.
|
||||||
|
// This is a workaround for targets where it's impossible to scalarize the
|
||||||
|
// result of a conversion, because the source type is legal.
|
||||||
|
// For instance, this happens on AArch64: v1i1 is illegal but v1i{8,16,32}
|
||||||
|
// are widened to v8i8, v4i16, and v2i32, which is legal, because v1i64 is
|
||||||
|
// legal and was not scalarized.
|
||||||
|
// See the similar logic in ScalarizeVecRes_VSETCC
|
||||||
|
if (getTypeAction(OpVT) == TargetLowering::TypeScalarizeVector) {
|
||||||
|
Op = GetScalarizedVector(Op);
|
||||||
|
} else {
|
||||||
|
EVT VT = OpVT.getVectorElementType();
|
||||||
|
Op = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Op,
|
||||||
|
DAG.getConstant(0, TLI.getVectorIdxTy()));
|
||||||
|
}
|
||||||
return DAG.getNode(N->getOpcode(), SDLoc(N), DestVT, Op);
|
return DAG.getNode(N->getOpcode(), SDLoc(N), DestVT, Op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,4 +60,23 @@ define <8 x i8> @test_v1i8_1(<1 x i64> %in0) {
|
|||||||
%1 = shufflevector <1 x i64> %in0, <1 x i64> undef, <8 x i32> <i32 undef, i32 undef, i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
%1 = shufflevector <1 x i64> %in0, <1 x i64> undef, <8 x i32> <i32 undef, i32 undef, i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
||||||
%2 = trunc <8 x i64> %1 to <8 x i8>
|
%2 = trunc <8 x i64> %1 to <8 x i8>
|
||||||
ret <8 x i8> %2
|
ret <8 x i8> %2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; PR20777: v1i1 is also problematic, but we can't widen it, so we extract_elt
|
||||||
|
; the i64 out of the v1i64 operand, and truncate that scalar instead.
|
||||||
|
|
||||||
|
define <1 x i1> @test_v1i1_0(<1 x i64> %in0) {
|
||||||
|
; CHECK-LABEL: test_v1i1_0:
|
||||||
|
; CHECK: fmov w0, s0
|
||||||
|
%1 = trunc <1 x i64> %in0 to <1 x i1>
|
||||||
|
ret <1 x i1> %1
|
||||||
|
}
|
||||||
|
|
||||||
|
define i1 @test_v1i1_1(<1 x i64> %in0) {
|
||||||
|
; CHECK-LABEL: test_v1i1_1:
|
||||||
|
; CHECK: fmov [[REG:w[0-9]+]], s0
|
||||||
|
%1 = trunc <1 x i64> %in0 to <1 x i1>
|
||||||
|
; CHECK: and w0, [[REG]], #0x1
|
||||||
|
%2 = extractelement <1 x i1> %1, i32 0
|
||||||
|
ret i1 %2
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user