On Fri, Dec 4, 2020 at 7:26 PM Segher Boessenkool
<seg...@kernel.crashing.org> wrote:
>
> Hi!
>
> On Fri, Dec 04, 2020 at 07:06:45PM +0100, Uros Bizjak wrote:
> > On Fri, Dec 4, 2020 at 6:57 PM Jakub Jelinek <ja...@redhat.com> wrote:
> > >
> > > On Fri, Dec 04, 2020 at 06:53:49PM +0100, Uros Bizjak wrote:
> > > > > > I was trying that first, but it didn't work.  Without the
> > > > > > clobber it actually works right, we don't have the rotate insn with 
> > > > > > the
> > > > > > masking and no clobber, so in the end combiner does add the clobber 
> > > > > > there
> > > > > > (or would fail it the clobber couldn't be added).
> > > > >
> > > > > I was not aware of that detail ...
> > > >
> > > > That said, IMO, it would be better to rewrite other _mask and _mask_1
> > > > patterns that remove useless masking to combine splitter.
> > > > Unfortunately, the combine splitter expects exactly two output
> > > > instructions for some reason, but these patterns split to one
> > > > instruction. Perhaps it is possible to relax this limitation of
> > > > combine splitters and also allow one output instruction.
> > >
> > > I've already checked it in.  Guess I can try to change the combine 
> > > splitters
> > > (can it wait till Monday?) so that they remove the masking when splitting
> > > the insn into two, so that the pre-reload splitters aren't involved.
> >
> > No, I didn't want to burden you with the additional task - the patch
> > is OK as it is. I was just thinking out loud, as I remembered that
> > changing bt patterns to combine splitter regressed one testcase. IIRC
> > combination of two insns blocked better combination of three insns, or
> > something like that.
> >
> > > To turn those pre-reload define_insn_and_splits I'm afraid we'd indeed
> > > need combiner's changes, so that would need to be discussed with Segher
> > > first.
> >
> > Yes, that is the long-term plan. Segher CC'd.
>
> A splitter can *already* split to only one insn.

Unfortunately, the attached patch with the following testcase:

--cut here--
int test (int a, int b)
{
 return a << (b & 31);
}
--cut here--

does not trigger the call to combine_split_insns. The reason in the
following condition:

  /* If we were combining three insns and the result is a simple SET
     with no ASM_OPERANDS that wasn't recognized, try to split it into two
     insns.  There are two ways to do this.  It can be split using a
     machine-specific method (like when you have an addition of a large
     constant) or by combine in the function find_split_point.  */

  if (i1 && insn_code_number < 0 && GET_CODE (newpat) == SET
      && asm_noperands (newpat) < 0)

where i1 is null.

Uros.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 21f0044179f..124495c1c4c 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -10883,50 +10883,35 @@
 })
 
 ;; Avoid useless masking of count operand.
-(define_insn_and_split "*ashl<mode>3_mask"
+(define_split
   [(set (match_operand:SWI48 0 "nonimmediate_operand")
        (ashift:SWI48
          (match_operand:SWI48 1 "nonimmediate_operand")
          (subreg:QI
            (and:SI
-             (match_operand:SI 2 "register_operand" "c,r")
-             (match_operand:SI 3 "const_int_operand")) 0)))
-   (clobber (reg:CC FLAGS_REG))]
+             (match_operand:SI 2 "register_operand")
+             (match_operand:SI 3 "const_int_operand")) 0)))]
   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
-      == GET_MODE_BITSIZE (<MODE>mode)-1
-   && ix86_pre_reload_split ()"
-  "#"
-  "&& 1"
-  [(parallel
-     [(set (match_dup 0)
-          (ashift:SWI48 (match_dup 1)
-                        (match_dup 2)))
-      (clobber (reg:CC FLAGS_REG))])]
-  "operands[2] = gen_lowpart (QImode, operands[2]);"
-  [(set_attr "isa" "*,bmi2")])
+      == GET_MODE_BITSIZE (<MODE>mode)-1"
+  [(set (match_dup 0)
+       (ashift:SWI48 (match_dup 1)
+                     (match_dup 2)))]
+  "operands[2] = gen_lowpart (QImode, operands[2]);")
 
-(define_insn_and_split "*ashl<mode>3_mask_1"
+(define_split
   [(set (match_operand:SWI48 0 "nonimmediate_operand")
        (ashift:SWI48
          (match_operand:SWI48 1 "nonimmediate_operand")
          (and:QI
-           (match_operand:QI 2 "register_operand" "c,r")
-           (match_operand:QI 3 "const_int_operand"))))
-   (clobber (reg:CC FLAGS_REG))]
+           (match_operand:QI 2 "register_operand")
+           (match_operand:QI 3 "const_int_operand"))))]
   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
-      == GET_MODE_BITSIZE (<MODE>mode)-1
-   && ix86_pre_reload_split ()"
-  "#"
-  "&& 1"
-  [(parallel
-     [(set (match_dup 0)
-          (ashift:SWI48 (match_dup 1)
-                        (match_dup 2)))
-      (clobber (reg:CC FLAGS_REG))])]
-  ""
-  [(set_attr "isa" "*,bmi2")])
+      == GET_MODE_BITSIZE (<MODE>mode)-1"
+  [(set (match_dup 0)
+       (ashift:SWI48 (match_dup 1)
+                     (match_dup 2)))])
 
 (define_insn "*bmi2_ashl<mode>3_1"
   [(set (match_operand:SWI48 0 "register_operand" "=r")
@@ -11403,50 +11388,35 @@
   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
 
 ;; Avoid useless masking of count operand.
-(define_insn_and_split "*<shift_insn><mode>3_mask"
+(define_split
   [(set (match_operand:SWI48 0 "nonimmediate_operand")
        (any_shiftrt:SWI48
          (match_operand:SWI48 1 "nonimmediate_operand")
          (subreg:QI
            (and:SI
-             (match_operand:SI 2 "register_operand" "c,r")
-             (match_operand:SI 3 "const_int_operand")) 0)))
-   (clobber (reg:CC FLAGS_REG))]
+             (match_operand:SI 2 "register_operand")
+             (match_operand:SI 3 "const_int_operand")) 0)))]
   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
-      == GET_MODE_BITSIZE (<MODE>mode)-1
-   && ix86_pre_reload_split ()"
-  "#"
-  "&& 1"
-  [(parallel
-     [(set (match_dup 0)
-          (any_shiftrt:SWI48 (match_dup 1)
-                             (match_dup 2)))
-      (clobber (reg:CC FLAGS_REG))])]
-  "operands[2] = gen_lowpart (QImode, operands[2]);"
-  [(set_attr "isa" "*,bmi2")])
+      == GET_MODE_BITSIZE (<MODE>mode)-1"
+  [(set (match_dup 0)
+       (any_shiftrt:SWI48 (match_dup 1)
+                          (match_dup 2)))]
+  "operands[2] = gen_lowpart (QImode, operands[2]);")
 
-(define_insn_and_split "*<shift_insn><mode>3_mask_1"
+(define_split
   [(set (match_operand:SWI48 0 "nonimmediate_operand")
        (any_shiftrt:SWI48
          (match_operand:SWI48 1 "nonimmediate_operand")
          (and:QI
-           (match_operand:QI 2 "register_operand" "c,r")
-           (match_operand:QI 3 "const_int_operand"))))
-   (clobber (reg:CC FLAGS_REG))]
+           (match_operand:QI 2 "register_operand")
+           (match_operand:QI 3 "const_int_operand"))))]
   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
-      == GET_MODE_BITSIZE (<MODE>mode)-1
-   && ix86_pre_reload_split ()"
-  "#"
-  "&& 1"
-  [(parallel
-     [(set (match_dup 0)
-          (any_shiftrt:SWI48 (match_dup 1)
-                             (match_dup 2)))
-      (clobber (reg:CC FLAGS_REG))])]
-  ""
-  [(set_attr "isa" "*,bmi2")])
+      == GET_MODE_BITSIZE (<MODE>mode)-1"
+  [(set (match_dup 0)
+       (any_shiftrt:SWI48 (match_dup 1)
+                          (match_dup 2)))])
 
 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
   [(set (match_operand:<DWI> 0 "register_operand")

Reply via email to