https://gcc.gnu.org/g:05b95238be648c9cf8af2516930af6a7b637a2b8
commit r15-1183-g05b95238be648c9cf8af2516930af6a7b637a2b8
Author: Uros Bizjak <ubiz...@gmail.com>
Date:   Tue Jun 11 16:00:31 2024 +0200

    i386: Use CMOV in .SAT_{ADD|SUB} expansion for TARGET_CMOV [PR112600]
    
    For TARGET_CMOV targets emit insn sequence involving conditonal move.
    
    .SAT_ADD:
    
            addl    %esi, %edi
            movl    $-1, %eax
            cmovnc  %edi, %eax
            ret
    
    .SAT_SUB:
    
            subl    %esi, %edi
            movl    $0, %eax
            cmovnc  %edi, %eax
            ret
    
            PR target/112600
    
    gcc/ChangeLog:
    
            * config/i386/i386.md (usadd<mode>3): Emit insn sequence
            involving conditional move for TARGET_CMOVE targets.
            (ussub<mode>3): Ditto.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/i386/pr112600-a.c: Also scan for cmov.
            * gcc.target/i386/pr112600-b.c: Ditto.

Diff:
---
 gcc/config/i386/i386.md                    | 62 +++++++++++++++++++++++++-----
 gcc/testsuite/gcc.target/i386/pr112600-a.c |  2 +-
 gcc/testsuite/gcc.target/i386/pr112600-b.c |  2 +-
 3 files changed, 55 insertions(+), 11 deletions(-)

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index d69bc8d6e482..a64f2ad4f5f0 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -9885,13 +9885,35 @@
   ""
 {
   rtx res = gen_reg_rtx (<MODE>mode);
-  rtx msk = gen_reg_rtx (<MODE>mode);
   rtx dst;
 
   emit_insn (gen_add<mode>3_cc_overflow_1 (res, operands[1], operands[2]));
-  emit_insn (gen_x86_mov<mode>cc_0_m1_neg (msk));
-  dst = expand_simple_binop (<MODE>mode, IOR, res, msk,
-                            operands[0], 1, OPTAB_WIDEN);
+
+  if (TARGET_CMOVE)
+    {
+      rtx cmp = gen_rtx_GEU (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
+                            const0_rtx);
+
+      if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
+       {
+         dst = force_reg (<MODE>mode, operands[0]);
+         emit_insn (gen_movsicc (gen_lowpart (SImode, dst), cmp,
+                                 gen_lowpart (SImode, res), constm1_rtx));
+       }
+       else
+       {
+         dst = operands[0];
+         emit_insn (gen_mov<mode>cc (dst, cmp, res, constm1_rtx));
+       }
+    }
+  else
+    {
+      rtx msk = gen_reg_rtx (<MODE>mode);
+
+      emit_insn (gen_x86_mov<mode>cc_0_m1_neg (msk));
+      dst = expand_simple_binop (<MODE>mode, IOR, res, msk,
+                                operands[0], 1, OPTAB_WIDEN);
+    }
 
   if (!rtx_equal_p (dst, operands[0]))
     emit_move_insn (operands[0], dst);
@@ -9905,14 +9927,36 @@
   ""
 {
   rtx res = gen_reg_rtx (<MODE>mode);
-  rtx msk = gen_reg_rtx (<MODE>mode);
   rtx dst;
 
   emit_insn (gen_sub<mode>_3 (res, operands[1], operands[2]));
-  emit_insn (gen_x86_mov<mode>cc_0_m1_neg (msk));
-  msk = expand_simple_unop (<MODE>mode, NOT, msk, NULL, 1);
-  dst = expand_simple_binop (<MODE>mode, AND, res, msk,
-                            operands[0], 1, OPTAB_WIDEN);
+
+  if (TARGET_CMOVE)
+    {
+      rtx cmp = gen_rtx_GEU (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
+                            const0_rtx);
+
+      if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
+       {
+         dst = force_reg (<MODE>mode, operands[0]);
+         emit_insn (gen_movsicc (gen_lowpart (SImode, dst), cmp,
+                                 gen_lowpart (SImode, res), const0_rtx));
+       }
+       else
+       {
+         dst = operands[0];
+         emit_insn (gen_mov<mode>cc (dst, cmp, res, const0_rtx));
+       }
+    }
+  else
+    {
+      rtx msk = gen_reg_rtx (<MODE>mode);
+
+      emit_insn (gen_x86_mov<mode>cc_0_m1_neg (msk));
+      msk = expand_simple_unop (<MODE>mode, NOT, msk, NULL, 1);
+      dst = expand_simple_binop (<MODE>mode, AND, res, msk,
+                                operands[0], 1, OPTAB_WIDEN);
+    }
 
   if (!rtx_equal_p (dst, operands[0]))
     emit_move_insn (operands[0], dst);
diff --git a/gcc/testsuite/gcc.target/i386/pr112600-a.c 
b/gcc/testsuite/gcc.target/i386/pr112600-a.c
index fa122bc7a3fd..2b0848604512 100644
--- a/gcc/testsuite/gcc.target/i386/pr112600-a.c
+++ b/gcc/testsuite/gcc.target/i386/pr112600-a.c
@@ -1,7 +1,7 @@
 /* PR target/112600 */
 /* { dg-do compile } */
 /* { dg-options "-O2" } */
-/* { dg-final { scan-assembler-times "sbb" 4 } } */
+/* { dg-final { scan-assembler-times "sbb|cmov" 4 } } */
 
 unsigned char
 add_sat_char (unsigned char x, unsigned char y)
diff --git a/gcc/testsuite/gcc.target/i386/pr112600-b.c 
b/gcc/testsuite/gcc.target/i386/pr112600-b.c
index ea14bb9738b7..ac4e26423b6f 100644
--- a/gcc/testsuite/gcc.target/i386/pr112600-b.c
+++ b/gcc/testsuite/gcc.target/i386/pr112600-b.c
@@ -1,7 +1,7 @@
 /* PR target/112600 */
 /* { dg-do compile } */
 /* { dg-options "-O2" } */
-/* { dg-final { scan-assembler-times "sbb" 4 } } */
+/* { dg-final { scan-assembler-times "sbb|cmov" 4 } } */
 
 unsigned char
 sub_sat_char (unsigned char x, unsigned char y)

Reply via email to