From 998fd1413977a70cfeb7bf9180f3b462a7731237 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Fri, 9 Mar 2018 18:50:56 +0000 Subject: [PATCH] re PR rtl-optimization/84682 (internal compiler error: Segmentation fault (process_address_1)) 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 | 13 +++++++++++++ gcc/lra-constraints.c | 15 ++++++++++++++- gcc/lra.c | 3 ++- gcc/recog.c | 24 +++++++++++++++++------- gcc/recog.h | 2 +- gcc/testsuite/ChangeLog | 9 ++++++++- gcc/testsuite/gcc.dg/torture/pr84682-1.c | 5 +++++ gcc/testsuite/gcc.dg/torture/pr84682-2.c | 10 ++++++++++ gcc/testsuite/gcc.dg/torture/pr84682-3.c | 8 ++++++++ 9 files changed, 78 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr84682-1.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr84682-2.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr84682-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e999368..4d0b159 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2018-03-09 Alexandre Oliva + + 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 PR target/83712 diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 6bfd465..118b65f 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -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'. */ diff --git a/gcc/lra.c b/gcc/lra.c index 645b166..3e11adf 100644 --- 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); } } diff --git a/gcc/recog.c b/gcc/recog.c index 0e26c93..0a8fa2c 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -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; } } diff --git a/gcc/recog.h b/gcc/recog.h index 4a47ff2..eca6280 100644 --- a/gcc/recog.h +++ b/gcc/recog.h @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b03f7e6..18d987b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2018-03-09 Alexandre Oliva + + 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 PR c++/84724 @@ -62,8 +69,8 @@ PR tree-optimization/84746 * gcc.dg/torture/pr84746.c: New testcase. -2018-03-08 Alexandre Oliva +2018-03-08 Alexandre Oliva 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 index 0000000..b189ed7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr84682-1.c @@ -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 index 0000000..5abda5f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr84682-2.c @@ -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 index 0000000..543a307 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr84682-3.c @@ -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)); +} -- 2.7.4