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

Reply via email to