Ping. https://gcc.gnu.org/pipermail/gcc-patches/2026-August/727263.html Thanks, Kyrill
> On 12 Aug 2026, at 08:32, Kyrylo Tkachov <[email protected]> wrote: > > From: Kyrylo Tkachov <[email protected]> > > This is a rework of previously-approved > https://gcc.gnu.org/pipermail/gcc-patches/2026-August/727208.html > with the FP CCmode logic factored into a helper to make it reusable in patch > 3. > > FCMP and FCMPE set NZCV identically. FCMPE also raises Invalid for a quiet > NaN. When NaNs are not honoured, or floating-point operations cannot trap, > this exception difference is not observable. > > For example, with -O2 -ffinite-math-only: > > int > f (double a, double b) > { > return (a < b) + (a == b); > } > > The ordered and equality comparisons used different condition modes, so > AArch64 emitted two comparisons: > > fcmpe d0, d1 > cset w0, mi > fcmp d0, d1 > cinc w0, w0, eq > > After this patch both operations use one comparison: > > fcmp d0, d1 > cset w0, eq > cinc w0, w0, mi > > Use CCFPmode for ordered comparisons too when the exception is not observable. > Keep CCFPEmode when both NaNs and trapping operations are honoured. Move the > rule into a helper that takes the comparison code and the operand mode, so > that a caller which has no operand rtx can use it. > > Also anchor the existing FP assembly scans. The old expressions could cross > line boundaries and incorrectly implied that FCCMP accepts a zero operand. > > The tests cover finite-math and non-trapping instruction selection, comparison > reuse, and the default trapping behaviour. > > gcc/ > > * config/aarch64/aarch64.cc (aarch64_fp_cc_mode): New function. > Use CCFPmode when the FCMPE exception is not observable. > (aarch64_select_cc_mode): Use it. > > gcc/testsuite/ > > * gcc.target/aarch64/ccmp_1.c: Update and anchor the FP scans. > * gcc.target/aarch64/fccmp_1.c: Update the expected mode. > * gcc.target/aarch64/fccmp_3.c: New test. > > Signed-off-by: Kyrylo Tkachov <[email protected]> > --- > gcc/config/aarch64/aarch64.cc | 60 ++++++++++++---------- > gcc/testsuite/gcc.target/aarch64/ccmp_1.c | 10 ++-- > gcc/testsuite/gcc.target/aarch64/fccmp_1.c | 8 +-- > gcc/testsuite/gcc.target/aarch64/fccmp_3.c | 18 +++++++ > 4 files changed, 61 insertions(+), 35 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/aarch64/fccmp_3.c > > diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc > index 8e1eb2d7e33..0b73146b620 100644 > --- a/gcc/config/aarch64/aarch64.cc > +++ b/gcc/config/aarch64/aarch64.cc > @@ -12674,40 +12674,46 @@ aarch64_emit_call_insn (rtx pat) > return as_a<rtx_call_insn *> (insn); > } > > +/* Return the condition code mode for comparison CODE of MODE floating-point > + operands. FCMP and FCMPE set the same flags, but FCMPE also raises > Invalid > + for a quiet NaN. Use CCFPE only when that exception is observable. */ > + > +static machine_mode > +aarch64_fp_cc_mode (rtx_code code, machine_mode mode) > +{ > + switch (code) > + { > + case EQ: > + case NE: > + case UNORDERED: > + case ORDERED: > + case UNLT: > + case UNLE: > + case UNGT: > + case UNGE: > + case UNEQ: > + return CCFPmode; > + > + case LT: > + case LE: > + case GT: > + case GE: > + case LTGT: > + return HONOR_NANS (mode) && flag_trapping_math ? CCFPEmode : CCFPmode; > + > + default: > + gcc_unreachable (); > + } > +} > + > machine_mode > aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y) > { > machine_mode mode_x = GET_MODE (x); > rtx_code code_x = GET_CODE (x); > > - /* All floating point compares return CCFP if it is an equality > - comparison, and CCFPE otherwise. */ > if (GET_MODE_CLASS (mode_x) == MODE_FLOAT) > - { > - switch (code) > - { > - case EQ: > - case NE: > - case UNORDERED: > - case ORDERED: > - case UNLT: > - case UNLE: > - case UNGT: > - case UNGE: > - case UNEQ: > - return CCFPmode; > - > - case LT: > - case LE: > - case GT: > - case GE: > - case LTGT: > - return CCFPEmode; > - > - default: > - gcc_unreachable (); > - } > - } > + return aarch64_fp_cc_mode (code, mode_x); > > /* Equality comparisons of short modes against zero can be performed > using the TST instruction with the appropriate bitmask. */ > diff --git a/gcc/testsuite/gcc.target/aarch64/ccmp_1.c > b/gcc/testsuite/gcc.target/aarch64/ccmp_1.c > index 9b68c070f9d..e1975c59ba1 100644 > --- a/gcc/testsuite/gcc.target/aarch64/ccmp_1.c > +++ b/gcc/testsuite/gcc.target/aarch64/ccmp_1.c > @@ -86,10 +86,12 @@ f13 (int a, int b) > /* { dg-final { scan-assembler "cmp\t(.)+35" } } */ > > /* { dg-final { scan-assembler-times "\tcmp\tw\[0-9\]+, 0" 4 } } */ > -/* { dg-final { scan-assembler-times "fcmpe\t(?:.)+0\\.0" 1 } } */ > -/* { dg-final { scan-assembler-times "fcmp\t(?:.)+0\\.0" 1 } } */ > +/* With -ffinite-math-only the signalling compares are not needed. */ > +/* { dg-final { scan-assembler-times {\tfcmp\t[sd][0-9]+, #0\.0} 4 } } */ > +/* { dg-final { scan-assembler-not {\tfcmpe\t} } } */ > > /* { dg-final { scan-assembler "adds\t" } } */ > /* { dg-final { scan-assembler-times "\tccmp\t" 11 } } */ > -/* { dg-final { scan-assembler-times "fccmp\t.*0\\.0" 1 } } */ > -/* { dg-final { scan-assembler-times "fccmpe\t.*0\\.0" 1 } } */ > +/* FCCMP has no zero-immediate form, so both operands are registers. */ > +/* { dg-final { scan-assembler-times {\tfccmp\t[sd][0-9]+, [sd][0-9]+,} 2 } > } */ > +/* { dg-final { scan-assembler-not {\tfccmpe\t} } } */ > diff --git a/gcc/testsuite/gcc.target/aarch64/fccmp_1.c > b/gcc/testsuite/gcc.target/aarch64/fccmp_1.c > index 96d6f717136..934bb0e560b 100644 > --- a/gcc/testsuite/gcc.target/aarch64/fccmp_1.c > +++ b/gcc/testsuite/gcc.target/aarch64/fccmp_1.c > @@ -7,8 +7,8 @@ > > /* > ** hf_lt: > -** fcmpe h0, h1 > -** fccmpe h2, h3, 0, mi > +** fcmp h0, h1 > +** fccmp h2, h3, 0, mi > ** cset w0, mi > ** ret > */ > @@ -35,8 +35,8 @@ hf_eq (_Float16 a, _Float16 b, _Float16 c, _Float16 d) > > /* > ** hf_ior: > -** fcmpe h0, h1 > -** fccmpe h2, h3, 8, pl > +** fcmp h0, h1 > +** fccmp h2, h3, 8, pl > ** cset w0, mi > ** ret > */ > diff --git a/gcc/testsuite/gcc.target/aarch64/fccmp_3.c > b/gcc/testsuite/gcc.target/aarch64/fccmp_3.c > new file mode 100644 > index 00000000000..eb1505fc26f > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/fccmp_3.c > @@ -0,0 +1,18 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -ffinite-math-only" } */ > +/* { dg-final { check-function-bodies "**" "" } } */ > + > +/* One condition code mode lets GCC reuse a compare of the same operands. */ > + > +/* > +** cse: > +** fcmp d0, d1 > +** cset w0, eq > +** cinc w0, w0, mi > +** ret > +*/ > +int > +cse (double a, double b) > +{ > + return (a < b) + (a == b); > +} > -- > 2.50.1 (Apple Git-155) >
