re PR target/80101 (ICE in store_data_bypass_p, at recog.c:3737)
authorKelvin Nilsen <kelvin@gcc.gnu.org>
Tue, 9 May 2017 01:15:46 +0000 (01:15 +0000)
committerKelvin Nilsen <kelvin@gcc.gnu.org>
Tue, 9 May 2017 01:15:46 +0000 (01:15 +0000)
gcc/testsuite/ChangeLog:

2017-05-08  Kelvin Nilsen  <kelvin@gcc.gnu.org>

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

gcc/ChangeLog:

2017-05-08  Kelvin Nilsen  <kelvin@gcc.gnu.org>

PR target/80101
* config/rs6000/power6.md: Replace store_data_bypass_p calls with
rs6000_store_data_bypass_p in seven define_bypass directives and
in several comments.
* config/rs6000/rs6000-protos.h: Add prototype for
rs6000_store_data_bypass_p function.
* config/rs6000/rs6000.c (rs6000_store_data_bypass_p): New
function implements slightly different (rs6000-specific) semantics
than store_data_bypass_p, returning false rather than aborting
with assertion error when arguments do not satisfy the
requirements of store data bypass.
(rs6000_adjust_cost): Replace six calls of store_data_bypass_p with
rs6000_store_data_bypass_p.

From-SVN: r247777

gcc/ChangeLog
gcc/config/rs6000/power6.md
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr80101-1.c [new file with mode: 0644]

index 2bfe704..4f4af36 100644 (file)
@@ -1,3 +1,19 @@
+2017-05-08  Kelvin Nilsen  <kelvin@gcc.gnu.org>
+
+       PR target/80101
+       * config/rs6000/power6.md: Replace store_data_bypass_p calls with
+       rs6000_store_data_bypass_p in seven define_bypass directives and
+       in several comments.
+       * config/rs6000/rs6000-protos.h: Add prototype for
+       rs6000_store_data_bypass_p function.
+       * config/rs6000/rs6000.c (rs6000_store_data_bypass_p): New
+       function implements slightly different (rs6000-specific) semantics
+       than store_data_bypass_p, returning false rather than aborting
+       with assertion error when arguments do not satisfy the
+       requirements of store data bypass.
+       (rs6000_adjust_cost): Replace six calls of store_data_bypass_p with
+       rs6000_store_data_bypass_p.
+
 2017-05-08  Max Filippov  <jcmvbkbc@gmail.com>
 
        * config/xtensa/xtensa-protos.h
index eb53246..0d81cde 100644 (file)
                   power6-store-update-indexed,\
                   power6-fpstore,\
                   power6-fpstore-update"
-  "store_data_bypass_p")
+  "rs6000_store_data_bypass_p")
 
 (define_insn_reservation "power6-load-ext" 4 ; fx
   (and (eq_attr "type" "load")
                   power6-store-update-indexed,\
                   power6-fpstore,\
                   power6-fpstore-update"
-  "store_data_bypass_p")
+  "rs6000_store_data_bypass_p")
 
 (define_insn_reservation "power6-load-update" 2 ; fx
   (and (eq_attr "type" "load")
                   power6-store-update-indexed,\
                   power6-fpstore,\
                   power6-fpstore-update"
-  "store_data_bypass_p")
+  "rs6000_store_data_bypass_p")
 
 (define_insn_reservation "power6-cntlz" 2
   (and (eq_attr "type" "cntlz")
                   power6-store-update-indexed,\
                   power6-fpstore,\
                   power6-fpstore-update"
-  "store_data_bypass_p")
+  "rs6000_store_data_bypass_p")
 
 (define_insn_reservation "power6-var-rotate" 4
   (and (eq_attr "type" "shift")
                   power6-store-update-indexed,\
                   power6-fpstore,\
                   power6-fpstore-update"
-  "store_data_bypass_p")
+  "rs6000_store_data_bypass_p")
 
 (define_insn_reservation "power6-delayed-compare" 2 ; N/A
   (and (eq_attr "type" "shift")
                   power6-store-update-indexed,\
                   power6-fpstore,\
                   power6-fpstore-update"
-  "store_data_bypass_p")
+  "rs6000_store_data_bypass_p")
 
 (define_insn_reservation "power6-idiv" 44
   (and (eq_attr "type" "div")
 ;                  power6-store-update-indexed,\
 ;                  power6-fpstore,\
 ;                  power6-fpstore-update"
-;  "store_data_bypass_p")
+;  "rs6000_store_data_bypass_p")
 
 (define_insn_reservation "power6-ldiv" 56
   (and (eq_attr "type" "div")
 ;                  power6-store-update-indexed,\
 ;                  power6-fpstore,\
 ;                  power6-fpstore-update"
-;  "store_data_bypass_p")
+;  "rs6000_store_data_bypass_p")
 
 (define_insn_reservation "power6-mtjmpr" 2
   (and (eq_attr "type" "mtjmpr,mfjmpr")
 
 (define_bypass 1 "power6-fp"
                  "power6-fpstore,power6-fpstore-update"
-  "store_data_bypass_p")
+  "rs6000_store_data_bypass_p")
 
 (define_insn_reservation "power6-fpcompare" 8
   (and (eq_attr "type" "fpcompare")
index 74ad733..0344823 100644 (file)
@@ -226,6 +226,7 @@ extern void rs6000_aix_asm_output_dwarf_table_ref (char *);
 extern void get_ppc476_thunk_name (char name[32]);
 extern bool rs6000_overloaded_builtin_p (enum rs6000_builtins);
 extern const char *rs6000_overloaded_builtin_name (enum rs6000_builtins);
+extern int rs6000_store_data_bypass_p (rtx_insn *, rtx_insn *);
 extern HOST_WIDE_INT rs6000_builtin_mask_calculate (void);
 extern void rs6000_asm_output_dwarf_pcrel (FILE *file, int size,
                                           const char *label);
index bac56ab..17b93a6 100644 (file)
@@ -508,6 +508,91 @@ mode_supports_pre_modify_p (machine_mode mode)
          != 0);
 }
 
+/* Given that there exists at least one variable that is set (produced)
+   by OUT_INSN and read (consumed) by IN_INSN, return true iff
+   IN_INSN represents one or more memory store operations and none of
+   the variables set by OUT_INSN is used by IN_INSN as the address of a
+   store operation.  If either IN_INSN or OUT_INSN does not represent
+   a "single" RTL SET expression (as loosely defined by the
+   implementation of the single_set function) or a PARALLEL with only
+   SETs, CLOBBERs, and USEs inside, this function returns false.
+
+   This rs6000-specific version of store_data_bypass_p checks for
+   certain conditions that result in assertion failures (and internal
+   compiler errors) in the generic store_data_bypass_p function and
+   returns false rather than calling store_data_bypass_p if one of the
+   problematic conditions is detected.  */
+
+int
+rs6000_store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
+{
+  rtx out_set, in_set;
+  rtx out_pat, in_pat;
+  rtx out_exp, in_exp;
+  int i, j;
+
+  in_set = single_set (in_insn);
+  if (in_set)
+    {
+      if (MEM_P (SET_DEST (in_set)))
+       {
+         out_set = single_set (out_insn);
+         if (!out_set)
+           {
+             out_pat = PATTERN (out_insn);
+             if (GET_CODE (out_pat) == PARALLEL)
+               {
+                 for (i = 0; i < XVECLEN (out_pat, 0); i++)
+                   {
+                     out_exp = XVECEXP (out_pat, 0, i);
+                     if ((GET_CODE (out_exp) == CLOBBER)
+                         || (GET_CODE (out_exp) == USE))
+                       continue;
+                     else if (GET_CODE (out_exp) != SET)
+                       return false;
+                   }
+               }
+           }
+       }
+    }
+  else
+    {
+      in_pat = PATTERN (in_insn);
+      if (GET_CODE (in_pat) != PARALLEL)
+       return false;
+
+      for (i = 0; i < XVECLEN (in_pat, 0); i++)
+       {
+         in_exp = XVECEXP (in_pat, 0, i);
+         if ((GET_CODE (in_exp) == CLOBBER) || (GET_CODE (in_exp) == USE))
+           continue;
+         else if (GET_CODE (in_exp) != SET)
+           return false;
+
+         if (MEM_P (SET_DEST (in_exp)))
+           {
+             out_set = single_set (out_insn);
+             if (!out_set)
+               {
+                 out_pat = PATTERN (out_insn);
+                 if (GET_CODE (out_pat) != PARALLEL)
+                   return false;
+                 for (j = 0; j < XVECLEN (out_pat, 0); j++)
+                   {
+                     out_exp = XVECEXP (out_pat, 0, j);
+                     if ((GET_CODE (out_exp) == CLOBBER)
+                         || (GET_CODE (out_exp) == USE))
+                       continue;
+                     else if (GET_CODE (out_exp) != SET)
+                       return false;
+                   }
+               }
+           }
+       }
+    }
+  return store_data_bypass_p (out_insn, in_insn);
+}
+
 /* Return true if we have D-form addressing in altivec registers.  */
 static inline bool
 mode_supports_vmx_dform (machine_mode mode)
@@ -33058,14 +33143,14 @@ rs6000_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost,
                   case TYPE_LOAD:
                   case TYPE_CNTLZ:
                     {
-                      if (! store_data_bypass_p (dep_insn, insn))
+                      if (! rs6000_store_data_bypass_p (dep_insn, insn))
                         return get_attr_sign_extend (dep_insn)
                                == SIGN_EXTEND_YES ? 6 : 4;
                       break;
                     }
                   case TYPE_SHIFT:
                     {
-                      if (! store_data_bypass_p (dep_insn, insn))
+                      if (! rs6000_store_data_bypass_p (dep_insn, insn))
                         return get_attr_var_shift (dep_insn) == VAR_SHIFT_YES ?
                                6 : 3;
                       break;
@@ -33076,7 +33161,7 @@ rs6000_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost,
                   case TYPE_EXTS:
                   case TYPE_INSERT:
                     {
-                      if (! store_data_bypass_p (dep_insn, insn))
+                      if (! rs6000_store_data_bypass_p (dep_insn, insn))
                         return 3;
                       break;
                     }
@@ -33085,19 +33170,19 @@ rs6000_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost,
                   case TYPE_FPSTORE:
                     {
                       if (get_attr_update (dep_insn) == UPDATE_YES
-                          && ! store_data_bypass_p (dep_insn, insn))
+                          && ! rs6000_store_data_bypass_p (dep_insn, insn))
                         return 3;
                       break;
                     }
                   case TYPE_MUL:
                     {
-                      if (! store_data_bypass_p (dep_insn, insn))
+                      if (! rs6000_store_data_bypass_p (dep_insn, insn))
                         return 17;
                       break;
                     }
                   case TYPE_DIV:
                     {
-                      if (! store_data_bypass_p (dep_insn, insn))
+                      if (! rs6000_store_data_bypass_p (dep_insn, insn))
                         return get_attr_size (dep_insn) == SIZE_32 ? 45 : 57;
                       break;
                     }
index 3aba70e..597930c 100644 (file)
@@ -1,3 +1,8 @@
+2017-05-08  Kelvin Nilsen  <kelvin@gcc.gnu.org>
+
+       PR target/80101
+       * gcc.target/powerpc/pr80101-1.c: New test.
+
 2017-05-08  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/79930
diff --git a/gcc/testsuite/gcc.target/powerpc/pr80101-1.c b/gcc/testsuite/gcc.target/powerpc/pr80101-1.c
new file mode 100644 (file)
index 0000000..45011d5
--- /dev/null
@@ -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 ();
+}