diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cse.c | 24 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/pr49847.C | 7 |
5 files changed, 50 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8a78716..a20cee3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2014-02-27 Mikael Pettersson <mikpe@it.uu.se> + Jeff Law <law@redhat.com> + + PR rtl-optimization/49847 + * cse.c (fold_rtx) Handle case where cc0 setter and cc0 user + are in different blocks. + * doc/tm.texi (Condition Code Status): Update documention for + relative locations of cc0-setter and cc0-user. + 2014-02-27 Vladimir Makarov <vmakarov@redhat.com> PR target/59222 @@ -3199,9 +3199,27 @@ fold_rtx (rtx x, rtx insn) #ifdef HAVE_cc0 case CC0: - folded_arg = prev_insn_cc0; - mode_arg = prev_insn_cc0_mode; - const_arg = equiv_constant (folded_arg); + /* The cc0-user and cc0-setter may be in different blocks if + the cc0-setter potentially traps. In that case PREV_INSN_CC0 + will have been cleared as we exited the block with the + setter. + + While we could potentially track cc0 in this case, it just + doesn't seem to be worth it given that cc0 targets are not + terribly common or important these days and trapping math + is rarely used. The combination of those two conditions + necessary to trip this situation is exceedingly rare in the + real world. */ + if (!prev_insn_cc0) + { + const_arg = NULL_RTX; + } + else + { + folded_arg = prev_insn_cc0; + mode_arg = prev_insn_cc0_mode; + const_arg = equiv_constant (folded_arg); + } break; #endif diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index f204936..f7024a7 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -5900,8 +5900,13 @@ most instructions do not affect it. The latter category includes most RISC machines. The implicit clobbering poses a strong restriction on the placement of -the definition and use of the condition code, which need to be in adjacent -insns for machines using @code{(cc0)}. This can prevent important +the definition and use of the condition code. In the past the definition +and use were always adjacent. However, recent changes to support trapping +arithmatic may result in the definition and user being in different blocks. +Thus, there may be a @code{NOTE_INSN_BASIC_BLOCK} between them. Additionally, +the definition may be the source of exception handling edges. + +These restrictions can prevent important optimizations on some machines. For example, on the IBM RS/6000, there is a delay for taken branches unless the condition code register is set three instructions earlier than the conditional branch. The instruction diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 128a5f7..be4cb12 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-02-27 Mikael Pettersson <mikpe@it.uu.se> + Jeff Law <law@redhat.com> + + PR rtl-optimization/49847 + * g++.dg/pr49847.C: New test. + 2014-02-27 Marek Polacek <polacek@redhat.com> PR middle-end/59223 diff --git a/gcc/testsuite/g++.dg/pr49847.C b/gcc/testsuite/g++.dg/pr49847.C new file mode 100644 index 0000000..b047713 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr49847.C @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fnon-call-exceptions" } */ +int f (float g) +{ + try { return g >= 0; } + catch (...) {} +} |