]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR middle-end/91001 (internal compiler error: in extract_insn, at recog...
authorJakub Jelinek <jakub@redhat.com>
Mon, 21 Oct 2019 11:39:53 +0000 (13:39 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 21 Oct 2019 11:39:53 +0000 (13:39 +0200)
Backported from mainline
2019-09-06  Jakub Jelinek  <jakub@redhat.com>

* function.c (assign_parm_find_data_types): Use RECORD_OR_UNION_TYPE_P
before testing TYPE_TRANSPARENT_AGGR.
* calls.c (initialize_argument_information, load_register_parameters):
Likewise.

2019-09-05  Jakub Jelinek  <jakub@redhat.com>

PR middle-end/91001
PR middle-end/91105
PR middle-end/91106
* calls.c (load_register_parameters): For TYPE_TRANSPARENT_AGGR
types, use type of their first field instead of type of
args[i].tree_value.

* gcc.c-torture/compile/pr91001.c: New test.

From-SVN: r277248

gcc/ChangeLog
gcc/calls.c
gcc/function.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr91001.c [new file with mode: 0644]

index 64d4e31be0e1a6f4ae3fe6017b1c80a9dd198307..0f40e8efb6d134cdac8599f42495f950d6c5d137 100644 (file)
@@ -1,6 +1,22 @@
 2019-10-21  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2019-09-06  Jakub Jelinek  <jakub@redhat.com>
+
+       * function.c (assign_parm_find_data_types): Use RECORD_OR_UNION_TYPE_P
+       before testing TYPE_TRANSPARENT_AGGR.
+       * calls.c (initialize_argument_information, load_register_parameters):
+       Likewise.
+
+       2019-09-05  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/91001
+       PR middle-end/91105
+       PR middle-end/91106
+       * calls.c (load_register_parameters): For TYPE_TRANSPARENT_AGGR
+       types, use type of their first field instead of type of
+       args[i].tree_value.
+
        2019-09-02  Jakub Jelinek  <jakub@redhat.com>
 
        PR go/91617
index c8a426800411bc320dd1821e59bb599560c8cb07..56795995650cc52138d04a6a1175dc5480a72e85 100644 (file)
@@ -1971,8 +1971,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
       /* If TYPE is a transparent union or record, pass things the way
         we would pass the first field of the union or record.  We have
         already verified that the modes are the same.  */
-      if ((TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == RECORD_TYPE)
-          && TYPE_TRANSPARENT_AGGR (type))
+      if (RECORD_OR_UNION_TYPE_P (type) && TYPE_TRANSPARENT_AGGR (type))
        type = TREE_TYPE (first_field (type));
 
       /* Decide where to pass this arg.
@@ -2750,6 +2749,9 @@ load_register_parameters (struct arg_data *args, int num_actuals,
          poly_int64 size = 0;
          HOST_WIDE_INT const_size = 0;
          rtx_insn *before_arg = get_last_insn ();
+         tree type = TREE_TYPE (args[i].tree_value);
+         if (RECORD_OR_UNION_TYPE_P (type) && TYPE_TRANSPARENT_AGGR (type))
+           type = TREE_TYPE (first_field (type));
          /* Set non-negative if we must move a word at a time, even if
             just one word (e.g, partial == 4 && mode == DFmode).  Set
             to -1 if we just use a normal move insn.  This value can be
@@ -2762,11 +2764,11 @@ load_register_parameters (struct arg_data *args, int num_actuals,
              gcc_assert (partial % UNITS_PER_WORD == 0);
              nregs = partial / UNITS_PER_WORD;
            }
-         else if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode)
+         else if (TYPE_MODE (type) == BLKmode)
            {
              /* Variable-sized parameters should be described by a
                 PARALLEL instead.  */
-             const_size = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
+             const_size = int_size_in_bytes (type);
              gcc_assert (const_size >= 0);
              nregs = (const_size + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
              size = const_size;
@@ -2893,8 +2895,7 @@ load_register_parameters (struct arg_data *args, int num_actuals,
          if (GET_CODE (reg) == PARALLEL)
            use_group_regs (call_fusage, reg);
          else if (nregs == -1)
-           use_reg_mode (call_fusage, reg,
-                         TYPE_MODE (TREE_TYPE (args[i].tree_value)));
+           use_reg_mode (call_fusage, reg, TYPE_MODE (type));
          else if (nregs > 0)
            use_regs (call_fusage, REGNO (reg), nregs);
        }
index c6e862b3369c78d0561574109a845b895ebfd4df..6c1d27f8a92138c6a8069991e5bcb8a745fe005f 100644 (file)
@@ -2449,8 +2449,7 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm,
   /* If the parm is to be passed as a transparent union or record, use the
      type of the first field for the tests below.  We have already verified
      that the modes are the same.  */
-  if ((TREE_CODE (passed_type) == UNION_TYPE
-       || TREE_CODE (passed_type) == RECORD_TYPE)
+  if (RECORD_OR_UNION_TYPE_P (passed_type)
       && TYPE_TRANSPARENT_AGGR (passed_type))
     passed_type = TREE_TYPE (first_field (passed_type));
 
index e2a268fafafb2460ab2e60f34e90efb1a4e7261a..1963746212e1752ad6c65be690720bae42dc5cec 100644 (file)
@@ -1,6 +1,13 @@
 2019-10-21  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2019-09-05  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/91001
+       PR middle-end/91105
+       PR middle-end/91106
+       * gcc.c-torture/compile/pr91001.c: New test.
+
        2019-09-02  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/91632
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr91001.c b/gcc/testsuite/gcc.c-torture/compile/pr91001.c
new file mode 100644 (file)
index 0000000..4b6a017
--- /dev/null
@@ -0,0 +1,31 @@
+/* PR middle-end/91001 */
+/* PR middle-end/91105 */
+/* PR middle-end/91106 */
+
+struct __attribute__((packed)) S { short b; char c; };
+struct T { short b, c, d; };
+struct __attribute__((packed)) R { int b; char c; };
+union __attribute__((aligned(128), transparent_union)) U { struct S c; } u;
+union __attribute__((aligned(32), transparent_union)) V { struct T c; } v;
+union __attribute__((aligned(32), transparent_union)) W { struct R c; } w;
+void foo (union U);
+void bar (union V);
+void baz (union W);
+
+void
+qux (void)
+{
+  foo (u);
+}
+
+void
+quux (void)
+{
+  bar (v);
+}
+
+void
+corge (void)
+{
+  baz (w);
+}