]> granicus.if.org Git - llvm/commitdiff
[PowerPC] [PowerPC] Enhance the fast selection of fptoi & fptrunc instruction and...
authorKang Zhang <shkzhang@cn.ibm.com>
Mon, 25 Feb 2019 02:46:16 +0000 (02:46 +0000)
committerKang Zhang <shkzhang@cn.ibm.com>
Mon, 25 Feb 2019 02:46:16 +0000 (02:46 +0000)
Summary:
Fast selection of llvm fptoi & fptrunc instructions is not handled well about
VSX instruction support.
We'd use VSX float convert integer instruction instead of non-vsx float convert
integer instruction if the operand register class is VSSRC or VSFRC because i32
and i64 are mapped to VSSRC and VSFRC correspondingly if VSX feature is
openeded.
For float trunc instruction, we do this silimar work like float convert integer
instruction to try to use VSX instruction.

Reviewed By: jsji

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354762 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCFastISel.cpp
test/CodeGen/PowerPC/fast-isel-rsp.ll [new file with mode: 0644]
test/CodeGen/PowerPC/pr26180.ll

index 14a72bd9980ead4cbcaeb4c2f90a886a86703323..e22e682bc5783ec890172ff5a098b54c37c56b2e 100644 (file)
@@ -987,12 +987,17 @@ bool PPCFastISel::SelectFPTrunc(const Instruction *I) {
 
   // Round the result to single precision.
   unsigned DestReg;
-
+  auto RC = MRI.getRegClass(SrcReg);
   if (PPCSubTarget->hasSPE()) {
     DestReg = createResultReg(&PPC::SPE4RCRegClass);
     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
       TII.get(PPC::EFSCFD), DestReg)
       .addReg(SrcReg);
+  } else if (isVSFRCRegClass(RC)) {
+    DestReg = createResultReg(&PPC::VSSRCRegClass);
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
+      TII.get(PPC::XSRSP), DestReg)
+      .addReg(SrcReg);
   } else {
     DestReg = createResultReg(&PPC::F4RCRegClass);
     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
@@ -1207,16 +1212,19 @@ bool PPCFastISel::SelectFPToI(const Instruction *I, bool IsSigned) {
   if (SrcReg == 0)
     return false;
 
-  // Convert f32 to f64 if necessary.  This is just a meaningless copy
-  // to get the register class right.
+  // Convert f32 to f64 or convert VSSRC to VSFRC if necessary. This is just a
+  // meaningless copy to get the register class right.
   const TargetRegisterClass *InRC = MRI.getRegClass(SrcReg);
   if (InRC == &PPC::F4RCRegClass)
     SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
+  else if (InRC == &PPC::VSSRCRegClass)
+    SrcReg = copyRegToRegClass(&PPC::VSFRCRegClass, SrcReg);
 
   // Determine the opcode for the conversion, which takes place
-  // entirely within FPRs.
+  // entirely within FPRs or VSRs.
   unsigned DestReg;
   unsigned Opc;
+  auto RC = MRI.getRegClass(SrcReg);
 
   if (PPCSubTarget->hasSPE()) {
     DestReg = createResultReg(&PPC::GPRCRegClass);
@@ -1224,6 +1232,12 @@ bool PPCFastISel::SelectFPToI(const Instruction *I, bool IsSigned) {
       Opc = InRC == &PPC::SPE4RCRegClass ? PPC::EFSCTSIZ : PPC::EFDCTSIZ;
     else
       Opc = InRC == &PPC::SPE4RCRegClass ? PPC::EFSCTUIZ : PPC::EFDCTUIZ;
+  } else if (isVSFRCRegClass(RC)) {
+    DestReg = createResultReg(&PPC::VSFRCRegClass);
+    if (DstVT == MVT::i32) 
+      Opc = IsSigned ? PPC::XSCVDPSXWS : PPC::XSCVDPUXWS;
+    else
+      Opc = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
   } else {
     DestReg = createResultReg(&PPC::F8RCRegClass);
     if (DstVT == MVT::i32)
diff --git a/test/CodeGen/PowerPC/fast-isel-rsp.ll b/test/CodeGen/PowerPC/fast-isel-rsp.ll
new file mode 100644 (file)
index 0000000..700e159
--- /dev/null
@@ -0,0 +1,13 @@
+; RUN: llc -mcpu=generic -mtriple=powerpc64le-unknown-unknown -O0 < %s \ 
+; RUN:   -verify-machineinstrs | FileCheck %s --check-prefix=GENERIC
+; RUN: llc -mcpu=ppc -mtriple=powerpc64le-unknown-unknown -O0 < %s \
+; RUN:   -verify-machineinstrs | FileCheck %s
+
+define float @testRSP(double %x) {
+entry:
+  %0 = fptrunc double %x to float
+  ret float %0
+; CHECK: frsp 1, 1
+; GENERIC: xsrsp 1, 1
+}
+
index d4b05dfeed6111051056e8d68787acde61efe28f..e8c6c60061cc0a30c5167300b8487b171a5c24b2 100644 (file)
@@ -1,14 +1,27 @@
-; RUN: llc -mcpu=generic -mtriple=powerpc64le-unknown-unknown -O0 < %s | FileCheck %s --check-prefix=GENERIC
-; RUN: llc -mcpu=ppc -mtriple=powerpc64le-unknown-unknown -O0 < %s | FileCheck %s
+; RUN: llc -mcpu=generic -mtriple=powerpc64le-unknown-unknown -O0 < %s \ 
+; RUN:   -verify-machineinstrs | FileCheck %s --check-prefix=GENERIC
+; RUN: llc -mcpu=ppc -mtriple=powerpc64le-unknown-unknown -O0 < %s \
+; RUN:   -verify-machineinstrs | FileCheck %s
 
 define i32 @bad(double %x) {
   %1 = fptoui double %x to i32
   ret i32 %1
-}
 
 ; CHECK: fctidz [[REG0:[0-9]+]], 1
 ; CHECK: stfd [[REG0]], [[OFF:.*]](1)
 ; CHECK: lwz {{[0-9]*}}, [[OFF]](1)
-; GENERIC: fctiwuz [[REG0:[0-9]+]], 1
-; GENERIC: stfd [[REG0]], [[OFF:.*]](1)
-; GENERIC: lwz {{[0-9]*}}, [[OFF]](1)
+; GENERIC: xscvdpuxws [[REG0:[0-9]+]], 1
+; GENERIC: mfvsrwz  {{[0-9]*}}, [[REG0]]
+}
+
+define i32 @bad1(float %x) {
+entry:
+  %0 = fptosi float %x to i32
+  ret i32 %0
+
+; CHECK: fctiwz [[REG0:[0-9]+]], 1
+; CHECK: stfd [[REG0]], [[OFF:.*]](1)
+; CHECK: lwa {{[0-9]*}}, [[OFF]](1)
+; GENERIC: xscvdpsxws [[REG0:[0-9]+]], 1
+; GENERIC: mfvsrwz  {{[0-9]*}}, [[REG0]]
+}