aboutsummaryrefslogtreecommitdiff
path: root/gcc/cse.c
diff options
context:
space:
mode:
authorMikael Pettersson <mikpe@it.uu.se>2014-02-27 20:02:18 +0100
committerJeff Law <law@gcc.gnu.org>2014-02-27 12:02:18 -0700
commit728acca06e395451f2aa26ffbadb8b90af24c90b (patch)
tree54fb29df472b4dafd12a4cf8703a088a272047d7 /gcc/cse.c
parentb076556843574ba6beb9712502af8ed135944b83 (diff)
downloadgcc-728acca06e395451f2aa26ffbadb8b90af24c90b.zip
gcc-728acca06e395451f2aa26ffbadb8b90af24c90b.tar.gz
gcc-728acca06e395451f2aa26ffbadb8b90af24c90b.tar.bz2
re PR rtl-optimization/49847 (NULL deref in fold_rtx (prev_insn_cc0 == NULL))
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. PR rtl-optimization/49847 * g++.dg/pr49847.C: New test. Co-Authored-By: Jeff Law <law@redhat.com> From-SVN: r208203
Diffstat (limited to 'gcc/cse.c')
-rw-r--r--gcc/cse.c24
1 files changed, 21 insertions, 3 deletions
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