This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix another match_asm_constraints_1 issue (PR PR inline-asm/85034)
- From: Richard Biener <rguenther at suse dot de>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: Jeff Law <law at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Date: Fri, 23 Mar 2018 09:56:52 +0100 (CET)
- Subject: Re: [PATCH] Fix another match_asm_constraints_1 issue (PR PR inline-asm/85034)
- References: <20180322215639.GZ8577@tucnak>
On Thu, 22 Mar 2018, Jakub Jelinek wrote:
> Hi!
>
> match_asm_constraints_1 verifies that the mode of input and output
> is the same, with one exception - when input is VOIDmode.
> It isn't correct to allow that blindly VOIDmode CONST_INT/CONST_DOUBLE
> is only ok if the output mode is scalar integer mode, on the testcase below
> output is (reg:SF), while input is (const_int 0) and we emit a move
> from this input to output, which isn't valid RTL.
> Mode mismatch isn't the only problem that can come up, another is e.g.
> if input is some large integer constant, but output is only small mode,
> e.g. unsigned short s; asm volatile ("" : "=r" (s) : "0" (0x12345678abcdef0ULL));
> So, in addition to mode we should also check that for CONST_INT
> trunc_int_for_mode gives the INTVAL. general_operand predicate checks
> already all that and other requirements; if input is a REG (and not hard
> reg), which is the most common case, general_operand is always true for it
> if the reg has the right mode.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK.
Richard.
> 2018-03-22 Jakub Jelinek <jakub@redhat.com>
>
> PR inline-asm/85034
> * function.c (match_asm_constraints_1): Don't optimize if input
> doesn't satisfy general_operand predicate for output's mode.
>
> * gcc.target/i386/pr85034.c: New test.
>
> --- gcc/function.c.jj 2018-03-22 13:31:13.393054131 +0100
> +++ gcc/function.c 2018-03-22 18:44:37.864083638 +0100
> @@ -6661,10 +6661,9 @@ match_asm_constraints_1 (rtx_insn *insn,
> /* Only do the transformation for pseudos. */
> if (! REG_P (output)
> || rtx_equal_p (output, input)
> - || (GET_MODE (input) != VOIDmode
> - && GET_MODE (input) != GET_MODE (output))
> || !(REG_P (input) || SUBREG_P (input)
> - || MEM_P (input) || CONSTANT_P (input)))
> + || MEM_P (input) || CONSTANT_P (input))
> + || !general_operand (input, GET_MODE (output)))
> continue;
>
> /* We can't do anything if the output is also used as input,
> --- gcc/testsuite/gcc.target/i386/pr85034.c.jj 2018-03-22 18:47:32.794168043 +0100
> +++ gcc/testsuite/gcc.target/i386/pr85034.c 2018-03-22 18:47:09.235156562 +0100
> @@ -0,0 +1,11 @@
> +/* PR inline-asm/85034 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +void
> +foo (void)
> +{
> + volatile float a;
> + struct S { char a; } b = { 0 };
> + asm volatile ("" : "=r" (a) : "0ir" (b));
> +}
>
> Jakub
>
>
--
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)