For extracting high part element from DImode register like:

{%1:SF=unspec[r122:DI>>0x20#0] 86;clobber scratch;}

split it before reload with "and mask" to avoid generating shift right
32 bit then shift left 32 bit.

srdi 3,3,32
sldi 9,3,32
mtvsrd 1,9
xscvspdpn 1,1

=>

rldicr 3,3,0,31
mtvsrd 1,3
xscvspdpn 1,1

gcc/ChangeLog:

2020-07-03  Xionghu Luo  <luo...@linux.ibm.com>

        PR rtl-optimization/89310
        * config/rs6000/rs6000.md (movsf_from_si2): New
        define_insn_and_split.

gcc/testsuite/ChangeLog:

2020-07-03  Xionghu Luo  <luo...@linux.ibm.com>

        PR rtl-optimization/89310
        * gcc.target/powerpc/pr89310.c: New test.
---
 gcc/config/rs6000/rs6000.md                | 63 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/powerpc/pr89310.c | 17 ++++++
 2 files changed, 80 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr89310.c

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 4fcd6a94022..8d51de07594 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -7593,6 +7593,69 @@ (define_insn_and_split "movsf_from_si"
            "*,          *,         p9v,       p8v,       *,         *,
             p8v,        p8v,       p8v,       *")])
 
+;; For extracting high part element from DImode register like:
+;;     {%1:SF=unspec[r122:DI>>0x20#0] 86;clobber scratch;}
+;; split it before reload with "and mask" to avoid generating shift right
+;; 32 bit then shift left 32 bit.
+(define_insn_and_split "movsf_from_si2"
+  [(set (match_operand:SF 0 "nonimmediate_operand"
+           "=!r,       f,         v,         wa,        m,         Z,
+            Z,         wa,        ?r,        !r")
+           (unspec:SF [
+            (subreg:SI (ashiftrt:DI
+              (match_operand:DI 1 "input_operand"
+          "m,         m,         wY,        Z,         r,         f,
+          wa,        r,         wa,        r")
+         (const_int 32)) 0)]
+                  UNSPEC_SF_FROM_SI))
+  (clobber (match_scratch:DI 2
+           "=X,        X,         X,         X,         X,         X,
+           X,         r,         X,         X"))]
+  "TARGET_NO_SF_SUBREG
+   && (register_operand (operands[0], SFmode)
+       && register_operand (operands[1], DImode))"
+  "@
+   lwz%U1%X1 %0,%1
+   lfs%U1%X1 %0,%1
+   lxssp %0,%1
+   lxsspx %x0,%y1
+   stw%U0%X0 %1,%0
+   stfiwx %1,%y0
+   stxsiwx %x1,%y0
+   #
+   mfvsrwz %0,%x1
+   mr %0,%1"
+
+  "&& !reload_completed
+   && vsx_reg_sfsubreg_ok (operands[0], SFmode)"
+  [(const_int 0)]
+{
+  rtx op0 = operands[0];
+  rtx op1 = operands[1];
+  rtx tmp = gen_reg_rtx (DImode);
+
+  /* Avoid split {r155:SI#0=unspec[r133:DI>>0x20#0] 86;clobber scratch;} from 
PR42745.  */
+  if (!SUBREG_P (operands[0]))
+    {
+      rtx mask = GEN_INT (HOST_WIDE_INT_M1U << 32);
+      emit_insn (gen_anddi3 (tmp, op1, mask));
+      emit_insn (gen_p8_mtvsrd_sf (op0, tmp));
+      emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
+      DONE;
+    }
+  else
+    FAIL;
+}
+  [(set_attr "length"
+           "*,          *,         *,         *,         *,         *,
+            *,          12,        *,         *")
+   (set_attr "type"
+           "load,       fpload,    fpload,    fpload,    store,     fpstore,
+            fpstore,    vecfloat,  mffgpr,    *")
+   (set_attr "isa"
+           "*,          *,         p9v,       p8v,       *,         *,
+            p8v,        p8v,       p8v,       *")])
+
 
 ;; Move 64-bit binary/decimal floating point
 (define_expand "mov<mode>"
diff --git a/gcc/testsuite/gcc.target/powerpc/pr89310.c 
b/gcc/testsuite/gcc.target/powerpc/pr89310.c
new file mode 100644
index 00000000000..15e78509246
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr89310.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct s {
+  int i;
+  float f;
+};
+
+float
+foo (struct s arg)
+{
+  return arg.f;
+}
+
+/* { dg-final { scan-assembler-not {\msrdi\M} } } */
+/* { dg-final { scan-assembler-not {\msldi\M} } } */
+/* { dg-final { scan-assembler-times {\mrldicr\M} 1 } } */
-- 
2.21.0.777.g83232e3864

Reply via email to