[gcc r16-1196] [i386] Improve "mov<mode>cc" expander for DImode immediates [PR120553]
Uros Bizjak
uros@gcc.gnu.org
Thu Jun 5 20:55:17 GMT 2025
https://gcc.gnu.org/g:ed57e5de634eda91f32e0e61724d8f103ef648dd
commit r16-1196-ged57e5de634eda91f32e0e61724d8f103ef648dd
Author: Uros Bizjak <ubizjak@gmail.com>
Date: Thu Jun 5 22:53:35 2025 +0200
[i386] Improve "mov<mode>cc" expander for DImode immediates [PR120553]
"mov<mode>cc" expander uses x86_64_general_operand predicate that limits the
range of immediate operands to 32-bit size. The usage of this predicate
causes ifcvt to force out-of-range immediates to registers when converting
through noce_try_cmove. The testcase:
long long foo (long long c) { return c >= 0 ? 0x400000000ll : -1ll; }
compiles (-O2) to:
foo:
testq %rdi, %rdi
movq $-1, %rax
movabsq $0x400000000, %rdx
cmovns %rdx, %rax
ret
The above testcase can be compiled to a more optimized code without
problematic CMOV instruction if 64-bit immediates are allowed in
"mov<mode>cc" expander:
foo:
movq %rdi, %rax
sarq $63, %rax
btsq $34, %rax
ret
The expander calls the ix86_expand_int_movcc function which internally
sanitizes arguments of emitted logical insns using expand_simple_binop.
The out-of-range immediates are forced to a temporary register just
before the instruction, so the instruction combiner is then able to
synthesize 64-bit BTS instruction.
The code improves even for non-exact-log2 64-bit immediates, e.g.
long long foo (long long c) { return c >= 0 ? 0x400001234ll : -1ll; }
that now compiles to:
foo:
movabsq $0x400001234, %rdx
movq %rdi, %rax
sarq $63, %rax
orq %rdx, %rax
ret
again avoiding problematic CMOV instruction.
PR target/120553
gcc/ChangeLog:
* config/i386/i386.md (mov<mode>cc): Use "general_operand"
predicate for operands 2 and 3 for all modes.
gcc/testsuite/ChangeLog:
* gcc.target/i386/pr120553.c: New test.
Diff:
---
gcc/config/i386/i386.md | 4 ++--
gcc/testsuite/gcc.target/i386/pr120553.c | 6 ++++++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 40b43cf092ac..8eee44756eba 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -26478,8 +26478,8 @@
(define_expand "mov<mode>cc"
[(set (match_operand:SWIM 0 "register_operand")
(if_then_else:SWIM (match_operand 1 "comparison_operator")
- (match_operand:SWIM 2 "<general_operand>")
- (match_operand:SWIM 3 "<general_operand>")))]
+ (match_operand:SWIM 2 "general_operand")
+ (match_operand:SWIM 3 "general_operand")))]
""
"if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
diff --git a/gcc/testsuite/gcc.target/i386/pr120553.c b/gcc/testsuite/gcc.target/i386/pr120553.c
new file mode 100644
index 000000000000..abbf58c67223
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr120553.c
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+long long foo (long long c) { return c >= 0 ? 0x400000000ll : -1ll; }
+
+/* { dg-final { scan-assembler "bts" } } */
More information about the Gcc-cvs
mailing list