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: [PATCH] Fix another match_asm_constraints_1 issue (PR PR inline-asm/85034)


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)


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