> Hi! > > xchg instruction is smaller, in some cases much smaller than 3 moves, > (e.g. in the testcase 2 bytes vs. 8 bytes), and is not a performance > disaster, but from Agner Fog tables and > https://stackoverflow.com/questions/45766444/why-is-xchg-reg-reg-a-3-micro-op-instruction-on-modern-intel-architectures > it doesn't seem to be something we'd want to use when optimizing for speed, > at least not on Intel. > > While we have *swap<mode> patterns, those are very unlikely to be triggered > during combine, usually we have different pseudos in there and the actual > need for swapping is only materialized during RA. > > The following patch does it when optimizing the insn for size only. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2019-11-19 Jakub Jelinek <ja...@redhat.com> > > PR target/92549 > * config/i386/i386.md (peephole2 for *swap<mode>): New peephole2. > > * gcc.target/i386/pr92549.c: New test.
Yep, it makes sense to me. I remember poking around xchg a while ago. We used to generate it pre-reload which had various unexpected consequences, but doing it via peephole seems safe. So patch is OK. Honza > > --- gcc/config/i386/i386.md.jj 2019-10-28 22:16:14.583008121 +0100 > +++ gcc/config/i386/i386.md 2019-11-18 17:06:36.050742545 +0100 > @@ -2787,6 +2787,17 @@ > (set_attr "amdfam10_decode" "double") > (set_attr "bdver1_decode" "double")]) > > +(define_peephole2 > + [(set (match_operand:SWI 0 "register_operand") > + (match_operand:SWI 1 "register_operand")) > + (set (match_dup 1) > + (match_operand:SWI 2 "register_operand")) > + (set (match_dup 2) (match_dup 0))] > + "peep2_reg_dead_p (3, operands[0]) > + && optimize_insn_for_size_p ()" > + [(parallel [(set (match_dup 1) (match_dup 2)) > + (set (match_dup 2) (match_dup 1))])]) > + > (define_expand "movstrict<mode>" > [(set (strict_low_part (match_operand:SWI12 0 "register_operand")) > (match_operand:SWI12 1 "general_operand"))] > --- gcc/testsuite/gcc.target/i386/pr92549.c.jj 2019-11-18 > 17:48:35.533177377 +0100 > +++ gcc/testsuite/gcc.target/i386/pr92549.c 2019-11-18 17:49:31.888336444 > +0100 > @@ -0,0 +1,28 @@ > +/* PR target/92549 */ > +/* { dg-do compile } */ > +/* { dg-options "-Os -masm=att" } */ > +/* { dg-final { scan-assembler "xchgl" } } */ > + > +#ifdef __i386__ > +#define R , regparm (2) > +#else > +#define R > +#endif > + > +__attribute__((noipa R)) int > +bar (int a, int b) > +{ > + return b - a + 5; > +} > + > +__attribute__((noipa R)) int > +foo (int a, int b) > +{ > + return 1 + bar (b, a); > +} > + > +int > +main () > +{ > + return foo (39, 3); > +} > > Jakub >