re PR rtl-optimization/84682 (internal compiler error: Segmentation fault (process_ad...
authorAlexandre Oliva <aoliva@redhat.com>
Fri, 9 Mar 2018 18:50:56 +0000 (18:50 +0000)
committerJeff Law <law@gcc.gnu.org>
Fri, 9 Mar 2018 18:50:56 +0000 (11:50 -0700)
PR rtl-optimization/84682
* lra-constraints.c (process_address_1): Check is_address flag
for address constraints.
(process_alt_operands): Likewise.
* lra.c (lra_set_insn_recog_data): Pass asm operand locs to
preprocess_constraints.
* recog.h (preprocess_constraints): Add oploc parameter.
Adjust callers.

PR rtl-optimization/84682
* gcc.dg/torture/pr84682-1.c: New.
* gcc.dg/torture/pr84682-2.c: New.
* gcc.dg/torture/pr84682-3.c: New.

From-SVN: r258393

gcc/ChangeLog
gcc/lra-constraints.c
gcc/lra.c
gcc/recog.c
gcc/recog.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr84682-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr84682-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr84682-3.c [new file with mode: 0644]

index e999368274c47203be2b6aba18aa89435f242be6..4d0b1592dafa52636ea6bddec374721892842e54 100644 (file)
@@ -1,3 +1,16 @@
+2018-03-09  Alexandre Oliva <aoliva@redhat.com>
+
+       PR rtl-optimization/84682
+       * lra-constraints.c (process_address_1): Check is_address flag
+       for address constraints.
+       (process_alt_operands): Likewise.
+       * lra.c (lra_set_insn_recog_data): Pass asm operand locs to
+       preprocess_constraints.
+       * recog.h (preprocess_constraints): Add oploc parameter.
+       Adjust callers.
+       * recog.c (preprocess_constraints): Test address_operand for
+       CT_ADDRESS constraints.
+
 2018-03-09  Vladimir Makarov  <vmakarov@redhat.com>
 
        PR target/83712
index 6bfd4659f7b3828d4b862ec236f22ebe942a60d3..118b65f6a23c99cbbfb6721595f645fc555150dc 100644 (file)
@@ -2276,6 +2276,12 @@ process_alt_operands (int only_alternative)
                      break;
 
                    case CT_ADDRESS:
+                     /* An asm operand with an address constraint
+                        that doesn't satisfy address_operand has
+                        is_address cleared, so that we don't try to
+                        make a non-address fit.  */
+                     if (!curr_static_id->operand[nop].is_address)
+                       break;
                      /* If we didn't already win, we can reload the address
                         into a base register.  */
                      if (satisfies_address_constraint_p (op, cn))
@@ -3236,7 +3242,14 @@ process_address_1 (int nop, bool check_only_p,
       && GET_CODE (XEXP (op, 0)) == SCRATCH)
     return false;
 
-  if (insn_extra_address_constraint (cn))
+  if (insn_extra_address_constraint (cn)
+      /* When we find an asm operand with an address constraint that
+        doesn't satisfy address_operand to begin with, we clear
+        is_address, so that we don't try to make a non-address fit.
+        If the asm statement got this far, it's because other
+        constraints are available, and we'll use them, disregarding
+        the unsatisfiable address ones.  */
+      && curr_static_id->operand[nop].is_address)
     decompose_lea_address (&ad, curr_id->operand_loc[nop]);
   /* Do not attempt to decompose arbitrary addresses generated by combine
      for asm operands with loose constraints, e.g 'X'.  */
index 645b166543668c077caf0f26d18b4f8b2a9225d8..3e11adf8ce8258647add30415e31ea47c98f1ae5 100644 (file)
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -1039,7 +1039,8 @@ lra_set_insn_recog_data (rtx_insn *insn)
        {
          operand_alternative *op_alt = XCNEWVEC (operand_alternative,
                                                  nalt * nop);
-         preprocess_constraints (nop, nalt, constraints, op_alt);
+         preprocess_constraints (nop, nalt, constraints, op_alt,
+                                 data->operand_loc);
          setup_operand_alternative (data, op_alt);
        }
     }
index 0e26c93162b1d33631d44d7af2f304e5b5360f21..0a8fa2ce46cf617a2372e7996e2492d1589a3ded 100644 (file)
@@ -2331,15 +2331,20 @@ extract_insn (rtx_insn *insn)
   which_alternative = -1;
 }
 
-/* Fill in OP_ALT_BASE for an instruction that has N_OPERANDS operands,
-   N_ALTERNATIVES alternatives and constraint strings CONSTRAINTS.
-   OP_ALT_BASE has N_ALTERNATIVES * N_OPERANDS entries and CONSTRAINTS
-   has N_OPERANDS entries.  */
+/* Fill in OP_ALT_BASE for an instruction that has N_OPERANDS
+   operands, N_ALTERNATIVES alternatives and constraint strings
+   CONSTRAINTS.  OP_ALT_BASE has N_ALTERNATIVES * N_OPERANDS entries
+   and CONSTRAINTS has N_OPERANDS entries.  OPLOC should be passed in
+   if the insn is an asm statement and preprocessing should take the
+   asm operands into account, e.g. to determine whether they could be
+   addresses in constraints that require addresses; it should then
+   point to an array of pointers to each operand.  */
 
 void
 preprocess_constraints (int n_operands, int n_alternatives,
                        const char **constraints,
-                       operand_alternative *op_alt_base)
+                       operand_alternative *op_alt_base,
+                       rtx **oploc)
 {
   for (int i = 0; i < n_operands; i++)
     {
@@ -2426,6 +2431,9 @@ preprocess_constraints (int n_operands, int n_alternatives,
                      break;
 
                    case CT_ADDRESS:
+                     if (oploc && !address_operand (*oploc[i], VOIDmode))
+                       break;
+
                      op_alt[i].is_address = 1;
                      op_alt[i].cl
                        = (reg_class_subunion
@@ -2470,7 +2478,8 @@ preprocess_insn_constraints (unsigned int icode)
 
   for (int i = 0; i < n_operands; ++i)
     constraints[i] = insn_data[icode].operand[i].constraint;
-  preprocess_constraints (n_operands, n_alternatives, constraints, op_alt);
+  preprocess_constraints (n_operands, n_alternatives, constraints, op_alt,
+                         NULL);
 
   this_target_recog->x_op_alt[icode] = op_alt;
   return op_alt;
@@ -2493,7 +2502,8 @@ preprocess_constraints (rtx_insn *insn)
       int n_entries = n_operands * n_alternatives;
       memset (asm_op_alt, 0, n_entries * sizeof (operand_alternative));
       preprocess_constraints (n_operands, n_alternatives,
-                             recog_data.constraints, asm_op_alt);
+                             recog_data.constraints, asm_op_alt,
+                             NULL);
       recog_op_alt = asm_op_alt;
     }
 }
index 4a47ff23ca95d4426ae61e4b45a1d19e45c574c0..eca62803458c4fdeaebd3247c7e5678cea89875c 100644 (file)
@@ -136,7 +136,7 @@ extern void extract_constrain_insn (rtx_insn *insn);
 extern void extract_constrain_insn_cached (rtx_insn *);
 extern void extract_insn_cached (rtx_insn *);
 extern void preprocess_constraints (int, int, const char **,
-                                   operand_alternative *);
+                                   operand_alternative *, rtx **);
 extern const operand_alternative *preprocess_insn_constraints (unsigned int);
 extern void preprocess_constraints (rtx_insn *);
 extern rtx_insn *peep2_next_insn (int);
index b03f7e617b83093e0fe188ff09c98859c698be03..18d987b46d6abd87c1412caeaf591e7053b9911a 100644 (file)
@@ -1,3 +1,10 @@
+2018-03-09  Alexandre Oliva <aoliva@redhat.com>
+
+       PR rtl-optimization/84682
+       * gcc.dg/torture/pr84682-1.c: New.
+       * gcc.dg/torture/pr84682-2.c: New.
+       * gcc.dg/torture/pr84682-3.c: New.
+
 2018-03-09  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/84724
@@ -62,8 +69,8 @@
        PR tree-optimization/84746
        * gcc.dg/torture/pr84746.c: New testcase.
 
-2018-03-08  Alexandre Oliva <aoliva@redhat.com>
 
+2018-03-08  Alexandre Oliva <aoliva@redhat.com>
        PR debug/84404
        PR debug/84408
        * gcc.dg/graphite/pr84404.c: New.
diff --git a/gcc/testsuite/gcc.dg/torture/pr84682-1.c b/gcc/testsuite/gcc.dg/torture/pr84682-1.c
new file mode 100644 (file)
index 0000000..b189ed7
--- /dev/null
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+
+void b(char a) {
+        asm("" : : "pir" (a));
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr84682-2.c b/gcc/testsuite/gcc.dg/torture/pr84682-2.c
new file mode 100644 (file)
index 0000000..5abda5f
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+int a;
+void b() {
+  float c;
+  for (int d; d;)
+    ;
+  a = c;
+  asm("" : : "pir"(c));
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr84682-3.c b/gcc/testsuite/gcc.dg/torture/pr84682-3.c
new file mode 100644 (file)
index 0000000..543a307
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* This is like pr84682-1.c, but with an extra memory constraint, to
+   check that we don't disable process_address altogether just because
+   of the disabled address constraint.  */
+
+void b(char a) {
+        asm("" : : "pmir" (a));
+}