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 <ja...@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