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:
parent
a4dfaae105
commit
e325aba2a7
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" } } */
|
|
@ -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" } } */
|
Loading…
Reference in New Issue