aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2015-12-18 10:17:14 -0700
committerJeff Law <law@gcc.gnu.org>2015-12-18 10:17:14 -0700
commit3f1d32a5fd3475d1e75452cb5fefe712e043540c (patch)
tree1f9cb33de6c2b56bbe4cfc7761ac15dc58e0038a /gcc
parenta012998e615e7ff43642d4de100cf4e3c369212c (diff)
downloadgcc-3f1d32a5fd3475d1e75452cb5fefe712e043540c.zip
gcc-3f1d32a5fd3475d1e75452cb5fefe712e043540c.tar.gz
gcc-3f1d32a5fd3475d1e75452cb5fefe712e043540c.tar.bz2
[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/ChangeLog5
-rw-r--r--gcc/cse.c7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/pr49847-2.C47
4 files changed, 64 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cb11d02..1caa076 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 cb78a95..4232028 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 6419d0e..57326d1 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 0000000..14f1198
--- /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) {
+ }
+ }