]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386: Fix ccmp support checks for floating-point modes [PR126148]
authorUros Bizjak <ubizjak@gmail.com>
Wed, 8 Jul 2026 14:50:15 +0000 (16:50 +0200)
committerUros Bizjak <ubizjak@gmail.com>
Wed, 8 Jul 2026 19:49:51 +0000 (21:49 +0200)
The ccmp expansion code allowed DFmode, SFmode and HFmode comparisons
without verifying that the corresponding floating-point instruction
set was available. This could result in attempts to generate ccmp
sequences for comparisons that cannot be emitted as a single instruction
under the selected target options.

Restrict XFmode support to x87 targets, DFmode/SFmode support to
targets with either x87 or SSE with SSE math enabled, and HFmode
support to targets with AVX512FP16 enabled.

PR target/126148

gcc/ChangeLog:

* config/i386/i386-expand.cc (ix86_gen_ccmp_first): Restrict
floating-point modes accepted for ccmp according to the
available floating-point instruction set.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr126148.c: New test.

gcc/config/i386/i386-expand.cc
gcc/testsuite/gcc.target/i386/pr126148.c [new file with mode: 0644]

index fd25b93a566b1d3c5a4c2e5f13c92b3585dfd5e5..a448e470f737c50e455820697c44fb46b98d342d 100644 (file)
@@ -27294,12 +27294,15 @@ ix86_gen_ccmp_first (rtx_insn **prep_seq, rtx_insn **gen_seq,
     op_mode = GET_MODE (op1);
 
   /* We only supports following scalar comparisons that use just 1
-     instruction: DI/SI/QI/HI/DF/SF/HF.
+     instruction: DI/SI/HI/QI/XF/DF/SF/HF.
      Unordered/Ordered compare cannot be correctly identified by
      ccmp so they are not supported.  */
-  if (!(op_mode == DImode || op_mode == SImode || op_mode == HImode
-       || op_mode == QImode || op_mode == DFmode || op_mode == SFmode
-       || op_mode == HFmode)
+  if (!(op_mode == DImode || op_mode == SImode
+       || op_mode == HImode || op_mode == QImode
+       || ((op_mode == XFmode || op_mode == DFmode || op_mode == SFmode)
+           && (TARGET_80387
+               || (SSE_FLOAT_MODE_P (op_mode) && TARGET_SSE_MATH)))
+       || (op_mode == HFmode && TARGET_AVX512FP16))
       || code == ORDERED
       || code == UNORDERED)
     {
diff --git a/gcc/testsuite/gcc.target/i386/pr126148.c b/gcc/testsuite/gcc.target/i386/pr126148.c
new file mode 100644 (file)
index 0000000..f706d30
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -ffast-math -mapxf -mno-80387 -mfpmath=387" } */
+
+int foo (int a, double b) {
+  if (a || b)
+    return 1;
+  return 0;
+}