On Sat, Nov 23, 2019 at 2:09 AM Jakub Jelinek <ja...@redhat.com> wrote: > > Hi! > > The following testcase ICEs, because ix86_md_asm_adjust emits an invalid > insn that isn't matched. setcc_qi output is nonimmediate_operand and so is > fine, but the problem is if we decide to do a ZERO_EXTEND, because > zero_extendqidi2 output must be register_operand, but dest could be MEM as > in the testcase. All other cases look ok to me, including if dest_mode is > SImode and DEST_MODE is DImode (with -m32), because we then do zero_extend > into a temporary pseudo and final extension that can cope with nonimmediate > dest, or the movstrictqi which is also into a register. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk and > release branches? > > 2019-11-23 Jakub Jelinek <ja...@redhat.com> > > PR target/92615 > * config/i386/i386.c (ix86_md_asm_adjust): If dest_mode is > GET_MODE (dest), is not QImode, using ZERO_EXTEND and dest is not > register_operand, force x into register before storing it into dest. > Formatting fix. > > * gcc.target/i386/pr92615.c: New test.
OK. Thanks, Uros. > --- gcc/config/i386/i386.c.jj 2019-11-18 12:07:54.673405114 +0100 > +++ gcc/config/i386/i386.c 2019-11-22 14:43:50.895674949 +0100 > @@ -20819,11 +20819,15 @@ ix86_md_asm_adjust (vec<rtx> &outputs, v > { > x = force_reg (dest_mode, const0_rtx); > > - emit_insn (gen_movstrictqi > - (gen_lowpart (QImode, x), destqi)); > + emit_insn (gen_movstrictqi (gen_lowpart (QImode, x), destqi)); > } > else > - x = gen_rtx_ZERO_EXTEND (dest_mode, destqi); > + { > + x = gen_rtx_ZERO_EXTEND (dest_mode, destqi); > + if (dest_mode == GET_MODE (dest) > + && !register_operand (dest, GET_MODE (dest))) > + x = force_reg (dest_mode, x); > + } > } > > if (dest_mode != GET_MODE (dest)) > --- gcc/testsuite/gcc.target/i386/pr92615.c.jj 2019-11-22 14:49:35.878541378 > +0100 > +++ gcc/testsuite/gcc.target/i386/pr92615.c 2019-11-22 14:52:49.658658923 > +0100 > @@ -0,0 +1,45 @@ > +/* PR target/92615 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2" } */ > + > +void *a; > +long long b; > +char c; > + > +void > +foo (void) > +{ > + void *p; > + long long q; > + char r; > + __asm__ ("" : : "r" (&p), "r" (&q), "r" (&r)); > + __asm__ ("" : "=@cca" (p)); > + a = p; > + __asm__ ("" : "=@cca" (q)); > + b = q; > + __asm__ ("" : "=@cca" (r)); > + c = r; > + __asm__ ("" : : "r" (&p), "r" (&q), "r" (&r)); > +} > + > +void > +bar (void) > +{ > + void *p; > + long long q; > + char r; > + __asm__ ("" : "=@cca" (p)); > + a = p; > + __asm__ ("" : "=@cca" (q)); > + b = q; > + __asm__ ("" : "=@cca" (r)); > + c = r; > + __asm__ ("" : : "r" (p), "A" (q), "q" (r)); > +} > + > +void > +baz (void) > +{ > + void *p = (void *) &p; > + __asm__ __volatile__ ("" : "=@ccng" (p) : "r" (1)); > +} > > Jakub >