[llvm] r331787 - [Power9]Legalize and emit code for truncate and convert QP to DW

Lei Huang via llvm-commits llvm-commits at lists.llvm.org
Tue May 8 11:23:31 PDT 2018


Author: lei
Date: Tue May  8 11:23:31 2018
New Revision: 331787

URL: http://llvm.org/viewvc/llvm-project?rev=331787&view=rev
Log:
[Power9]Legalize and emit code for truncate and convert QP to DW

Legalize and emit code for:

  * xscvqpsdz : VSX Scalar truncate & Convert Quad-Precision to Signed Dword
  * xscvqpudz : VSX Scalar truncate & Convert Quad-Precision to Unsigned Dword

Differential Revision: https://reviews.llvm.org/D45553

Added:
    llvm/trunk/test/CodeGen/PowerPC/f128-truncateNconv.ll
Modified:
    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/trunk/lib/Target/PowerPC/PPCInstrVSX.td

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=331787&r1=331786&r2=331787&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Tue May  8 11:23:31 2018
@@ -6930,6 +6930,11 @@ SDValue PPCTargetLowering::LowerFP_TO_IN
 
 SDValue PPCTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
                                           const SDLoc &dl) const {
+
+  // FP to INT conversions are legal for f128.
+  if (EnableQuadPrecision && (Op->getOperand(0).getValueType() == MVT::f128))
+    return Op;
+
   // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
   // PPC (the libcall is not available).
   if (Op.getOperand(0).getValueType() == MVT::ppcf128) {

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrVSX.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrVSX.td?rev=331787&r1=331786&r2=331787&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrVSX.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrVSX.td Tue May  8 11:23:31 2018
@@ -2530,7 +2530,7 @@ let AddedComplexity = 400, Predicates =
   def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
   def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
 
-  // Convert (Un)Signed DWord -> QP
+  // Convert (Un)Signed DWord -> QP.
   def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>;
   def : Pat<(f128 (sint_to_fp i64:$src)),
             (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
@@ -2538,7 +2538,7 @@ let AddedComplexity = 400, Predicates =
   def : Pat<(f128 (uint_to_fp i64:$src)),
             (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
 
-  // Convert (Un)Signed Word -> QP
+  // Convert (Un)Signed Word -> QP.
   def : Pat<(f128 (sint_to_fp i32:$src)),
             (f128 (XSCVSDQP (MTVSRWA $src)))>;
   def : Pat<(f128 (sint_to_fp (i32 (load xoaddr:$src)))),
@@ -3170,9 +3170,21 @@ let AddedComplexity = 400, Predicates =
   def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi8)),
             (f128 (XSCVUDQP (LXSIBZX xoaddr:$src)))>;
 
+  // Truncate & Convert QP -> (Un)Signed (D)Word.
+  def : Pat<(i64 (fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>;
+  def : Pat<(i64 (fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>;
+
   // Instructions for fptosint (i64,i16,i8) feeding a store.
   // The 8-byte version is repeated here due to availability of D-Form STXSD.
   def : Pat<(PPCstore_scal_int_from_vsr
+              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xaddr:$dst, 8),
+            (STXSDX (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
+                    xaddr:$dst)>;
+  def : Pat<(PPCstore_scal_int_from_vsr
+              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), ixaddr:$dst, 8),
+            (STXSD (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
+                   ixaddr:$dst)>;
+  def : Pat<(PPCstore_scal_int_from_vsr
               (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xaddr:$dst, 8),
             (STXSDX (XSCVDPSXDS f64:$src), xaddr:$dst)>;
   def : Pat<(PPCstore_scal_int_from_vsr
@@ -3187,6 +3199,14 @@ let AddedComplexity = 400, Predicates =
 
   // Instructions for fptouint (i64,i16,i8) feeding a store.
   def : Pat<(PPCstore_scal_int_from_vsr
+              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xaddr:$dst, 8),
+            (STXSDX (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
+                    xaddr:$dst)>;
+  def : Pat<(PPCstore_scal_int_from_vsr
+              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), ixaddr:$dst, 8),
+            (STXSD (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
+                   ixaddr:$dst)>;
+  def : Pat<(PPCstore_scal_int_from_vsr
               (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xaddr:$dst, 8),
             (STXSDX (XSCVDPUXDS f64:$src), xaddr:$dst)>;
   def : Pat<(PPCstore_scal_int_from_vsr

Added: llvm/trunk/test/CodeGen/PowerPC/f128-truncateNconv.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/f128-truncateNconv.ll?rev=331787&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/f128-truncateNconv.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/f128-truncateNconv.ll Tue May  8 11:23:31 2018
@@ -0,0 +1,195 @@
+; RUN: llc -mcpu=pwr9 -mtriple=powerpc64le-unknown-unknown \
+; RUN:   -verify-machineinstrs -enable-ppc-quad-precision \
+; RUN:   -ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+ at f128Array = global [4 x fp128] [fp128 0xL00000000000000004004C00000000000,
+                                 fp128 0xLF000000000000000400808AB851EB851,
+                                 fp128 0xL5000000000000000400E0C26324C8366,
+                                 fp128 0xL8000000000000000400A24E2E147AE14],
+                                align 16
+
+; Function Attrs: norecurse nounwind readonly
+define i64 @qpConv2sdw(fp128* nocapture readonly %a) {
+entry:
+  %0 = load fp128, fp128* %a, align 16
+  %conv = fptosi fp128 %0 to i64
+  ret i64 %conv
+
+; CHECK-LABEL: qpConv2sdw
+; CHECK: lxv [[REG:[0-9]+]], 0(3)
+; CHECK-NEXT: xscvqpsdz [[CONV:[0-9]+]], [[REG]]
+; CHECK-NEXT: mfvsrd 3, [[CONV]]
+; CHECK-NEXT: blr
+}
+
+; Function Attrs: norecurse nounwind
+define void @qpConv2sdw_02(i64* nocapture %res) local_unnamed_addr #1 {
+entry:
+  %0 = load fp128, fp128* getelementptr inbounds
+                            ([4 x fp128], [4 x fp128]* @f128Array, i64 0,
+                             i64 2), align 16
+  %conv = fptosi fp128 %0 to i64
+  store i64 %conv, i64* %res, align 8
+  ret void
+
+; CHECK-LABEL: qpConv2sdw_02
+; CHECK: addis [[REG0:[0-9]+]], 2, .LC0 at toc@ha
+; CHECK: ld [[REG0]], .LC0 at toc@l([[REG0]])
+; CHECK: lxv [[REG:[0-9]+]], 32([[REG0]])
+; CHECK-NEXT: xscvqpsdz [[CONV:[0-9]+]], [[REG]]
+; CHECK-NEXT: stxsd [[CONV]], 0(3)
+; CHECK-NEXT: blr
+}
+
+; Function Attrs: norecurse nounwind readonly
+define i64 @qpConv2sdw_03(fp128* nocapture readonly %a) {
+entry:
+  %0 = load fp128, fp128* %a, align 16
+  %1 = load fp128, fp128* getelementptr inbounds
+                            ([4 x fp128], [4 x fp128]* @f128Array, i64 0,
+                             i64 1), align 16
+  %add = fadd fp128 %0, %1
+  %conv = fptosi fp128 %add to i64
+  ret i64 %conv
+
+; CHECK-LABEL: qpConv2sdw_03
+; CHECK: addis [[REG0:[0-9]+]], 2, .LC0 at toc@ha
+; CHECK-DAG: ld [[REG0]], .LC0 at toc@l([[REG0]])
+; CHECK-DAG: lxv [[REG1:[0-9]+]], 16([[REG0]])
+; CHECK-DAG: lxv [[REG:[0-9]+]], 0(3)
+; CHECK: xsaddqp [[REG]], [[REG]], [[REG1]]
+; CHECK-NEXT: xscvqpsdz [[CONV:[0-9]+]], [[REG]]
+; CHECK-NEXT: mfvsrd 3, [[CONV]]
+; CHECK-NEXT: blr
+}
+
+; Function Attrs: norecurse nounwind
+define void @qpConv2sdw_04(fp128* nocapture readonly %a,
+                           fp128* nocapture readonly %b, i64* nocapture %res) {
+entry:
+  %0 = load fp128, fp128* %a, align 16
+  %1 = load fp128, fp128* %b, align 16
+  %add = fadd fp128 %0, %1
+  %conv = fptosi fp128 %add to i64
+  store i64 %conv, i64* %res, align 8
+  ret void
+
+; CHECK-LABEL: qpConv2sdw_04
+; CHECK-DAG: lxv [[REG1:[0-9]+]], 0(4)
+; CHECK-DAG: lxv [[REG:[0-9]+]], 0(3)
+; CHECK: xsaddqp [[REG]], [[REG]], [[REG1]]
+; CHECK-NEXT: xscvqpsdz [[CONV:[0-9]+]], [[REG]]
+; CHECK-NEXT: stxsd [[CONV]], 0(5)
+; CHECK-NEXT: blr
+}
+
+; Function Attrs: norecurse nounwind
+define void @qpConv2sdw_testXForm(i64* nocapture %res, i32 signext %idx) {
+entry:
+  %0 = load fp128, fp128* getelementptr inbounds
+                            ([4 x fp128], [4 x fp128]* @f128Array,
+                             i64 0, i64 2), align 16
+  %conv = fptosi fp128 %0 to i64
+  %idxprom = sext i32 %idx to i64
+  %arrayidx = getelementptr inbounds i64, i64* %res, i64 %idxprom
+  store i64 %conv, i64* %arrayidx, align 8
+  ret void
+
+; CHECK-LABEL: qpConv2sdw_testXForm
+; CHECK: xscvqpsdz [[CONV:[0-9]+]],
+; CHECK-NEXT: stxsdx [[CONV]], 3, 4
+; CHECK-NEXT: blr
+}
+
+; Function Attrs: norecurse nounwind readonly
+define i64 @qpConv2udw(fp128* nocapture readonly %a) {
+entry:
+  %0 = load fp128, fp128* %a, align 16
+  %conv = fptoui fp128 %0 to i64
+  ret i64 %conv
+
+; CHECK-LABEL: qpConv2udw
+; CHECK: lxv [[REG:[0-9]+]], 0(3)
+; CHECK-NEXT: xscvqpudz [[CONV:[0-9]+]], [[REG]]
+; CHECK-NEXT: mfvsrd 3, [[CONV]]
+; CHECK-NEXT: blr
+}
+
+; Function Attrs: norecurse nounwind
+define void @qpConv2udw_02(i64* nocapture %res) {
+entry:
+  %0 = load fp128, fp128* getelementptr inbounds
+                            ([4 x fp128], [4 x fp128]* @f128Array, i64 0,
+                             i64 2), align 16
+  %conv = fptoui fp128 %0 to i64
+  store i64 %conv, i64* %res, align 8
+  ret void
+
+; CHECK-LABEL: qpConv2udw_02
+; CHECK: addis [[REG0:[0-9]+]], 2, .LC0 at toc@ha
+; CHECK: ld [[REG0]], .LC0 at toc@l([[REG0]])
+; CHECK: lxv [[REG:[0-9]+]], 32([[REG0]])
+; CHECK-NEXT: xscvqpudz [[CONV:[0-9]+]], [[REG]]
+; CHECK-NEXT: stxsd [[CONV]], 0(3)
+; CHECK-NEXT: blr
+}
+
+; Function Attrs: norecurse nounwind readonly
+define i64 @qpConv2udw_03(fp128* nocapture readonly %a) {
+entry:
+  %0 = load fp128, fp128* %a, align 16
+  %1 = load fp128, fp128* getelementptr inbounds
+                            ([4 x fp128], [4 x fp128]* @f128Array, i64 0,
+                             i64 1), align 16
+  %add = fadd fp128 %0, %1
+  %conv = fptoui fp128 %add to i64
+  ret i64 %conv
+
+; CHECK-LABEL: qpConv2udw_03
+; CHECK: addis [[REG0:[0-9]+]], 2, .LC0 at toc@ha
+; CHECK-DAG: ld [[REG0]], .LC0 at toc@l([[REG0]])
+; CHECK-DAG: lxv [[REG1:[0-9]+]], 16([[REG0]])
+; CHECK-DAG: lxv [[REG:[0-9]+]], 0(3)
+; CHECK: xsaddqp [[REG]], [[REG]], [[REG1]]
+; CHECK-NEXT: xscvqpudz [[CONV:[0-9]+]], [[REG]]
+; CHECK-NEXT: mfvsrd 3, [[CONV]]
+; CHECK-NEXT: blr
+}
+
+; Function Attrs: norecurse nounwind
+define void @qpConv2udw_04(fp128* nocapture readonly %a,
+                           fp128* nocapture readonly %b, i64* nocapture %res) {
+entry:
+  %0 = load fp128, fp128* %a, align 16
+  %1 = load fp128, fp128* %b, align 16
+  %add = fadd fp128 %0, %1
+  %conv = fptoui fp128 %add to i64
+  store i64 %conv, i64* %res, align 8
+  ret void
+
+; CHECK-LABEL: qpConv2udw_04
+; CHECK-DAG: lxv [[REG1:[0-9]+]], 0(4)
+; CHECK-DAG: lxv [[REG:[0-9]+]], 0(3)
+; CHECK: xsaddqp [[REG]], [[REG]], [[REG1]]
+; CHECK-NEXT: xscvqpudz [[CONV:[0-9]+]], [[REG]]
+; CHECK-NEXT: stxsd [[CONV]], 0(5)
+; CHECK-NEXT: blr
+}
+
+; Function Attrs: norecurse nounwind
+define void @qpConv2udw_testXForm(i64* nocapture %res, i32 signext %idx) {
+entry:
+  %0 = load fp128, fp128* getelementptr inbounds
+                            ([4 x fp128], [4 x fp128]* @f128Array,
+                             i64 0, i64 0), align 16
+  %conv = fptoui fp128 %0 to i64
+  %idxprom = sext i32 %idx to i64
+  %arrayidx = getelementptr inbounds i64, i64* %res, i64 %idxprom
+  store i64 %conv, i64* %arrayidx, align 8
+  ret void
+
+; CHECK-LABEL: qpConv2udw_testXForm
+; CHECK: xscvqpudz [[CONV:[0-9]+]],
+; CHECK-NEXT: stxsdx [[CONV]], 3, 4
+; CHECK-NEXT: blr
+}




More information about the llvm-commits mailing list