Fix another match_asm_constraints_1 issue (PR PR inline-asm/85034)

Message ID 20180322215639.GZ8577@tucnak
State New
Headers show
Series
  • Fix another match_asm_constraints_1 issue (PR PR inline-asm/85034)
Related show

Commit Message

Jakub Jelinek March 22, 2018, 9:56 p.m.
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?

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.


	Jakub

Comments

Richard Biener March 23, 2018, 8:56 a.m. | #1
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)

Patch

--- 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));
+}