Commit 8acb8575 by Michael Meissner Committed by Michael Meissner

re PR target/79038 (Improve PowerPC ISA 3.0 conversion between integers and hardware _Float128)

[gcc]
2017-05-05  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/79038
	PR target/79202
	PR target/79203
	* config/rs6000/rs6000.md (u code attribute): Add FIX and
	UNSIGNED_FIX.
	(extendsi<mode>2): Add support for doing sign extension via
	VUPKHSW and XXPERMDI if the value is in Altivec registers and we
	don't have ISA 3.0 instructions.
	(extendsi<mode>2 splitter): Likewise.
	(fix_trunc<mode>si2): If we are at ISA 2.07 (VSX small integer),
	generate the normal insns since SImode can now go in vector
	registers.  Disallow the special UNSPECs needed for previous
	machines to hide SImode being used.  Add new insns
	fctiw{,w}_<mode>_smallint if SImode can go in vector registers.
	(fix_trunc<mode>si2_stfiwx): Likewise.
	(fix_trunc<mode>si2_internal): Likewise.
	(fixuns_trunc<mode>si2): Likewise.
	(fixuns_trunc<mode>si2_stfiwx): Likewise.
	(fctiw<u>z_<mode>_smallint): Likewise.
	(fctiw<u>z_<mode>_mem): New combiner pattern to prevent conversion
	of floating point to 32-bit integer from doing a direct move to
	the GPR registers to do a store.
	(fctiwz_<mode>): Break long line.

[gcc/testsuite]
2017-05-05  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/79038
	PR target/79202
	PR target/79203
	* gcc.target/powerpc/ppc-round3.c: New test.
	* gcc.target/powerpc/ppc-round2.c: Update expected code.

From-SVN: r247657
parent 4b4b2e58
2017-05-05 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/79038
PR target/79202
PR target/79203
* config/rs6000/rs6000.md (u code attribute): Add FIX and
UNSIGNED_FIX.
(extendsi<mode>2): Add support for doing sign extension via
VUPKHSW and XXPERMDI if the value is in Altivec registers and we
don't have ISA 3.0 instructions.
(extendsi<mode>2 splitter): Likewise.
(fix_trunc<mode>si2): If we are at ISA 2.07 (VSX small integer),
generate the normal insns since SImode can now go in vector
registers. Disallow the special UNSPECs needed for previous
machines to hide SImode being used. Add new insns
fctiw{,w}_<mode>_smallint if SImode can go in vector registers.
(fix_trunc<mode>si2_stfiwx): Likewise.
(fix_trunc<mode>si2_internal): Likewise.
(fixuns_trunc<mode>si2): Likewise.
(fixuns_trunc<mode>si2_stfiwx): Likewise.
(fctiw<u>z_<mode>_smallint): Likewise.
(fctiw<u>z_<mode>_mem): New combiner pattern to prevent conversion
of floating point to 32-bit integer from doing a direct move to
the GPR registers to do a store.
(fctiwz_<mode>): Break long line.
2017-05-05 Bin Cheng <bin.cheng@arm.com>
* Makefile.in (GTFILES): Add tree-ssa-loop-ivopts.c.
......
......@@ -566,7 +566,9 @@
(define_code_iterator any_float [float unsigned_float])
(define_code_attr u [(sign_extend "")
(zero_extend "u")])
(zero_extend "u")
(fix "")
(unsigned_fix "u")])
(define_code_attr su [(sign_extend "s")
(zero_extend "u")
......@@ -1027,8 +1029,8 @@
(define_insn "extendsi<mode>2"
[(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK")
(sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK")))]
[(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK,wH")
(sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK,wH")))]
""
"@
lwa%U1%X1 %0,%1
......@@ -1036,9 +1038,38 @@
lfiwax %0,%y1
lxsiwax %x0,%y1
mtvsrwa %x0,%1
vextsw2d %0,%1"
[(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts")
(set_attr "sign_extend" "yes")])
vextsw2d %0,%1
#"
[(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm")
(set_attr "sign_extend" "yes")
(set_attr "length" "4,4,4,4,4,4,8")])
(define_split
[(set (match_operand:DI 0 "altivec_register_operand")
(sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
"TARGET_VSX_SMALL_INTEGER && TARGET_P8_VECTOR && !TARGET_P9_VECTOR
&& reload_completed"
[(const_int 0)]
{
rtx dest = operands[0];
rtx src = operands[1];
int dest_regno = REGNO (dest);
int src_regno = REGNO (src);
rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
if (VECTOR_ELT_ORDER_BIG)
{
emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
}
else
{
emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
}
DONE;
})
(define_insn_and_split "*extendsi<mode>2_dot"
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
......@@ -5570,7 +5601,7 @@
"TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
"
{
if (!<E500_CONVERT>)
if (!<E500_CONVERT> && !TARGET_VSX_SMALL_INTEGER)
{
rtx src = force_reg (<MODE>mode, operands[1]);
......@@ -5596,7 +5627,8 @@
(clobber (match_scratch:DI 2 "=d"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
&& TARGET_STFIWX && can_create_pseudo_p ()"
&& TARGET_STFIWX && can_create_pseudo_p ()
&& !TARGET_VSX_SMALL_INTEGER"
"#"
""
[(pc)]
......@@ -5637,7 +5669,8 @@
(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
(clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
(clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !TARGET_VSX_SMALL_INTEGER"
"#"
""
[(pc)]
......@@ -5721,7 +5754,7 @@
|| <E500_CONVERT>)"
"
{
if (!<E500_CONVERT>)
if (!<E500_CONVERT> && !TARGET_VSX_SMALL_INTEGER)
{
emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
DONE;
......@@ -5733,7 +5766,8 @@
(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
(clobber (match_scratch:DI 2 "=d"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
&& TARGET_STFIWX && can_create_pseudo_p ()"
&& TARGET_STFIWX && can_create_pseudo_p ()
&& !TARGET_VSX_SMALL_INTEGER"
"#"
""
[(pc)]
......@@ -5818,13 +5852,43 @@
}
DONE;
})
; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
; rather than (set (subreg:SI (reg)) (fix:SI ...))
; because the first makes it clear that operand 0 is not live
; before the instruction.
;; If -mvsx-small-integer, we can represent the FIX operation directly. On
;; older machines, we have to use an UNSPEC to produce a SImode and move it
;; to another location, since SImode is not allowed in vector registers.
(define_insn "*fctiw<u>z_<mode>_smallint"
[(set (match_operand:SI 0 "vsx_register_operand" "=d,wi")
(any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& TARGET_VSX_SMALL_INTEGER"
"@
fctiw<u>z %0,%1
xscvdp<su>xws %x0,%x1"
[(set_attr "type" "fp")])
;; Combiner pattern to prevent moving the result of converting a floating point
;; value to 32-bit integer to GPR in order to save it.
(define_insn_and_split "*fctiw<u>z_<mode>_mem"
[(set (match_operand:SI 0 "memory_operand" "=Z")
(any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
(clobber (match_scratch:SI 2 "=wa"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& TARGET_VSX_SMALL_INTEGER"
"#"
"&& reload_completed"
[(set (match_dup 2)
(any_fix:SI (match_dup 1)))
(set (match_dup 0)
(match_dup 2))])
;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
;; rather than (set (subreg:SI (reg)) (fix:SI ...))
;; because the first makes it clear that operand 0 is not live
;; before the instruction.
(define_insn "fctiwz_<mode>"
[(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
(unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
(unspec:DI [(fix:SI
(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
UNSPEC_FCTIWZ))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"@
......
2017-05-05 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/79038
PR target/79202
PR target/79203
* gcc.target/powerpc/ppc-round3.c: New test.
* gcc.target/powerpc/ppc-round2.c: Update expected code.
2017-05-05 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/80632
......
......@@ -3,18 +3,21 @@
/* { dg-require-effective-target powerpc_p8vector_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
/* { dg-options "-O2 -mcpu=power8" } */
/* { dg-final { scan-assembler-times "fcfid " 2 } } */
/* { dg-final { scan-assembler-times "fcfids " 2 } } */
/* { dg-final { scan-assembler-times "fctiwuz \|xscvdpuxws " 2 } } */
/* { dg-final { scan-assembler-times "fcfid \|xscvsxddp " 2 } } */
/* { dg-final { scan-assembler-times "fcfids \|xscvsxdsp " 2 } } */
/* { dg-final { scan-assembler-times "fctiwz \|xscvdpsxws " 2 } } */
/* { dg-final { scan-assembler-times "mfvsrd " 4 } } */
/* { dg-final { scan-assembler-times "mtvsrwa " 2 } } */
/* { dg-final { scan-assembler-times "mtvsrwz " 2 } } */
/* { dg-final { scan-assembler-not "lwz" } } */
/* { dg-final { scan-assembler-not "lfiwax " } } */
/* { dg-final { scan-assembler-not "lfiwzx " } } */
/* { dg-final { scan-assembler-not "stw" } } */
/* { dg-final { scan-assembler-not "stfiwx " } } */
/* { dg-final { scan-assembler-times "fctiwuz \|xscvdpuxws " 2 } } */
/* { dg-final { scan-assembler-times {\mmfvsrwz\M} 2 } } */
/* { dg-final { scan-assembler-times {\mmtvsrwz\M} 2 } } */
/* { dg-final { scan-assembler-times {\mvupkhsw\M} 2 } } */
/* { dg-final { scan-assembler-times {\mxxpermdi\M} 2 } } */
/* { dg-final { scan-assembler-not {\mmfvsrd\M} } } */
/* { dg-final { scan-assembler-not {\mmtvsrwa\M} } } */
/* { dg-final { scan-assembler-not {\mlwz\M} } } */
/* { dg-final { scan-assembler-not {\mlfiwax\M} } } */
/* { dg-final { scan-assembler-not {\mlfiwzx\M} } } */
/* { dg-final { scan-assembler-not {\mstw\M} } } */
/* { dg-final { scan-assembler-not {\mstfiwx\M} } } */
/* Make sure we don't have loads/stores to the GPR unit. */
double
......
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_p9vector_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
/* { dg-options "-O2 -mcpu=power9" } */
/* { dg-final { scan-assembler-times "fcfid \|xscvsxddp " 2 } } */
/* { dg-final { scan-assembler-times "fcfids \|xscvsxdsp " 2 } } */
/* { dg-final { scan-assembler-times "fctiwz \|xscvdpsxws " 2 } } */
/* { dg-final { scan-assembler-times "fctiwuz \|xscvdpuxws " 2 } } */
/* { dg-final { scan-assembler-times {\mvextsw2d\M} 2 } } */
/* { dg-final { scan-assembler-times {\mxxextractuw\M} 2 } } */
/* { dg-final { scan-assembler-not {\mmfvsrd\M} } } */
/* { dg-final { scan-assembler-not {\mmfvsrwz\M} } } */
/* { dg-final { scan-assembler-not {\mmtvsrwa\M} } } */
/* { dg-final { scan-assembler-not {\mmtvsrwz\M} } } */
/* { dg-final { scan-assembler-not {\mlwz\M} } } */
/* { dg-final { scan-assembler-not {\mlfiwax\M} } } */
/* { dg-final { scan-assembler-not {\mlfiwzx\M} } } */
/* { dg-final { scan-assembler-not {\mstw\M} } } */
/* { dg-final { scan-assembler-not {\mstfiwx\M} } } */
/* Make sure we don't have loads/stores to the GPR unit. */
double
round_double_int (double a)
{
return (double)(int)a;
}
float
round_float_int (float a)
{
return (float)(int)a;
}
double
round_double_uint (double a)
{
return (double)(unsigned int)a;
}
float
round_float_uint (float a)
{
return (float)(unsigned int)a;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment