aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/cse.c24
-rw-r--r--gcc/doc/tm.texi9
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/pr49847.C7
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
diff --git a/gcc/cse.c b/gcc/cse.c
index cffa553..dba85f1 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -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 (...) {}
+}