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] PR80101: Fix ICE in store_data_bypass_p


[This is a repost of a patch previously posted on 3/29/2017.
Eric, I hope you might consider that this falls within your scope
of maintenance.  Thanks.]

This problem reports an assertion error when certain rtl expressions
which are not eligible as producers or consumers of a store bypass
optimization are passed as arguments to the store_data_bypass_p
function.  The proposed patch returns false from store_data_bypass_p
rather than terminating with an assertion error.  False indicates that
the passed arguments are not eligible for the store bypass scheduling
optimization.

The patch has been boostrapped without regressions on
powerpc64le-unknown-linux-gnu.  Is this ok for the trunk?

gcc/ChangeLog:

2017-03-29  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	PR target/80101
	* recog.c (store_data_bypass_p): Rather than terminate with
	assertion error, return false if either function argument is not a
	single_set or a PARALLEL with SETs inside.

gcc/testsuite/ChangeLog:

2017-03-29  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	PR target/80101
	* gcc.target/powerpc/pr80101-1.c: New test.


Index: gcc/recog.c
===================================================================
--- gcc/recog.c	(revision 246469)
+++ gcc/recog.c	(working copy)
@@ -3663,9 +3663,12 @@ peephole2_optimize (void)

 /* Common predicates for use with define_bypass.  */

-/* True if the dependency between OUT_INSN and IN_INSN is on the store
-   data not the address operand(s) of the store.  IN_INSN and OUT_INSN
-   must be either a single_set or a PARALLEL with SETs inside.  */
+/* Returns true if the dependency between OUT_INSN and IN_INSN is on
+   the stored data, false if there is no dependency.  Note that a
+   consumer instruction that loads only the address (rather than the
+   value) stored by a producer instruction does not represent a
+   dependency.  If IN_INSN or OUT_INSN are not a single_set or a
+   PARALLEL with SETs inside, this function returns false.  */

 int
 store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
@@ -3701,7 +3704,8 @@ store_data_bypass_p (rtx_insn *out_insn, rtx_insn
             if (GET_CODE (out_exp) == CLOBBER)
               continue;

-            gcc_assert (GET_CODE (out_exp) == SET);
+	    if (GET_CODE (out_exp) != SET)
+	      return false;

             if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set)))
               return false;
@@ -3711,7 +3715,8 @@ store_data_bypass_p (rtx_insn *out_insn, rtx_insn
   else
     {
       in_pat = PATTERN (in_insn);
-      gcc_assert (GET_CODE (in_pat) == PARALLEL);
+      if (GET_CODE (in_pat) != PARALLEL)
+	return false;

       for (i = 0; i < XVECLEN (in_pat, 0); i++)
 	{
@@ -3720,7 +3725,8 @@ store_data_bypass_p (rtx_insn *out_insn, rtx_insn
 	  if (GET_CODE (in_exp) == CLOBBER)
 	    continue;

-	  gcc_assert (GET_CODE (in_exp) == SET);
+	  if (GET_CODE (in_exp) != SET)
+	    return false;

 	  if (!MEM_P (SET_DEST (in_exp)))
 	    return false;
@@ -3734,7 +3740,8 @@ store_data_bypass_p (rtx_insn *out_insn, rtx_insn
           else
             {
               out_pat = PATTERN (out_insn);
-              gcc_assert (GET_CODE (out_pat) == PARALLEL);
+	      if (GET_CODE (out_pat) != PARALLEL)
+		return false;

               for (j = 0; j < XVECLEN (out_pat, 0); j++)
                 {
@@ -3743,7 +3750,8 @@ store_data_bypass_p (rtx_insn *out_insn, rtx_insn
                   if (GET_CODE (out_exp) == CLOBBER)
                     continue;

-                  gcc_assert (GET_CODE (out_exp) == SET);
+		  if (GET_CODE (out_exp) != SET)
+		    return false;

                   if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_exp)))
                     return false;
Index: gcc/testsuite/gcc.target/powerpc/pr80101-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr80101-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr80101-1.c	(working copy)
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power6" } } */
+/* { dg-require-effective-target dfp_hw } */
+/* { dg-options "-mcpu=power6 -mno-sched-epilog -Ofast" } */
+
+/* Prior to resolving PR 80101, this test case resulted in an internal
+   compiler error.  The role of this test program is to assure that
+   dejagnu's "test for excess errors" does not find any.  */
+
+int b;
+
+void e ();
+
+int c ()
+{
+  struct
+  {
+    int a[b];
+  } d;
+  if (d.a[0])
+    e ();
+}


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