[PATCH] rs6000: Split movsf_from_si from high word before reload[PR89310]
Xionghu Luo
luoxhu@linux.ibm.com
Mon Jul 6 02:17:57 GMT 2020
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, *")])
+
;; 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
More information about the Gcc-patches
mailing list