Bitcasts between FP and INT values using direct moves
authorNemanja Ivanovic <nemanja.i.ibm@gmail.com>
Tue, 15 Dec 2015 14:50:34 +0000 (14:50 +0000)
committerNemanja Ivanovic <nemanja.i.ibm@gmail.com>
Tue, 15 Dec 2015 14:50:34 +0000 (14:50 +0000)
This patch corresponds to review:
http://reviews.llvm.org/D15286

This patch was meant to land in revision 255246, but I accidentally uploaded
the patch that corresponds to http://reviews.llvm.org/D15372 in that revision
accidentally.

Thereby, this patch is the actual Bitcasts using direct moves patch, whereas
http://reviews.llvm.org/rL255246 actually corresponds to
http://reviews.llvm.org/D15372.

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

lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/PowerPC/PPCInstrVSX.td
lib/Target/PowerPC/PPCVSXCopy.cpp
test/CodeGen/PowerPC/bitcasts-direct-move.ll [new file with mode: 0644]
test/CodeGen/PowerPC/fp128-bitcast-after-operation.ll

index 8788382567bcb4ee4078b9747b801bf41b0aa011..c84248c64632a6caa8ca1fa5162304e57b1580aa 100644 (file)
@@ -255,10 +255,17 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
   setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand);
   setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
 
-  setOperationAction(ISD::BITCAST, MVT::f32, Expand);
-  setOperationAction(ISD::BITCAST, MVT::i32, Expand);
-  setOperationAction(ISD::BITCAST, MVT::i64, Expand);
-  setOperationAction(ISD::BITCAST, MVT::f64, Expand);
+  if (Subtarget.hasDirectMove()) {
+    setOperationAction(ISD::BITCAST, MVT::f32, Legal);
+    setOperationAction(ISD::BITCAST, MVT::i32, Legal);
+    setOperationAction(ISD::BITCAST, MVT::i64, Legal);
+    setOperationAction(ISD::BITCAST, MVT::f64, Legal);
+  } else {
+    setOperationAction(ISD::BITCAST, MVT::f32, Expand);
+    setOperationAction(ISD::BITCAST, MVT::i32, Expand);
+    setOperationAction(ISD::BITCAST, MVT::i64, Expand);
+    setOperationAction(ISD::BITCAST, MVT::f64, Expand);
+  }
 
   // We cannot sextinreg(i1).  Expand to shifts.
   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
index 1b3ffbfcee83d2cf808a8edc9aec4ea5a6ee14db..df1142cb42f3d405858b4daba9633ee79be2354b 100644 (file)
@@ -1759,3 +1759,27 @@ let Predicates = [IsLittleEndian, HasDirectMove] in {
   def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
             (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
 } // IsLittleEndian, HasDirectMove
+
+let Predicates = [HasDirectMove, HasVSX] in {
+// bitconvert f32 -> i32
+// (convert to 32-bit fp single, shift right 1 word, move to GPR)
+def : Pat<(i32 (bitconvert f32:$S)),
+          (i32 (MFVSRWZ (EXTRACT_SUBREG
+                          (XXSLDWI (XSCVDPSPN $S),(XSCVDPSPN $S), 3),
+                          sub_64)))>;
+// bitconvert i32 -> f32
+// (move to FPR, shift left 1 word, convert to 64-bit fp single)
+def : Pat<(f32 (bitconvert i32:$A)),
+          (f32 (XSCVSPDPN
+                 (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
+
+// bitconvert f64 -> i64
+// (move to GPR, nothing else needed)
+def : Pat<(i64 (bitconvert f64:$S)),
+          (i64 (MFVSRD $S))>;
+
+// bitconvert i64 -> f64
+// (move to FPR, nothing else needed)
+def : Pat<(f64 (bitconvert i64:$S)),
+          (f64 (MTVSRD $S))>;
+}
index 11ee3051f984e0bb308920de1560acf1123635b7..782583ce3423d2e99c872f789d897f762cabc84e 100644 (file)
@@ -81,6 +81,10 @@ namespace {
       return IsRegInClass(Reg, &PPC::VSFRCRegClass, MRI);
     }
 
+    bool IsVSSReg(unsigned Reg, MachineRegisterInfo &MRI) {
+      return IsRegInClass(Reg, &PPC::VSSRCRegClass, MRI);
+    }
+
 protected:
     bool processBlock(MachineBasicBlock &MBB) {
       bool Changed = false;
@@ -105,6 +109,7 @@ protected:
                                            &PPC::VSLRCRegClass;
           assert((IsF8Reg(SrcMO.getReg(), MRI) ||
                   IsVRReg(SrcMO.getReg(), MRI) ||
+                  IsVSSReg(SrcMO.getReg(), MRI) ||
                   IsVSFReg(SrcMO.getReg(), MRI)) &&
                  "Unknown source for a VSX copy");
 
@@ -129,6 +134,7 @@ protected:
                                            &PPC::VSLRCRegClass;
           assert((IsF8Reg(DstMO.getReg(), MRI) ||
                   IsVSFReg(DstMO.getReg(), MRI) ||
+                  IsVSSReg(DstMO.getReg(), MRI) ||
                   IsVRReg(DstMO.getReg(), MRI)) &&
                  "Unknown destination for a VSX copy");
 
diff --git a/test/CodeGen/PowerPC/bitcasts-direct-move.ll b/test/CodeGen/PowerPC/bitcasts-direct-move.ll
new file mode 100644 (file)
index 0000000..756f579
--- /dev/null
@@ -0,0 +1,83 @@
+; RUN: llc -mcpu=pwr8 -mtriple=powerpc64-unknown-unknown < %s | FileCheck %s
+; RUN: llc -mcpu=pwr7 -mtriple=powerpc64le-unknown-unknown < %s | FileCheck %s \
+; RUN:  --check-prefix=CHECK-P7
+
+define signext i32 @f32toi32(float %a) {
+entry:
+  %0 = bitcast float %a to i32
+  ret i32 %0
+; CHECK-P7: stfs 1,
+; CHECK-P7: lwa 3,
+; CHECK: xscvdpspn [[CONVREG:[0-9]+]], 1
+; CHECK: xxsldwi [[SHIFTREG:[0-9]+]], [[CONVREG]], [[CONVREG]], 3
+; CHECK: mfvsrwz 3, [[SHIFTREG]]
+}
+
+define i64 @f64toi64(double %a) {
+entry:
+  %0 = bitcast double %a to i64
+  ret i64 %0
+; CHECK-P7: stxsdx 1,
+; CHECK-P7: ld 3,
+; CHECK: mfvsrd 3, 1
+}
+
+define float @i32tof32(i32 signext %a) {
+entry:
+  %0 = bitcast i32 %a to float
+  ret float %0
+; CHECK-P7: stw 3,
+; CHECK-P7: lfs 1,
+; CHECK: mtvsrd [[MOVEREG:[0-9]+]], 3
+; CHECK: xxsldwi [[SHIFTREG:[0-9]+]], [[MOVEREG]], [[MOVEREG]], 1
+; CHECK: xscvspdpn 1, [[SHIFTREG]]
+}
+
+define double @i64tof64(i64 %a) {
+entry:
+  %0 = bitcast i64 %a to double
+  ret double %0
+; CHECK-P7: std 3,
+; CHECK-P7: lxsdx 1,
+; CHECK: mtvsrd 1, 3
+}
+
+define zeroext i32 @f32toi32u(float %a) {
+entry:
+  %0 = bitcast float %a to i32
+  ret i32 %0
+; CHECK-P7: stfs 1,
+; CHECK-P7: lwz 3,
+; CHECK: xscvdpspn [[CONVREG:[0-9]+]], 1
+; CHECK: xxsldwi [[SHIFTREG:[0-9]+]], [[CONVREG]], [[CONVREG]], 3
+; CHECK: mfvsrwz 3, [[SHIFTREG]]
+}
+
+define i64 @f64toi64u(double %a) {
+entry:
+  %0 = bitcast double %a to i64
+  ret i64 %0
+; CHECK-P7: stxsdx 1,
+; CHECK-P7: ld 3,
+; CHECK: mfvsrd 3, 1
+}
+
+define float @i32utof32(i32 zeroext %a) {
+entry:
+  %0 = bitcast i32 %a to float
+  ret float %0
+; CHECK-P7: stw 3,
+; CHECK-P7: lfs 1,
+; CHECK: mtvsrd [[MOVEREG:[0-9]+]], 3
+; CHECK: xxsldwi [[SHIFTREG:[0-9]+]], [[MOVEREG]], [[MOVEREG]], 1
+; CHECK: xscvspdpn 1, [[SHIFTREG]]
+}
+
+define double @i64utof64(i64 %a) {
+entry:
+  %0 = bitcast i64 %a to double
+  ret double %0
+; CHECK-P7: std 3,
+; CHECK-P7: lxsdx 1,
+; CHECK: mtvsrd 1, 3
+}
index 5f3c9278f8d5c7b27f862d516fa5987b5cd92d83..f5b0a3a59bf3674742d2df9561216228aceb1a26 100644 (file)
@@ -1,6 +1,6 @@
-; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s -check-prefix=PPC64
+; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s -check-prefix=PPC64-P8
 ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr7 < %s | FileCheck %s -check-prefix=PPC64
-; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s -check-prefix=PPC64
+; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s -check-prefix=PPC64-P8
 ; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 < %s | FileCheck %s -check-prefix=PPC64
 ; RUN: llc -mtriple=powerpc-unknown-linux-gnu < %s | FileCheck %s -check-prefix=PPC32
 
@@ -20,6 +20,16 @@ entry:
 ; PPC64-DAG: xor 4, [[LO]], [[FLIP_BIT]]
 ; PPC64: blr
 
+; PPC64-P8-LABEL: test_abs:
+; PPC64-P8-DAG: mfvsrd [[LO:[0-9]+]], 2
+; PPC64-P8-DAG: mfvsrd [[HI:[0-9]+]], 1
+; PPC64-P8-DAG: li [[MASK_REG:[0-9]+]], 1
+; PPC64-P8-DAG: sldi [[SHIFT_REG:[0-9]+]], [[MASK_REG]], 63
+; PPC64-P8: and [[FLIP_BIT:[0-9]+]], [[HI]], [[SHIFT_REG]]
+; PPC64-P8-DAG: xor 3, [[HI]], [[FLIP_BIT]]
+; PPC64-P8-DAG: xor 4, [[LO]], [[FLIP_BIT]]
+; PPC64-P8: blr
+
 ; PPC32-DAG: stfd 1, 24(1)
 ; PPC32-DAG: stfd 2, 16(1)
 ; PPC32: nop
@@ -52,6 +62,16 @@ entry:
 ; PPC64-DAG: xor 4, [[LO]], [[FLIP_BIT]]
 ; PPC64: blr
 
+; PPC64-P8-LABEL: test_neg:
+; PPC64-P8-DAG: mfvsrd [[LO:[0-9]+]], 2
+; PPC64-P8-DAG: mfvsrd [[HI:[0-9]+]], 1
+; PPC64-P8-DAG: li [[IMM1:[0-9]+]], 1
+; PPC64-P8-DAG: sldi [[FLIP_BIT]], [[IMM1]], 63
+; PPC64-P8-NOT: BARRIER
+; PPC64-P8-DAG: xor 3, [[HI]], [[FLIP_BIT]]
+; PPC64-P8-DAG: xor 4, [[LO]], [[FLIP_BIT]]
+; PPC64-P8: blr
+
 ; PPC32-DAG: stfd 1, 24(1)
 ; PPC32-DAG: stfd 2, 16(1)
 ; PPC32: nop
@@ -86,6 +106,20 @@ entry:
 ; PPC64-DAG: xor 4, [[SIGN]], [[CST_LO]]
 ; PPC64: blr
 
+; PPC64-P8-LABEL: test_copysign:
+; PPC64-P8-DAG: mfvsrd [[X_HI:[0-9]+]], 1
+; PPC64-P8-DAG: li [[SIGN:[0-9]+]], 1
+; PPC64-P8-DAG: sldi [[SIGN]], [[SIGN]], 63
+; PPC64-P8-DAG: li [[HI_TMP:[0-9]+]], 16399
+; PPC64-P8-DAG: sldi [[CST_HI:[0-9]+]], [[HI_TMP]], 48
+; PPC64-P8-DAG: li [[LO_TMP:[0-9]+]], 3019
+; PPC64-P8-DAG: sldi [[CST_LO:[0-9]+]], [[LO_TMP]], 52
+; PPC64-P8-NOT: BARRIER
+; PPC64-P8-DAG: and [[NEW_HI_TMP:[0-9]+]], [[X_HI]], [[SIGN]]
+; PPC64-P8-DAG: or 3, [[NEW_HI_TMP]], [[CST_HI]]
+; PPC64-P8-DAG: xor 4, [[NEW_HI_TMP]], [[CST_LO]]
+; PPC64-P8: blr
+
 ; PPC32: stfd 1, [[STACK:[0-9]+]](1)
 ; PPC32: nop
 ; PPC32: lwz [[HI:[0-9]+]], [[STACK]](1)