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 <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 > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)