diff options
author | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2017-03-20 09:33:11 +0000 |
---|---|---|
committer | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2017-03-20 09:33:11 +0000 |
commit | 477999046dcffd943d5c3aa7a67247b73d047a7c (patch) | |
tree | 847bd59b1f3c3df6fda4292ba44e72ac9fff3f69 | |
parent | ef971097148e4d139240ae6ca8d16d21ea448199 (diff) |
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.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@246274 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/s390/load-and-test-fp-1.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/s390/load-and-test-fp-2.c | 16 |
5 files changed, 71 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 95f52b372a3..70c85b3d094 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 164a644b3ae..19daf317c10 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7a8dbc0aef0..ee5893d305a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.target/s390/load-and-test-fp-1.c b/gcc/testsuite/gcc.target/s390/load-and-test-fp-1.c new file mode 100644 index 00000000000..b9d59122242 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/load-and-test-fp-1.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.target/s390/load-and-test-fp-2.c b/gcc/testsuite/gcc.target/s390/load-and-test-fp-2.c new file mode 100644 index 00000000000..7646fdd5def --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/load-and-test-fp-2.c @@ -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" } } */ |