i386: Use SDWIM mode iterator for abs and maxmin [PR97873]
authorUros Bizjak <ubizjak@gmail.com>
Thu, 26 Nov 2020 08:47:01 +0000 (09:47 +0100)
committerUros Bizjak <ubizjak@gmail.com>
Thu, 26 Nov 2020 08:50:33 +0000 (09:50 +0100)
Generate special double mode sequence also for QImode and HImode.

Without QImode and HImode patterns, middle-end extends operands to SImode
and emits SImode conditional move instruction with paradoxical SImode output
register.  This form is not recognized by STV pass, but a single abs with
input operand in a register would not be converted anyway due to relatively
high register conversion cost.

2020-11-26  Uroš Bizjak  <ubizjak@gmail.com>

PR target/97873

gcc/
* config/i386/i386.md (abs<mode>2): Use SDWIM mode iterator.
(*abs<mode>2_1): Use SWI mode iterator.

(<maxmin:code><mode>3): Use SDWIM mode iterator.
(*<maxmin:code><mode>3_1): Use SWI mode iterator.

gcc/testsuite/
* gcc.target/i386/pr97873-3.c: New test.

gcc/config/i386/i386.md
gcc/testsuite/gcc.target/i386/pr97873-3.c [new file with mode: 0644]

index 943a1c98a391a9dd4d7185dfe875038c87b7b114..7c25ae2078d1337d505c82fc49e65b11617cd4f1 100644 (file)
 
 (define_expand "abs<mode>2"
   [(parallel
-    [(set (match_operand:SWI48DWI 0 "register_operand")
-         (abs:SWI48DWI
-           (match_operand:SWI48DWI 1 "general_operand")))
+    [(set (match_operand:SDWIM 0 "register_operand")
+         (abs:SDWIM
+           (match_operand:SDWIM 1 "general_operand")))
      (clobber (reg:CC FLAGS_REG))])]
   "TARGET_CMOVE"
 {
 })
 
 (define_insn_and_split "*abs<mode>2_1"
-  [(set (match_operand:SWI48 0 "register_operand")
-       (abs:SWI48
-         (match_operand:SWI48 1 "general_operand")))
+  [(set (match_operand:SWI 0 "register_operand")
+       (abs:SWI
+         (match_operand:SWI 1 "general_operand")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_CMOVE
    && ix86_pre_reload_split ()"
   [(parallel
      [(set (reg:CCGOC FLAGS_REG)
           (compare:CCGOC
-            (neg:SWI48 (match_dup 1))
+            (neg:SWI (match_dup 1))
             (const_int 0)))
       (set (match_dup 2)
-          (neg:SWI48 (match_dup 1)))])
+          (neg:SWI (match_dup 1)))])
    (set (match_dup 0)
-        (if_then_else:SWI48
+        (if_then_else:SWI
          (ge (reg:CCGOC FLAGS_REG) (const_int 0))
          (match_dup 2)
          (match_dup 1)))]
 
 (define_expand "<code><mode>3"
   [(parallel
-    [(set (match_operand:SWI48DWI 0 "register_operand")
-         (maxmin:SWI48DWI
-           (match_operand:SWI48DWI 1 "register_operand")
-           (match_operand:SWI48DWI 2 "general_operand")))
+    [(set (match_operand:SDWIM 0 "register_operand")
+         (maxmin:SDWIM
+           (match_operand:SDWIM 1 "register_operand")
+           (match_operand:SDWIM 2 "general_operand")))
      (clobber (reg:CC FLAGS_REG))])]
   "TARGET_CMOVE")
 
 })
 
 (define_insn_and_split "*<code><mode>3_1"
-  [(set (match_operand:SWI48 0 "register_operand")
-       (maxmin:SWI48
-         (match_operand:SWI48 1 "register_operand")
-         (match_operand:SWI48 2 "general_operand")))
+  [(set (match_operand:SWI 0 "register_operand")
+       (maxmin:SWI
+         (match_operand:SWI 1 "register_operand")
+         (match_operand:SWI 2 "general_operand")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_CMOVE
    && ix86_pre_reload_split ()"
   "#"
   "&& 1"
   [(set (match_dup 0)
-       (if_then_else:SWI48 (match_dup 3)
+       (if_then_else:SWI (match_dup 3)
          (match_dup 1)
          (match_dup 2)))]
 {
diff --git a/gcc/testsuite/gcc.target/i386/pr97873-3.c b/gcc/testsuite/gcc.target/i386/pr97873-3.c
new file mode 100644 (file)
index 0000000..e682f14
--- /dev/null
@@ -0,0 +1,27 @@
+/* PR target/97873 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -mno-sse3 -mtune=generic" } */
+
+short test_absw (short x)
+{
+  return (x < 0) ? -x : x;
+}
+
+short test_sminw (short x, short y)
+{
+  return (x < y) ? x : y;
+}
+
+/* { dg-final { scan-assembler-not "movswl" } } */
+
+char test_absb (char x)
+{
+  return (x < 0) ? -x : x;
+}
+
+char test_sminb (char x, char y)
+{
+  return (x < y) ? x : y;
+}
+
+/* { dg-final { scan-assembler-not "movsbl" } } */