]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Move V1TI shift/rotate lowering from expand to pre-reload split on x86_64.
authorRoger Sayle <roger@nextmovesoftware.com>
Sat, 13 Aug 2022 13:52:45 +0000 (14:52 +0100)
committerRoger Sayle <roger@nextmovesoftware.com>
Sat, 13 Aug 2022 13:52:45 +0000 (14:52 +0100)
This patch moves the lowering of 128-bit V1TImode shifts and rotations by
constant bit counts to sequences of SSE operations from the RTL expansion
pass to the pre-reload split pass.  Postponing this splitting of shifts
and rotates enables (will enable) the TImode equivalents of these operations/
instructions to be considered as candidates by the (TImode) STV pass.
Technically, this patch changes the existing expanders to continue to
lower shifts by variable amounts, but constant operands become RTL
instructions, specified by define_insn_and_split that are triggered by
x86_pre_reload_split.  The one minor complication is that logical shifts
by multiples of eight, don't get split, but are handled by existing insn
patterns, such as sse2_ashlv1ti3 and sse2_lshrv1ti3.  There should be no
changes in generated code with this patch, which just adjusts the pass
in which transformations get applied.

2022-08-13  Roger Sayle  <roger@nextmovesoftware.com>
    Uroš Bizjak  <ubizjak@gmail.com>

gcc/ChangeLog
* config/i386/predicates.md (const_0_to_255_not_mul_8_operand):
New predicate for values between 0/1 and 255, not multiples of 8.
* config/i386/sse.md (ashlv1ti3): Delay lowering of logical left
shifts by constant bit counts.
(*ashlvti3_internal): New define_insn_and_split that lowers
logical left shifts by constant bit counts, that aren't multiples
of 8, before reload.
(lshrv1ti3): Delay lowering of logical right shifts by constant.
(*lshrv1ti3_internal): New define_insn_and_split that lowers
logical right shifts by constant bit counts, that aren't multiples
of 8, before reload.
(ashrv1ti3):: Delay lowering of arithmetic right shifts by
constant bit counts.
(*ashrv1ti3_internal): New define_insn_and_split that lowers
arithmetic right shifts by constant bit counts before reload.
(rotlv1ti3): Delay lowering of rotate left by constant.
(*rotlv1ti3_internal): New define_insn_and_split that lowers
rotate left by constant bits counts before reload.
(rotrv1ti3): Delay lowering of rotate right by constant.
(*rotrv1ti3_internal): New define_insn_and_split that lowers
rotate right by constant bits counts before reload.

gcc/config/i386/predicates.md
gcc/config/i386/sse.md

index 064596d9594dd01aa0d757ccad860aae0cf8303f..4f16bb748b550a9bb7b3ca6f0030eeb0d7fde8f6 100644 (file)
   return val <= 255*8 && val % 8 == 0;
 })
 
+;; Match 1 to 255 except multiples of 8
+(define_predicate "const_0_to_255_not_mul_8_operand"
+  (match_code "const_int")
+{
+  unsigned HOST_WIDE_INT val = INTVAL (op);
+  return val <= 255 && val % 8 != 0;
+})
+
 ;; Return true if OP is CONST_INT >= 1 and <= 31 (a valid operand
 ;; for shift & compare patterns, as shifting by 0 does not change flags).
 (define_predicate "const_1_to_31_operand"
index ccd9d002e9315a0ed9f80c14cd1dd1abff79b0e0..b23f07e08c60564c46761b6fd1683a6fda3ec425 100644 (file)
 })
 
 (define_expand "ashlv1ti3"
+  [(set (match_operand:V1TI 0 "register_operand")
+        (ashift:V1TI
+         (match_operand:V1TI 1 "register_operand")
+         (match_operand:QI 2 "general_operand")))]
+  "TARGET_SSE2 && TARGET_64BIT"
+{
+  if (!CONST_INT_P (operands[2]))
+    {
+      ix86_expand_v1ti_shift (ASHIFT, operands);
+      DONE;
+    }
+})
+
+(define_insn_and_split "*ashlv1ti3_internal"
   [(set (match_operand:V1TI 0 "register_operand")
        (ashift:V1TI
         (match_operand:V1TI 1 "register_operand")
-        (match_operand:QI 2 "general_operand")))]
-  "TARGET_SSE2 && TARGET_64BIT"
+        (match_operand:SI 2 "const_0_to_255_not_mul_8_operand")))]
+  "TARGET_SSE2 && TARGET_64BIT
+   && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
 {
   ix86_expand_v1ti_shift (ASHIFT, operands);
   DONE;
         (match_operand:V1TI 1 "register_operand")
         (match_operand:QI 2 "general_operand")))]
   "TARGET_SSE2 && TARGET_64BIT"
+{
+  if (!CONST_INT_P (operands[2]))
+    {
+      ix86_expand_v1ti_shift (LSHIFTRT, operands);
+      DONE;
+    }
+})
+
+(define_insn_and_split "*lshrv1ti3_internal"
+  [(set (match_operand:V1TI 0 "register_operand")
+       (lshiftrt:V1TI
+        (match_operand:V1TI 1 "register_operand")
+        (match_operand:SI 2 "const_0_to_255_not_mul_8_operand")))]
+  "TARGET_SSE2 && TARGET_64BIT
+   && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
 {
   ix86_expand_v1ti_shift (LSHIFTRT, operands);
   DONE;
         (match_operand:V1TI 1 "register_operand")
         (match_operand:QI 2 "general_operand")))]
   "TARGET_SSE2 && TARGET_64BIT"
+{
+  if (!CONST_INT_P (operands[2]))
+    {
+      ix86_expand_v1ti_ashiftrt (operands);
+      DONE;
+    }
+})
+
+
+(define_insn_and_split "*ashrv1ti3_internal"
+  [(set (match_operand:V1TI 0 "register_operand")
+       (ashiftrt:V1TI
+        (match_operand:V1TI 1 "register_operand")
+        (match_operand:SI 2 "const_0_to_255_operand")))]
+  "TARGET_SSE2 && TARGET_64BIT
+   && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
 {
   ix86_expand_v1ti_ashiftrt (operands);
   DONE;
         (match_operand:V1TI 1 "register_operand")
         (match_operand:QI 2 "general_operand")))]
   "TARGET_SSE2 && TARGET_64BIT"
+{
+  if (!CONST_INT_P (operands[2]))
+    {
+      ix86_expand_v1ti_rotate (ROTATE, operands);
+      DONE;
+    }
+})
+
+(define_insn_and_split "*rotlv1ti3_internal"
+  [(set (match_operand:V1TI 0 "register_operand")
+       (rotate:V1TI
+        (match_operand:V1TI 1 "register_operand")
+        (match_operand:SI 2 "const_0_to_255_operand")))]
+  "TARGET_SSE2 && TARGET_64BIT
+   && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
 {
   ix86_expand_v1ti_rotate (ROTATE, operands);
   DONE;
         (match_operand:V1TI 1 "register_operand")
         (match_operand:QI 2 "general_operand")))]
   "TARGET_SSE2 && TARGET_64BIT"
+{
+  if (!CONST_INT_P (operands[2]))
+    {
+      ix86_expand_v1ti_rotate (ROTATERT, operands);
+      DONE;
+    }
+})
+
+(define_insn_and_split "*rotrv1ti3_internal"
+  [(set (match_operand:V1TI 0 "register_operand")
+       (rotatert:V1TI
+        (match_operand:V1TI 1 "register_operand")
+        (match_operand:SI 2 "const_0_to_255_operand")))]
+  "TARGET_SSE2 && TARGET_64BIT
+   && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
 {
   ix86_expand_v1ti_rotate (ROTATERT, operands);
   DONE;