S/390: PR78857: Don't use load and test if result is live.

The FP load and test instruction should not be used for a comparison
if the target operand is being used afterwards.  It unfortunately
turns SNaNs into QNaNs.

gcc/ChangeLog:

2017-03-20  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>

	PR target/78857
	* config/s390/s390.md ("cmp<mode>_ccs_0"): Add a clobber of the
	target operand.  A new splitter adds the clobber statement in case
	the target operand is dead anyway.

gcc/testsuite/ChangeLog:

2017-03-20  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>

	PR target/78857
	* gcc.target/s390/load-and-test-fp-1.c: New test.
	* gcc.target/s390/load-and-test-fp-2.c: New test.

From-SVN: r246274
This commit is contained in:
Andreas Krebbel 2017-03-20 09:33:11 +00:00 committed by Andreas Krebbel
parent a4dfaae105
commit e325aba2a7
5 changed files with 71 additions and 2 deletions

View File

@ -1,3 +1,10 @@
2017-03-20 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
PR target/78857
* config/s390/s390.md ("cmp<mode>_ccs_0"): Add a clobber of the
target operand. A new splitter adds the clobber statement in case
the target operand is dead anyway.
2017-03-19 Gerald Pfeifer <gerald@pfeifer.com>
* doc/install.texi (Specific) <sparc-*-linux*>: No longer refer

View File

@ -1284,16 +1284,39 @@
; (TF|DF|SF|TD|DD|SD) instructions
; load and test instructions turn SNaN into QNaN what is not
; acceptable if the target will be used afterwards. On the other hand
; they are quite convenient for implementing comparisons with 0.0. So
; try to enable them via splitter if the value isn't needed anymore.
; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
(define_insn "*cmp<mode>_ccs_0"
[(set (reg CC_REGNUM)
(compare (match_operand:FP 0 "register_operand" "f")
(match_operand:FP 1 "const0_operand" "")))]
(compare (match_operand:FP 0 "register_operand" "f")
(match_operand:FP 1 "const0_operand" "")))
(clobber (match_operand:FP 2 "register_operand" "=0"))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
"lt<xde><bt>r\t%0,%0"
[(set_attr "op_type" "RRE")
(set_attr "type" "fsimp<mode>")])
(define_split
[(set (match_operand 0 "cc_reg_operand")
(compare (match_operand:FP 1 "register_operand")
(match_operand:FP 2 "const0_operand")))]
"TARGET_HARD_FLOAT && REG_P (operands[1]) && dead_or_set_p (insn, operands[1])"
[(parallel
[(set (match_dup 0) (match_dup 3))
(clobber (match_dup 1))])]
{
/* s390_match_ccmode requires the compare to have the same CC mode
as the CC destination register. */
operands[3] = gen_rtx_COMPARE (GET_MODE (operands[0]),
operands[1], operands[2]);
})
; cxtr, cxbr, cdtr, cdbr, cebr, cdb, ceb
(define_insn "*cmp<mode>_ccs"
[(set (reg CC_REGNUM)

View File

@ -1,3 +1,9 @@
2017-03-20 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
PR target/78857
* gcc.target/s390/load-and-test-fp-1.c: New test.
* gcc.target/s390/load-and-test-fp-2.c: New test.
2017-03-18 Paul Thomas <pault@gcc.gnu.org>
PR fortran/79676

View File

@ -0,0 +1,17 @@
/* { dg-do compile } */
/* { dg-options "-O3 -mzarch" } */
/* a is used after the comparison. We cannot use load and test here
since it would turn SNaNs into QNaNs. */
double gl;
double
foo (double dummy, double a)
{
if (a == 0.0)
gl = 1;
return a;
}
/* { dg-final { scan-assembler "cdbr\t" } } */

View File

@ -0,0 +1,16 @@
/* { dg-do compile } */
/* { dg-options "-O3" } */
/* a is not used after the comparison. So we should use load and test
here. */
double gl;
void
bar (double a)
{
if (a == 0.0)
gl = 1;
}
/* { dg-final { scan-assembler "ltdbr\t" } } */