This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] [PR rtl-optimization/49847] Fix ICE in CSE due to cc0-setter and cc0-user in different blocks




Andreas recently reported a bug on aarch64. However, when I first scanned the report I missed the fact that it was aarch64. Instead my brain saw Andreas's m68k-linux.org address and locked in on m68k. Then I looked quickly at the bug and it looked like I was going to need a native system for testing.

So I immediately fired up my old aranym VM and started a build knowing it'd take a *long* time to have something testable.

Of course, I soon realized it was an aarch64 problem, but I left the m68k bootstrap running. Several days later it had ICE'd building the libjava libraries in stage3 :-)

The ICE is more fallout from allowing the cc0-setter and cc0-user to be in different blocks. We saw this in bz49847 and after some discussion decided to fault in fixes as we saw them rather than try and audit all the cc0 code.

This is another instance of that class of problem. Thankfully it's easily fixed. With the cc0-setter and cc0-user in different blocks, PREV_INSN_CC0 will be NULL_RTX when we ask fold_rtx to fold a reference to CC0 resulting in NULL_RTX being returned from fold_rtx.

Naturally the caller isn't prepared to handle that and blows up.

This patch handles that return value in the caller. I've verified the reduced testcase and original testcase now compile without problems with a cross compiler. I've also done an x86_64-linux-gnu bootstrap & regression test (though we know that's of very limited value here). I've got a quickstrap going with this patch on my m68k VM, but it won't finish for a long time.


Installed on the trunk.  No plans to backport to the release branches.



Jeff

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)   {
+   }
+  }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]