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
>

Reply via email to