On Tue, Mar 16, 2021 at 12:52 PM Jakub Jelinek <ja...@redhat.com> wrote: > > On Tue, Mar 16, 2021 at 11:55:01AM +0100, Uros Bizjak wrote: > > Maybe we could simply emit a special form of a ASHIFT pattern, tagged > > with some unspec (similar to e.g. divmod<mode>4_1), and teach > > ix86_split_lea_for_addr to emit it instead? Peephole pass is so late > > in the pass sequence that we won't lose anything. We only need one > > additional SWI48mode ASHIFT pattern with a const123_operand immediate. > > Ok. Any reason not to use just MULT for that and split it back into > ASHIFT during the split pass that follows shortly after peephole2?
Works for me. Uros. > > 2021-03-16 Jakub Jelinek <ja...@redhat.com> > > PR target/99600 > * config/i386/i386-expand.c (ix86_split_lea_for_addr): Emit a MULT > rather than ASHIFT. > * config/i386/i386.md (mult by 1248 into ashift): New splitter. > > * gcc.target/i386/pr99600.c: New test. > > --- gcc/config/i386/i386-expand.c.jj 2021-03-16 11:16:08.487860451 +0100 > +++ gcc/config/i386/i386-expand.c 2021-03-16 12:26:20.331083409 +0100 > @@ -1348,9 +1348,10 @@ ix86_split_lea_for_addr (rtx_insn *insn, > if (regno0 != regno2) > emit_insn (gen_rtx_SET (target, parts.index)); > > - /* Use shift for scaling. */ > - ix86_emit_binop (ASHIFT, mode, target, > - GEN_INT (exact_log2 (parts.scale))); > + /* Use shift for scaling, but emit it as MULT instead > + to avoid it being immediately peephole2 optimized back > + into lea. */ > + ix86_emit_binop (MULT, mode, target, GEN_INT (parts.scale)); > > if (parts.base) > ix86_emit_binop (PLUS, mode, target, parts.base); > --- gcc/config/i386/i386.md.jj 2021-03-16 00:21:12.192422264 +0100 > +++ gcc/config/i386/i386.md 2021-03-16 12:41:27.384022356 +0100 > @@ -5219,6 +5219,18 @@ (define_peephole2 > > DONE; > }) > + > +;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being > +;; peephole2 optimized back into a lea. Split that into the shift during > +;; the following split pass. > +(define_split > + [(set (match_operand:SWI48 0 "general_reg_operand") > + (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 > "const1248_operand"))) > + (clobber (reg:CC FLAGS_REG))] > + "reload_completed" > + [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1))) > + (clobber (reg:CC FLAGS_REG))])] > + "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));") > > ;; Add instructions > > --- gcc/testsuite/gcc.target/i386/pr99600.c.jj 2021-03-16 12:26:50.610747515 > +0100 > +++ gcc/testsuite/gcc.target/i386/pr99600.c 2021-03-16 12:26:50.610747515 > +0100 > @@ -0,0 +1,16 @@ > +/* PR target/99600 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -march=atom" } */ > + > +char a, b; > +long c; > + > +long > +foo (void) > +{ > + if (a) > + c = b == 1 ? 1 << 3 : 1 << 2; > + else > + c = 0; > + return 0; > +} > > > Jakub >