forked from OSchip/llvm-project
[PowerPC] Extend custom lower of vector truncate to handle wider input
Current custom lowering of truncate vector handles a source of up to 128 bits, but that only uses one of the two shuffle vector operands. Extend it to use both operands to handle 256 bit sources. Differential Revision: https://reviews.llvm.org/D68035
This commit is contained in:
parent
1f6c4d829c
commit
b6d7ed469f
|
@ -7862,20 +7862,45 @@ SDValue PPCTargetLowering::LowerTRUNCATEVector(SDValue Op,
|
|||
// <uu, uu, uu, uu, uu, uu, LSB2|MSB2, LSB1|MSB1> to
|
||||
// <u, u, u, u, u, u, u, u, u, u, u, u, u, u, LSB2, LSB1>
|
||||
|
||||
assert(Op.getValueType().isVector() && "Vector type expected.");
|
||||
|
||||
SDLoc DL(Op);
|
||||
SDValue N1 = Op.getOperand(0);
|
||||
unsigned SrcSize = N1.getValueType().getSizeInBits();
|
||||
assert(SrcSize <= 128 && "Source must fit in an Altivec/VSX vector");
|
||||
SDValue WideSrc = SrcSize == 128 ? N1 : widenVec(DAG, N1, DL);
|
||||
|
||||
EVT TrgVT = Op.getValueType();
|
||||
assert(TrgVT.isVector() && "Vector type expected.");
|
||||
unsigned TrgNumElts = TrgVT.getVectorNumElements();
|
||||
EVT EltVT = TrgVT.getVectorElementType();
|
||||
if (!isOperationCustom(Op.getOpcode(), TrgVT) ||
|
||||
TrgVT.getSizeInBits() > 128 || !isPowerOf2_32(TrgNumElts) ||
|
||||
!isPowerOf2_32(EltVT.getSizeInBits()))
|
||||
return SDValue();
|
||||
|
||||
SDValue N1 = Op.getOperand(0);
|
||||
EVT SrcVT = N1.getValueType();
|
||||
unsigned SrcSize = SrcVT.getSizeInBits();
|
||||
if (SrcSize > 256 ||
|
||||
!isPowerOf2_32(SrcVT.getVectorNumElements()) ||
|
||||
!isPowerOf2_32(SrcVT.getVectorElementType().getSizeInBits()))
|
||||
return SDValue();
|
||||
if (SrcSize == 256 && SrcVT.getVectorNumElements() < 2)
|
||||
return SDValue();
|
||||
|
||||
unsigned WideNumElts = 128 / EltVT.getSizeInBits();
|
||||
EVT WideVT = EVT::getVectorVT(*DAG.getContext(), EltVT, WideNumElts);
|
||||
|
||||
SDLoc DL(Op);
|
||||
SDValue Op1, Op2;
|
||||
if (SrcSize == 256) {
|
||||
EVT VecIdxTy = getVectorIdxTy(DAG.getDataLayout());
|
||||
EVT SplitVT =
|
||||
N1.getValueType().getHalfNumVectorElementsVT(*DAG.getContext());
|
||||
unsigned SplitNumElts = SplitVT.getVectorNumElements();
|
||||
Op1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SplitVT, N1,
|
||||
DAG.getConstant(0, DL, VecIdxTy));
|
||||
Op2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SplitVT, N1,
|
||||
DAG.getConstant(SplitNumElts, DL, VecIdxTy));
|
||||
}
|
||||
else {
|
||||
Op1 = SrcSize == 128 ? N1 : widenVec(DAG, N1, DL);
|
||||
Op2 = DAG.getUNDEF(WideVT);
|
||||
}
|
||||
|
||||
// First list the elements we want to keep.
|
||||
unsigned SizeMult = SrcSize / TrgVT.getSizeInBits();
|
||||
SmallVector<int, 16> ShuffV;
|
||||
|
@ -7891,8 +7916,9 @@ SDValue PPCTargetLowering::LowerTRUNCATEVector(SDValue Op,
|
|||
// ShuffV.push_back(i + WideNumElts);
|
||||
ShuffV.push_back(WideNumElts + 1);
|
||||
|
||||
SDValue Conv = DAG.getNode(ISD::BITCAST, DL, WideVT, WideSrc);
|
||||
return DAG.getVectorShuffle(WideVT, DL, Conv, DAG.getUNDEF(WideVT), ShuffV);
|
||||
Op1 = DAG.getNode(ISD::BITCAST, DL, WideVT, Op1);
|
||||
Op2 = DAG.getNode(ISD::BITCAST, DL, WideVT, Op2);
|
||||
return DAG.getVectorShuffle(WideVT, DL, Op1, Op2, ShuffV);
|
||||
}
|
||||
|
||||
/// LowerSELECT_CC - Lower floating point select_cc's into fsel instruction when
|
||||
|
@ -10750,13 +10776,11 @@ void PPCTargetLowering::ReplaceNodeResults(SDNode *N,
|
|||
Results.push_back(LowerFP_TO_INT(SDValue(N, 0), DAG, dl));
|
||||
return;
|
||||
case ISD::TRUNCATE: {
|
||||
EVT TrgVT = N->getValueType(0);
|
||||
EVT OpVT = N->getOperand(0).getValueType();
|
||||
if (TrgVT.isVector() &&
|
||||
isOperationCustom(N->getOpcode(), TrgVT) &&
|
||||
OpVT.getSizeInBits() <= 128 &&
|
||||
isPowerOf2_32(OpVT.getVectorElementType().getSizeInBits()))
|
||||
Results.push_back(LowerTRUNCATEVector(SDValue(N, 0), DAG));
|
||||
if (!N->getValueType(0).isVector())
|
||||
return;
|
||||
SDValue Lowered = LowerTRUNCATEVector(SDValue(N, 0), DAG);
|
||||
if (Lowered)
|
||||
Results.push_back(Lowered);
|
||||
return;
|
||||
}
|
||||
case ISD::BITCAST:
|
||||
|
|
|
@ -0,0 +1,189 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
|
||||
; RUN: -mattr=+vsx -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
|
||||
; RUN: FileCheck %s
|
||||
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
|
||||
; RUN: -mattr=+vsx -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
|
||||
; RUN: FileCheck %s --check-prefix=CHECK-BE
|
||||
|
||||
define dso_local <8 x i8> @test8x32(i32 %i1, i32 %i2, i32 %i3, i32 %i4,
|
||||
i32 %i5, i32 %i6, i32 %i7, i32 %i8) {
|
||||
; CHECK-LABEL: test8x32:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: rldimi r3, r4, 32, 0
|
||||
; CHECK-NEXT: rldimi r5, r6, 32, 0
|
||||
; CHECK-NEXT: addis r11, r2, .LCPI0_0@toc@ha
|
||||
; CHECK-NEXT: rldimi r7, r8, 32, 0
|
||||
; CHECK-NEXT: rldimi r9, r10, 32, 0
|
||||
; CHECK-NEXT: mtfprd f0, r3
|
||||
; CHECK-NEXT: addi r3, r11, .LCPI0_0@toc@l
|
||||
; CHECK-NEXT: mtfprd f1, r5
|
||||
; CHECK-NEXT: lvx v4, 0, r3
|
||||
; CHECK-NEXT: mtfprd f2, r7
|
||||
; CHECK-NEXT: mtfprd f3, r9
|
||||
; CHECK-NEXT: xxmrghd v2, vs1, vs0
|
||||
; CHECK-NEXT: xxmrghd v3, vs3, vs2
|
||||
; CHECK-NEXT: vperm v2, v3, v2, v4
|
||||
; CHECK-NEXT: blr
|
||||
;
|
||||
; CHECK-BE-LABEL: test8x32:
|
||||
; CHECK-BE: # %bb.0:
|
||||
; CHECK-BE-NEXT: stw r10, -80(r1)
|
||||
; CHECK-BE-NEXT: stw r9, -96(r1)
|
||||
; CHECK-BE-NEXT: stw r8, -112(r1)
|
||||
; CHECK-BE-NEXT: stw r7, -128(r1)
|
||||
; CHECK-BE-NEXT: stw r6, -16(r1)
|
||||
; CHECK-BE-NEXT: stw r5, -32(r1)
|
||||
; CHECK-BE-NEXT: stw r4, -48(r1)
|
||||
; CHECK-BE-NEXT: stw r3, -64(r1)
|
||||
; CHECK-BE-NEXT: addi r3, r1, -80
|
||||
; CHECK-BE-NEXT: lxvw4x v2, 0, r3
|
||||
; CHECK-BE-NEXT: addi r3, r1, -96
|
||||
; CHECK-BE-NEXT: lxvw4x v3, 0, r3
|
||||
; CHECK-BE-NEXT: addi r3, r1, -112
|
||||
; CHECK-BE-NEXT: lxvw4x v4, 0, r3
|
||||
; CHECK-BE-NEXT: addi r3, r1, -128
|
||||
; CHECK-BE-NEXT: lxvw4x v5, 0, r3
|
||||
; CHECK-BE-NEXT: addi r3, r1, -16
|
||||
; CHECK-BE-NEXT: lxvw4x v0, 0, r3
|
||||
; CHECK-BE-NEXT: addi r3, r1, -32
|
||||
; CHECK-BE-NEXT: lxvw4x v1, 0, r3
|
||||
; CHECK-BE-NEXT: addi r3, r1, -48
|
||||
; CHECK-BE-NEXT: lxvw4x v6, 0, r3
|
||||
; CHECK-BE-NEXT: addi r3, r1, -64
|
||||
; CHECK-BE-NEXT: lxvw4x v7, 0, r3
|
||||
; CHECK-BE-NEXT: addis r3, r2, .LCPI0_0@toc@ha
|
||||
; CHECK-BE-NEXT: vmrghw v2, v3, v2
|
||||
; CHECK-BE-NEXT: vmrghw v3, v5, v4
|
||||
; CHECK-BE-NEXT: vmrghw v4, v1, v0
|
||||
; CHECK-BE-NEXT: addi r3, r3, .LCPI0_0@toc@l
|
||||
; CHECK-BE-NEXT: xxmrghd v2, v3, v2
|
||||
; CHECK-BE-NEXT: lxvw4x v8, 0, r3
|
||||
; CHECK-BE-NEXT: vmrghw v5, v7, v6
|
||||
; CHECK-BE-NEXT: xxmrghd v3, v5, v4
|
||||
; CHECK-BE-NEXT: vperm v2, v3, v2, v8
|
||||
; CHECK-BE-NEXT: blr
|
||||
%v10 = insertelement <8 x i32> undef, i32 %i1, i32 0
|
||||
%v11 = insertelement <8 x i32> %v10, i32 %i2, i32 1
|
||||
%v12 = insertelement <8 x i32> %v11, i32 %i3, i32 2
|
||||
%v13 = insertelement <8 x i32> %v12, i32 %i4, i32 3
|
||||
%v14 = insertelement <8 x i32> %v13, i32 %i5, i32 4
|
||||
%v15 = insertelement <8 x i32> %v14, i32 %i6, i32 5
|
||||
%v16 = insertelement <8 x i32> %v15, i32 %i7, i32 6
|
||||
%v17 = insertelement <8 x i32> %v16, i32 %i8, i32 7
|
||||
%v2 = trunc <8 x i32> %v17 to <8 x i8>
|
||||
ret <8 x i8> %v2
|
||||
}
|
||||
|
||||
define dso_local <4 x i16> @test4x64(i64 %i1, i64 %i2, i64 %i3, i64 %i4) {
|
||||
; CHECK-LABEL: test4x64:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addis r7, r2, .LCPI1_0@toc@ha
|
||||
; CHECK-NEXT: mtfprd f0, r5
|
||||
; CHECK-NEXT: mtfprd f1, r6
|
||||
; CHECK-NEXT: mtfprd f2, r3
|
||||
; CHECK-NEXT: addi r3, r7, .LCPI1_0@toc@l
|
||||
; CHECK-NEXT: mtfprd f3, r4
|
||||
; CHECK-NEXT: xxmrghd v2, vs1, vs0
|
||||
; CHECK-NEXT: lvx v4, 0, r3
|
||||
; CHECK-NEXT: xxmrghd v3, vs3, vs2
|
||||
; CHECK-NEXT: vperm v2, v2, v3, v4
|
||||
; CHECK-NEXT: blr
|
||||
;
|
||||
; CHECK-BE-LABEL: test4x64:
|
||||
; CHECK-BE: # %bb.0:
|
||||
; CHECK-BE-NEXT: std r6, -8(r1)
|
||||
; CHECK-BE-NEXT: std r5, -16(r1)
|
||||
; CHECK-BE-NEXT: std r4, -24(r1)
|
||||
; CHECK-BE-NEXT: std r3, -32(r1)
|
||||
; CHECK-BE-NEXT: addi r3, r1, -32
|
||||
; CHECK-BE-NEXT: addis r4, r2, .LCPI1_0@toc@ha
|
||||
; CHECK-BE-NEXT: addi r7, r1, -16
|
||||
; CHECK-BE-NEXT: lxvd2x v3, 0, r3
|
||||
; CHECK-BE-NEXT: addi r3, r4, .LCPI1_0@toc@l
|
||||
; CHECK-BE-NEXT: lxvd2x v2, 0, r7
|
||||
; CHECK-BE-NEXT: lxvw4x v4, 0, r3
|
||||
; CHECK-BE-NEXT: vperm v2, v3, v2, v4
|
||||
; CHECK-BE-NEXT: blr
|
||||
%v10 = insertelement <4 x i64> undef, i64 %i1, i32 0
|
||||
%v11 = insertelement <4 x i64> %v10, i64 %i2, i32 1
|
||||
%v12 = insertelement <4 x i64> %v11, i64 %i3, i32 2
|
||||
%v13 = insertelement <4 x i64> %v12, i64 %i4, i32 3
|
||||
%v2 = trunc <4 x i64> %v13 to <4 x i16>
|
||||
ret <4 x i16> %v2
|
||||
}
|
||||
|
||||
define dso_local <8 x i16> @test8x24(i32 %i1, i32 %i2, i32 %i3, i32 %i4,
|
||||
i32 %i5, i32 %i6, i32 %i7, i32 %i8) {
|
||||
; CHECK-LABEL: test8x24:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: mtvsrd v2, r3
|
||||
; CHECK-NEXT: mtvsrd v3, r4
|
||||
; CHECK-NEXT: mtvsrd v4, r5
|
||||
; CHECK-NEXT: mtvsrd v5, r6
|
||||
; CHECK-NEXT: mtvsrd v0, r7
|
||||
; CHECK-NEXT: mtvsrd v1, r8
|
||||
; CHECK-NEXT: vmrghh v2, v3, v2
|
||||
; CHECK-NEXT: mtvsrd v3, r9
|
||||
; CHECK-NEXT: vmrghh v4, v5, v4
|
||||
; CHECK-NEXT: mtvsrd v5, r10
|
||||
; CHECK-NEXT: vmrghh v0, v1, v0
|
||||
; CHECK-NEXT: vmrghh v3, v5, v3
|
||||
; CHECK-NEXT: vmrglw v2, v4, v2
|
||||
; CHECK-NEXT: vmrglw v3, v3, v0
|
||||
; CHECK-NEXT: xxmrgld v2, v3, v2
|
||||
; CHECK-NEXT: blr
|
||||
;
|
||||
; CHECK-BE-LABEL: test8x24:
|
||||
; CHECK-BE: # %bb.0:
|
||||
; CHECK-BE-NEXT: sth r10, -16(r1)
|
||||
; CHECK-BE-NEXT: sth r9, -32(r1)
|
||||
; CHECK-BE-NEXT: sth r8, -48(r1)
|
||||
; CHECK-BE-NEXT: sth r7, -64(r1)
|
||||
; CHECK-BE-NEXT: sth r6, -80(r1)
|
||||
; CHECK-BE-NEXT: sth r5, -96(r1)
|
||||
; CHECK-BE-NEXT: sth r4, -112(r1)
|
||||
; CHECK-BE-NEXT: sth r3, -128(r1)
|
||||
; CHECK-BE-NEXT: addi r3, r1, -16
|
||||
; CHECK-BE-NEXT: lxvw4x v2, 0, r3
|
||||
; CHECK-BE-NEXT: addi r3, r1, -32
|
||||
; CHECK-BE-NEXT: lxvw4x v3, 0, r3
|
||||
; CHECK-BE-NEXT: addi r3, r1, -48
|
||||
; CHECK-BE-NEXT: lxvw4x v4, 0, r3
|
||||
; CHECK-BE-NEXT: addi r3, r1, -64
|
||||
; CHECK-BE-NEXT: lxvw4x v5, 0, r3
|
||||
; CHECK-BE-NEXT: addi r3, r1, -80
|
||||
; CHECK-BE-NEXT: lxvw4x v0, 0, r3
|
||||
; CHECK-BE-NEXT: addi r3, r1, -96
|
||||
; CHECK-BE-NEXT: lxvw4x v1, 0, r3
|
||||
; CHECK-BE-NEXT: addi r3, r1, -112
|
||||
; CHECK-BE-NEXT: lxvw4x v6, 0, r3
|
||||
; CHECK-BE-NEXT: addi r3, r1, -128
|
||||
; CHECK-BE-NEXT: lxvw4x v7, 0, r3
|
||||
; CHECK-BE-NEXT: vmrghh v2, v3, v2
|
||||
; CHECK-BE-NEXT: vmrghh v3, v5, v4
|
||||
; CHECK-BE-NEXT: vmrghh v4, v1, v0
|
||||
; CHECK-BE-NEXT: vmrghw v2, v3, v2
|
||||
; CHECK-BE-NEXT: vmrghh v5, v7, v6
|
||||
; CHECK-BE-NEXT: vmrghw v3, v5, v4
|
||||
; CHECK-BE-NEXT: xxmrghd v2, v3, v2
|
||||
; CHECK-BE-NEXT: blr
|
||||
%i11 = trunc i32 %i1 to i24
|
||||
%i21 = trunc i32 %i2 to i24
|
||||
%i31 = trunc i32 %i3 to i24
|
||||
%i41 = trunc i32 %i4 to i24
|
||||
%i51 = trunc i32 %i5 to i24
|
||||
%i61 = trunc i32 %i6 to i24
|
||||
%i71 = trunc i32 %i7 to i24
|
||||
%i81 = trunc i32 %i8 to i24
|
||||
%v10 = insertelement <8 x i24> undef, i24 %i11, i32 0
|
||||
%v11 = insertelement <8 x i24> %v10, i24 %i21, i32 1
|
||||
%v12 = insertelement <8 x i24> %v11, i24 %i31, i32 2
|
||||
%v13 = insertelement <8 x i24> %v12, i24 %i41, i32 3
|
||||
%v14 = insertelement <8 x i24> %v13, i24 %i51, i32 4
|
||||
%v15 = insertelement <8 x i24> %v14, i24 %i61, i32 5
|
||||
%v16 = insertelement <8 x i24> %v15, i24 %i71, i32 6
|
||||
%v17 = insertelement <8 x i24> %v16, i24 %i81, i32 7
|
||||
%v2 = trunc <8 x i24> %v17 to <8 x i16>
|
||||
ret <8 x i16> %v2
|
||||
}
|
Loading…
Reference in New Issue