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]

Re: [PR84682] disregard address constraints on non-addresses


On Fri, Mar 9, 2018 at 6:45 AM, Alexandre Oliva <aoliva@redhat.com> wrote:
> LRA gets very confused when non-addresses are passed as operands to
> asms with address contraints.  Even if other constraints are
> available, and the operand is a perfect fit for them, we'd still
> attempt to process the operand as an address, and fail miserably at
> that.
>
> Truth is, address constraints expect operands allowed by
> address_operand, and we make sure this is the case throughout the
> compiler, even in asm statements.  The problem was that, if multiple
> constraints were available, we wouldn't insist that the operand be
> allowed by address_operand, but we would proceed as if it was,
> regardless of any other constraints.
>
> To address this problem, I've arranged for LRA to attempt to deal with
> address-constrained operands as addresses only when the is_address
> flag is set, and to not set this flag in preprocess_constraints for
> asm operands that are not allowed by address_operand.
>
> Regstrapped on i686- and x86_64-linux-gnu.  Ok to install?
>
> for  gcc/ChangeLog
>
>         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.
>
> for  gcc/testsuite/ChangeLog
>
>         PR rtl-optimization/84682
>         * gcc.dg/torture/pr84682-1.c: New.
>         * gcc.dg/torture/pr84682-2.c: New.
Hi Alexandre,
This test failed because of ICE on various aarch64 targets with below
error message:

Executing on host: /.../build/build-aarch64-none-elf/obj/gcc2/gcc/xgcc
-B/.../build/build-aarch64-none-elf/obj/gcc2/gcc/
/.../build/src/gcc/gcc/testsuite/gcc.dg/torture/pr84682-2.c
-fno-diagnostics-show-caret -fdiagnostics-color=never    -O0   -S
-specs=aem-ve.specs    -mcmodel=small  -o pr84682-2.s    (timeout =
300)
spawn /.../build/build-aarch64-none-elf/obj/gcc2/gcc/xgcc
-B/.../build/build-aarch64-none-elf/obj/gcc2/gcc/
/.../build/src/gcc/gcc/testsuite/gcc.dg/torture/pr84682-2.c
-fno-diagnostics-show-caret -fdiagnostics-color=never -O0 -S
-specs=aem-ve.specs -mcmodel=small -o pr84682-2.s
during RTL pass: expand
/.../build/src/gcc/gcc/testsuite/gcc.dg/torture/pr84682-2.c: In function 'b':
/.../build/src/gcc/gcc/testsuite/gcc.dg/torture/pr84682-2.c:9:3:
internal compiler error: in aarch64_classify_address, at
config/aarch64/aarch64.c:5678
0xfe3c29 aarch64_classify_address
    /.../build/src/gcc/gcc/config/aarch64/aarch64.c:5677
0xfe8be8 aarch64_legitimate_address_hook_p
    /.../build/src/gcc/gcc/config/aarch64/aarch64.c:5958
0xc0149e default_addr_space_legitimate_address_p(machine_mode,
rtx_def*, bool, unsigned char)
    /.../build/src/gcc/gcc/targhooks.c:1476
0xb5b9f1 memory_address_addr_space_p(machine_mode, rtx_def*, unsigned char)
    /.../build/src/gcc/gcc/recog.c:1334
0xb5d278 address_operand(rtx_def*, machine_mode)
    /.../build/src/gcc/gcc/recog.c:1073
0xb5e186 asm_operand_ok(rtx_def*, char const*, char const**)
    /.../build/src/gcc/gcc/recog.c:1816
0x73f440 expand_asm_stmt
    /.../build/src/gcc/gcc/cfgexpand.c:3138
0x742d3c expand_gimple_stmt_1
    /.../build/src/gcc/gcc/cfgexpand.c:3621
0x742d3c expand_gimple_stmt
    /.../build/src/gcc/gcc/cfgexpand.c:3790
0x745c15 expand_gimple_basic_block
    /.../build/src/gcc/gcc/cfgexpand.c:5819
0x749c2f execute
    /.../build/src/gcc/gcc/cfgexpand.c:6425
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.

Not sure if it reveals latent bug or just inconsistent issue with
backend though.

Thanks,
bin
>         * gcc.dg/torture/pr84682-3.c: New.
> ---
>  gcc/lra-constraints.c                    |   15 ++++++++++++++-
>  gcc/lra.c                                |    3 ++-
>  gcc/recog.c                              |   24 +++++++++++++++++-------
>  gcc/recog.h                              |    2 +-
>  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 ++++++++
>  7 files changed, 57 insertions(+), 10 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/lra-constraints.c b/gcc/lra-constraints.c
> index 59b97540d98f..ae55c86f1777 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 a64d8f1a3011..0a251144026c 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 af6a6b01d88c..fa8e261d1476 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 4a47ff23ca95..eca62803458c 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/gcc.dg/torture/pr84682-1.c b/gcc/testsuite/gcc.dg/torture/pr84682-1.c
> new file mode 100644
> index 000000000000..b189ed78cdc3
> --- /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 000000000000..5abda5fd136c
> --- /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 000000000000..543a307d6c12
> --- /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));
> +}
>
>
> --
> Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
> You must be the change you wish to see in the world. -- Gandhi
> Be Free! -- http://FSFLA.org/   FSF Latin America board member
> Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer


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