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? 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