public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] rs6000: Split movsf_from_si from high word before reload[PR89310]
@ 2020-07-06  2:17 Xionghu Luo
  2020-07-07  0:18 ` Segher Boessenkool
  0 siblings, 1 reply; 16+ messages in thread
From: Xionghu Luo @ 2020-07-06  2:17 UTC (permalink / raw)
  To: gcc-patches; +Cc: segher, dje.gcc, wschmidt, guojiufu, linkw, Xionghu Luo

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  <luoxhu@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  <luoxhu@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,       *")])
+
 \f
 ;; 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


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2020-07-21  3:43 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-06  2:17 [PATCH] rs6000: Split movsf_from_si from high word before reload[PR89310] Xionghu Luo
2020-07-07  0:18 ` Segher Boessenkool
2020-07-07  8:39   ` luoxhu
2020-07-07 21:31     ` Segher Boessenkool
2020-07-08  3:19       ` luoxhu
2020-07-08 22:43         ` Segher Boessenkool
2020-07-09  3:09           ` luoxhu
2020-07-09 19:25             ` Segher Boessenkool
2020-07-10  1:39               ` [PATCH] rs6000: Define movsf_from_si2 to extract high part SF element from DImode[PR89310] luoxhu
2020-07-11  0:54                 ` Segher Boessenkool
2020-07-13  6:30                   ` luoxhu
2020-07-14 14:17                     ` David Edelsohn
2020-07-15  3:47                       ` luoxhu
2020-07-20 15:31                     ` Segher Boessenkool
2020-07-21  3:43                       ` luoxhu
2020-07-10  7:41               ` [PATCH] rs6000: Split movsf_from_si from high word before reload[PR89310] luoxhu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).