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

Jakub Jelinek jakub@redhat.com
Fri Mar 23 01:38:00 GMT 2018


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.

--- 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



More information about the Gcc-patches mailing list