aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2024-06-11 16:00:31 +0200
committerUros Bizjak <ubizjak@gmail.com>2024-06-11 18:59:20 +0200
commit05b95238be648c9cf8af2516930af6a7b637a2b8 (patch)
treec303659bbd63f73ac5c06d8e49a9ce41de0f805e
parente7cd8ea1fa3e48404954bb7c06e9bcd603f132dd (diff)
downloadgcc-05b95238be648c9cf8af2516930af6a7b637a2b8.zip
gcc-05b95238be648c9cf8af2516930af6a7b637a2b8.tar.gz
gcc-05b95238be648c9cf8af2516930af6a7b637a2b8.tar.bz2
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.
-rw-r--r--gcc/config/i386/i386.md62
-rw-r--r--gcc/testsuite/gcc.target/i386/pr112600-a.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr112600-b.c2
3 files changed, 55 insertions, 11 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index d69bc8d..a64f2ad 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 fa122bc..2b08486 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 ea14bb9..ac4e264 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)