[llvm] r345361 - [PowerPC] Keep vector int to fp conversions in vector domain
Nemanja Ivanovic via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 25 20:19:13 PDT 2018
Author: nemanjai
Date: Thu Oct 25 20:19:13 2018
New Revision: 345361
URL: http://llvm.org/viewvc/llvm-project?rev=345361&view=rev
Log:
[PowerPC] Keep vector int to fp conversions in vector domain
At present a v2i16 -> v2f64 convert is implemented by extracts to scalar,
scalar converts, and merge back into a vector. Use vector converts instead,
with the int data permuted into the proper position and extended if necessary.
Patch by RolandF.
Differential revision: https://reviews.llvm.org/D53346
Added:
llvm/trunk/test/CodeGen/PowerPC/vec-itofp.ll
Modified:
llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h
Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=345361&r1=345360&r2=345361&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Thu Oct 25 20:19:13 2018
@@ -792,6 +792,9 @@ PPCTargetLowering::PPCTargetLowering(con
setOperationAction(ISD::FP_TO_SINT, MVT::v2i64, Legal);
setOperationAction(ISD::FP_TO_UINT, MVT::v2i64, Legal);
+ setOperationAction(ISD::UINT_TO_FP, MVT::v2i16, Custom);
+ setOperationAction(ISD::SINT_TO_FP, MVT::v2i16, Custom);
+
setOperationAction(ISD::FNEG, MVT::v4f32, Legal);
setOperationAction(ISD::FNEG, MVT::v2f64, Legal);
setOperationAction(ISD::FABS, MVT::v4f32, Legal);
@@ -7265,10 +7268,75 @@ SDValue PPCTargetLowering::LowerINT_TO_F
return FP;
}
+static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl) {
+
+ EVT VecVT = Vec.getValueType();
+ assert(VecVT.isVector() && "Expected a vector type.");
+ assert(VecVT.getSizeInBits() < 128 && "Vector is already full width.");
+
+ EVT EltVT = VecVT.getVectorElementType();
+ unsigned WideNumElts = 128 / EltVT.getSizeInBits();
+ EVT WideVT = EVT::getVectorVT(*DAG.getContext(), EltVT, WideNumElts);
+
+ unsigned NumConcat = WideNumElts / VecVT.getVectorNumElements();
+ SmallVector<SDValue, 16> Ops(NumConcat);
+ Ops[0] = Vec;
+ SDValue UndefVec = DAG.getUNDEF(VecVT);
+ for (unsigned i = 1; i < NumConcat; ++i)
+ Ops[i] = UndefVec;
+
+ return DAG.getNode(ISD::CONCAT_VECTORS, dl, WideVT, Ops);
+}
+
+SDValue PPCTargetLowering::LowerINT_TO_FPVector(SDValue Op,
+ SelectionDAG &DAG,
+ const SDLoc &dl) const {
+
+ unsigned Opc = Op.getOpcode();
+ assert((Opc == ISD::UINT_TO_FP || Opc == ISD::SINT_TO_FP) &&
+ "Unexpected conversion type");
+ assert(Op.getValueType() == MVT::v2f64 && "Supports v2f64 only.");
+
+ // CPU's prior to P9 don't have a way to sign-extend in vectors.
+ bool SignedConv = Opc == ISD::SINT_TO_FP;
+ if (SignedConv && !Subtarget.hasP9Altivec())
+ return SDValue();
+
+ SDValue Wide = widenVec(DAG, Op.getOperand(0), dl);
+ EVT WideVT = Wide.getValueType();
+ unsigned WideNumElts = WideVT.getVectorNumElements();
+
+ SmallVector<int, 16> ShuffV;
+ for (unsigned i = 0; i < WideNumElts; ++i)
+ ShuffV.push_back(i + WideNumElts);
+
+ if (Subtarget.isLittleEndian()) {
+ ShuffV[0] = 0;
+ ShuffV[WideNumElts / 2] = 1;
+ }
+ else {
+ ShuffV[WideNumElts / 2 - 1] = 0;
+ ShuffV[WideNumElts - 1] = 1;
+ }
+
+ SDValue ShuffleSrc2 = SignedConv ? DAG.getUNDEF(WideVT) :
+ DAG.getConstant(0, dl, WideVT);
+ SDValue Arrange = DAG.getVectorShuffle(WideVT, dl, Wide, ShuffleSrc2, ShuffV);
+ unsigned ExtendOp = SignedConv ? (unsigned) PPCISD::SExtVElems :
+ (unsigned) ISD::BITCAST;
+ SDValue Extend = DAG.getNode(ExtendOp, dl, MVT::v2i64, Arrange);
+
+ return DAG.getNode(Opc, dl, Op.getValueType(), Extend);
+}
+
SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
SelectionDAG &DAG) const {
SDLoc dl(Op);
+ if (Op.getValueType() == MVT::v2f64 &&
+ Op.getOperand(0).getValueType() == MVT::v2i16)
+ return LowerINT_TO_FPVector(Op, DAG, dl);
+
// Conversions to f128 are legal.
if (EnableQuadPrecision && (Op.getValueType() == MVT::f128))
return Op;
Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h?rev=345361&r1=345360&r2=345361&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h Thu Oct 25 20:19:13 2018
@@ -927,6 +927,9 @@ namespace llvm {
SDValue LowerINT_TO_FPDirectMove(SDValue Op, SelectionDAG &DAG,
const SDLoc &dl) const;
+ SDValue LowerINT_TO_FPVector(SDValue Op, SelectionDAG &DAG,
+ const SDLoc &dl) const;
+
SDValue getFramePointerFrameIndex(SelectionDAG & DAG) const;
SDValue getReturnAddrFrameIndex(SelectionDAG & DAG) const;
Added: llvm/trunk/test/CodeGen/PowerPC/vec-itofp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/vec-itofp.ll?rev=345361&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/vec-itofp.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/vec-itofp.ll Thu Oct 25 20:19:13 2018
@@ -0,0 +1,192 @@
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
+; RUN: -mcpu=pwr8 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
+; RUN: FileCheck %s --check-prefix=CHECK-P8
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
+; RUN: -mcpu=pwr9 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
+; RUN: FileCheck %s --check-prefix=CHECK-P9
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
+; RUN: -mcpu=pwr9 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
+; RUN: FileCheck %s --check-prefix=CHECK-BE
+
+define void @test8(<8 x double>* nocapture %Sink, <8 x i16>* nocapture readonly %SrcPtr) {
+entry:
+ %0 = load <8 x i16>, <8 x i16>* %SrcPtr, align 16
+ %1 = uitofp <8 x i16> %0 to <8 x double>
+ store <8 x double> %1, <8 x double>* %Sink, align 16
+ ret void
+; CHECK-P9-LABEL: @test8
+; CHECK-P9: vperm
+; CHECK-P9: vperm
+; CHECK-P9: vperm
+; CHECK-P9: vperm
+; CHECK-P9: xvcvuxddp
+; CHECK-P9: xvcvuxddp
+; CHECK-P9: xvcvuxddp
+; CHECK-P9: xvcvuxddp
+; CHECK-P8-LABEL: @test8
+; CHECK-P8: vperm
+; CHECK-P8: vperm
+; CHECK-P8: vperm
+; CHECK-P8: vperm
+; CHECK-P8: xvcvuxddp
+; CHECK-P8: xvcvuxddp
+; CHECK-P8: xvcvuxddp
+; CHECK-P8: xvcvuxddp
+}
+
+define void @test4(<4 x double>* nocapture %Sink, <4 x i16>* nocapture readonly %SrcPtr) {
+entry:
+ %0 = load <4 x i16>, <4 x i16>* %SrcPtr, align 16
+ %1 = uitofp <4 x i16> %0 to <4 x double>
+ store <4 x double> %1, <4 x double>* %Sink, align 16
+ ret void
+; CHECK-P9-LABEL: @test4
+; CHECK-P9: vperm
+; CHECK-P9: vperm
+; CHECK-P9: xvcvuxddp
+; CHECK-P9: xvcvuxddp
+; CHECK-P8-LABEL: @test4
+; CHECK-P8: vperm
+; CHECK-P8: vperm
+; CHECK-P8: xvcvuxddp
+; CHECK-P8: xvcvuxddp
+}
+
+define void @test2(<2 x double>* nocapture %Sink, <2 x i16>* nocapture readonly %SrcPtr) {
+entry:
+ %0 = load <2 x i16>, <2 x i16>* %SrcPtr, align 16
+ %1 = uitofp <2 x i16> %0 to <2 x double>
+ store <2 x double> %1, <2 x double>* %Sink, align 16
+ ret void
+; CHECK-P9-LABEL: .LCPI2_0:
+; CHECK-P9-NEXT: .byte 31
+; CHECK-P9-NEXT: .byte 30
+; CHECK-P9-NEXT: .byte 13
+; CHECK-P9-NEXT: .byte 12
+; CHECK-P9-NEXT: .byte 11
+; CHECK-P9-NEXT: .byte 10
+; CHECK-P9-NEXT: .byte 9
+; CHECK-P9-NEXT: .byte 8
+; CHECK-P9-NEXT: .byte 29
+; CHECK-P9-NEXT: .byte 28
+; CHECK-P9-NEXT: .byte 5
+; CHECK-P9-NEXT: .byte 4
+; CHECK-P9-NEXT: .byte 3
+; CHECK-P9-NEXT: .byte 2
+; CHECK-P9-NEXT: .byte 1
+; CHECK-P9-NEXT: .byte 0
+; CHECK-P9: addi [[REG1:r[0-9]+]], {{r[0-9]+}}, .LCPI2_0 at toc@l
+; CHECK-P9: lxvx [[REG2:v[0-9]+]], 0, [[REG1]]
+; CHECK-P9: vperm [[REG3:v[0-9]+]], {{v[0-9]+}}, {{v[0-9]+}}, [[REG2]]
+; CHECK-P9: xvcvuxddp {{vs[0-9]+}}, [[REG3]]
+; CHECK-P8-LABEL: @test2
+; CHECK-P8: vperm [[REG1:v[0-9]+]]
+; CHECK-P8: xvcvuxddp {{vs[0-9]+}}, [[REG1]]
+; CHECK-BE-LABEL: .LCPI2_0:
+; CHECK-BE-NEXT: .byte 16
+; CHECK-BE-NEXT: .byte 17
+; CHECK-BE-NEXT: .byte 18
+; CHECK-BE-NEXT: .byte 19
+; CHECK-BE-NEXT: .byte 20
+; CHECK-BE-NEXT: .byte 21
+; CHECK-BE-NEXT: .byte 0
+; CHECK-BE-NEXT: .byte 1
+; CHECK-BE-NEXT: .byte 24
+; CHECK-BE-NEXT: .byte 25
+; CHECK-BE-NEXT: .byte 26
+; CHECK-BE-NEXT: .byte 27
+; CHECK-BE-NEXT: .byte 28
+; CHECK-BE-NEXT: .byte 29
+; CHECK-BE-NEXT: .byte 2
+; CHECK-BE-NEXT: .byte 3
+; CHECK-BE: addi [[REG1:r[0-9]+]], {{r[0-9]+}}, .LCPI2_0 at toc@l
+; CHECK-BE: lxvx [[REG2:v[0-9]+]], 0, [[REG1]]
+; CHECK-BE: vperm [[REG3:v[0-9]+]], {{v[0-9]+}}, {{v[0-9]+}}, [[REG2]]
+; CHECK-BE: xvcvuxddp {{vs[0-9]+}}, [[REG3]]
+}
+
+define void @stest8(<8 x double>* nocapture %Sink, <8 x i16>* nocapture readonly %SrcPtr) {
+entry:
+ %0 = load <8 x i16>, <8 x i16>* %SrcPtr, align 16
+ %1 = sitofp <8 x i16> %0 to <8 x double>
+ store <8 x double> %1, <8 x double>* %Sink, align 16
+ ret void
+; CHECK-P9-LABEL: @stest8
+; CHECK-P9: vperm
+; CHECK-P9: vperm
+; CHECK-P9: vperm
+; CHECK-P9: vperm
+; CHECK-P9: vextsh2d
+; CHECK-P9: vextsh2d
+; CHECK-P9: vextsh2d
+; CHECK-P9: vextsh2d
+; CHECK-P9: xvcvsxddp
+; CHECK-P9: xvcvsxddp
+; CHECK-P9: xvcvsxddp
+; CHECK-P9: xvcvsxddp
+}
+
+define void @stest4(<4 x double>* nocapture %Sink, <4 x i16>* nocapture readonly %SrcPtr) {
+entry:
+ %0 = load <4 x i16>, <4 x i16>* %SrcPtr, align 16
+ %1 = sitofp <4 x i16> %0 to <4 x double>
+ store <4 x double> %1, <4 x double>* %Sink, align 16
+ ret void
+; CHECK-P9-LABEL: @stest4
+; CHECK-P9: vperm
+; CHECK-P9: vperm
+; CHECK-P9: vextsh2d
+; CHECK-P9: vextsh2d
+; CHECK-P9: xvcvsxddp
+; CHECK-P9: xvcvsxddp
+}
+
+define void @stest2(<2 x double>* nocapture %Sink, <2 x i16>* nocapture readonly %SrcPtr) {
+entry:
+ %0 = load <2 x i16>, <2 x i16>* %SrcPtr, align 16
+ %1 = sitofp <2 x i16> %0 to <2 x double>
+ store <2 x double> %1, <2 x double>* %Sink, align 16
+ ret void
+; CHECK-P9-LABEL: .LCPI5_0:
+; CHECK-P9-NEXT: .byte 31
+; CHECK-P9-NEXT: .byte 30
+; CHECK-P9-NEXT: .byte 31
+; CHECK-P9-NEXT: .byte 31
+; CHECK-P9-NEXT: .byte 31
+; CHECK-P9-NEXT: .byte 31
+; CHECK-P9-NEXT: .byte 31
+; CHECK-P9-NEXT: .byte 31
+; CHECK-P9-NEXT: .byte 29
+; CHECK-P9-NEXT: .byte 28
+; CHECK-P9-NEXT: .byte 31
+; CHECK-P9-NEXT: .byte 31
+; CHECK-P9-NEXT: .byte 31
+; CHECK-P9-NEXT: .byte 31
+; CHECK-P9-NEXT: .byte 31
+; CHECK-P9-NEXT: .byte 31
+; CHECK-P9: vperm [[REG1:v[0-9]+]]
+; CHECK-P9: vextsh2d [[REG2:v[0-9]+]], [[REG1]]
+; CHECK-P9: xvcvsxddp {{vs[0-9]+}}, [[REG2]]
+; CHECK-BE-LABEL: .LCPI5_0:
+; CHECK-BE-NEXT: .byte 0
+; CHECK-BE-NEXT: .byte 0
+; CHECK-BE-NEXT: .byte 0
+; CHECK-BE-NEXT: .byte 0
+; CHECK-BE-NEXT: .byte 0
+; CHECK-BE-NEXT: .byte 0
+; CHECK-BE-NEXT: .byte 0
+; CHECK-BE-NEXT: .byte 1
+; CHECK-BE-NEXT: .byte 0
+; CHECK-BE-NEXT: .byte 0
+; CHECK-BE-NEXT: .byte 0
+; CHECK-BE-NEXT: .byte 0
+; CHECK-BE-NEXT: .byte 0
+; CHECK-BE-NEXT: .byte 0
+; CHECK-BE-NEXT: .byte 2
+; CHECK-BE-NEXT: .byte 3
+; CHECK-BE: addi [[REG1:r[0-9]+]], {{r[0-9]+}}, .LCPI5_0 at toc@l
+; CHECK-BE: lxvx [[REG2:v[0-9]+]], 0, [[REG1]]
+; CHECK-BE: vperm [[REG3:v[0-9]+]], {{v[0-9]+}}, {{v[0-9]+}}, [[REG2]]
+; CHECK-BE: vextsh2d [[REG4:v[0-9]+]], [[REG3]]
+; CHECK-BE: xvcvsxddp {{vs[0-9]+}}, [[REG4]]
+}
More information about the llvm-commits
mailing list