diff options
author | Jeff Law <law@redhat.com> | 2015-12-18 10:17:14 -0700 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2015-12-18 10:17:14 -0700 |
commit | 3f1d32a5fd3475d1e75452cb5fefe712e043540c (patch) | |
tree | 1f9cb33de6c2b56bbe4cfc7761ac15dc58e0038a /gcc | |
parent | a012998e615e7ff43642d4de100cf4e3c369212c (diff) | |
download | gcc-3f1d32a5fd3475d1e75452cb5fefe712e043540c.tar.gz |
[PATCH] [PR rtl-optimization/49847] Fix ICE in CSE due to cc0-setter and cc0-user in different blocks
PR rtl-optimization/49847
* cse.c (record_jump_equiv): Handle fold_rtx returning NULL_RTX.
PR rtl-optimization/49847
* g++.dg/pr49847-2.C: New test.
From-SVN: r231821
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cse.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/pr49847-2.C | 47 |
4 files changed, 64 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cb11d02bcce..1caa0760db7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2015-12-18 Jeff Law <law@redhat.com> + + PR rtl-optimization/49847 + * cse.c (record_jump_equiv): Handle fold_rtx returning NULL_RTX. + 2015-12-18 Nathan Sidwell <nathan@acm.org> * config/nvptx/nvptx.c (worker_bcast_name, worker_red_name): Delete. diff --git a/gcc/cse.c b/gcc/cse.c index cb78a95c0b8..4232028f54f 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -3874,6 +3874,13 @@ record_jump_equiv (rtx_insn *insn, bool taken) op0 = fold_rtx (XEXP (XEXP (SET_SRC (set), 0), 0), insn); op1 = fold_rtx (XEXP (XEXP (SET_SRC (set), 0), 1), insn); + /* On a cc0 target the cc0-setter and cc0-user may end up in different + blocks. When that happens the tracking of the cc0-setter via + PREV_INSN_CC0 is spoiled. That means that fold_rtx may return + NULL_RTX. In those cases, there's nothing to record. */ + if (op0 == NULL_RTX || op1 == NULL_RTX) + return; + code = find_comparison_args (code, &op0, &op1, &mode0, &mode1); if (! cond_known_true) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6419d0ee800..57326d19ee9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-12-18 Jeff Law <law@redhat.com> + + PR rtl-optimization/49847 + * g++.dg/pr49847-2.C: New test. + 2015-12-18 H.J. Lu <hongjiu.lu@intel.com> * gcc.dg/vect/pr68305.c (dg-additional-options): Add -mavx2 diff --git a/gcc/testsuite/g++.dg/pr49847-2.C b/gcc/testsuite/g++.dg/pr49847-2.C new file mode 100644 index 00000000000..14f1198fbe8 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr49847-2.C @@ -0,0 +1,47 @@ +/* { dg-do compile { target m68k-*-* } } */ +/* { dg-options "-O2 -mcpu=68060 -fnon-call-exceptions -fPIC -O2 -fpermissive" } */ + +extern "C" { + typedef __java_int jint; + typedef __java_float jfloat; + namespace java { + namespace lang { + class Class; + class Object; + class Throwable; + } +} + } + typedef class java::lang::Class * jclass; + typedef class java::lang::Throwable * jthrowable; + typedef unsigned short _Jv_ushort __attribute__ ((__mode__ (__HI__))); + extern "Java" { + struct _JvObjectPrefix { + }; + } + class java::lang::Object: public _JvObjectPrefix { + }; + union _Jv_word { + jint i; + jfloat f; + }; + class _Jv_MethodBase { + }; + class _Jv_InterpMethod: public _Jv_MethodBase { + private:_Jv_ushort max_stack; + static void run (_Jv_InterpMethod *); + }; + class java::lang::Throwable: public::java::lang::Object { + public:static::java::lang::Class class$; + }; + void _Jv_InterpMethod::run (_Jv_InterpMethod * meth) { + _Jv_word stack[meth->max_stack]; + _Jv_word *sp = stack; + try { + jfloat value2 = ((jfloat) (--sp)->f); + jfloat value1 = ((jfloat) (--sp)->f); + if (value1 > value2) (sp++)->i = (1); + } + catch (java::lang::Throwable * ex) { + } + } |