https://gcc.gnu.org/g:7ddc204d331ea1637620c8f50abbe8034702ab43
commit r16-5293-g7ddc204d331ea1637620c8f50abbe8034702ab43 Author: Karl Meakin <[email protected]> Date: Tue Sep 30 12:05:00 2025 +0000 aarch64: Fix condition accepted by mov<GPF>cc Apply the same fix from bc11cbff9e648fdda2798bfa2d7151d5cd164b87 ("aarch64: Fix condition accepted by mov<ALLI>cc") to `MOV<GPF>cc`. Fixes ICEs when compiling code such as `cmpbr-4.c` and `cmpbr-5.c` with `+cmpbr`. gcc/ChangeLog: * config/aarch64/aarch64.md(mov<GPF>cc): Accept MODE_CC conditions directly; reject QI/HImode conditions. gcc/testsuite/ChangeLog: * gcc.target/aarch64/cmpbr-4.c: New test. * gcc.target/aarch64/cmpbr-5.c: New test. Diff: --- gcc/config/aarch64/aarch64.md | 48 ++++++++++++++++++++---------- gcc/testsuite/gcc.target/aarch64/cmpbr-4.c | 12 ++++++++ gcc/testsuite/gcc.target/aarch64/cmpbr-5.c | 13 ++++++++ 3 files changed, 58 insertions(+), 15 deletions(-) diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 98c65a74c8ed..e2b8d5d3af96 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -4829,15 +4829,21 @@ (match_operand:GPF 3 "register_operand")))] "" { - rtx ccreg; enum rtx_code code = GET_CODE (operands[1]); - if (code == UNEQ || code == LTGT) FAIL; - ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0), - XEXP (operands[1], 1)); - operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); + rtx ccreg = XEXP (operands[1], 0); + enum machine_mode ccmode = GET_MODE (ccreg); + if (GET_MODE_CLASS (ccmode) == MODE_CC) + gcc_assert (XEXP (operands[1], 1) == const0_rtx); + else if (ccmode == QImode || ccmode == HImode) + FAIL; + else + { + ccreg = aarch64_gen_compare_reg (code, ccreg, XEXP (operands[1], 1)); + operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); + } } ) @@ -4848,15 +4854,21 @@ (match_operand:GPF 3 "register_operand")))] "" { - rtx ccreg; enum rtx_code code = GET_CODE (operands[1]); - if (code == UNEQ || code == LTGT) FAIL; - ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0), - XEXP (operands[1], 1)); - operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); + rtx ccreg = XEXP (operands[1], 0); + enum machine_mode ccmode = GET_MODE (ccreg); + if (GET_MODE_CLASS (ccmode) == MODE_CC) + gcc_assert (XEXP (operands[1], 1) == const0_rtx); + else if (ccmode == QImode || ccmode == HImode) + FAIL; + else + { + ccreg = aarch64_gen_compare_reg (code, ccreg, XEXP (operands[1], 1)); + operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); + } } ) @@ -4867,15 +4879,21 @@ (match_operand:GPI 3 "register_operand")))] "" { - rtx ccreg; enum rtx_code code = GET_CODE (operands[1]); - if (code == UNEQ || code == LTGT) FAIL; - ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0), - XEXP (operands[1], 1)); - operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); + rtx ccreg = XEXP (operands[1], 0); + enum machine_mode ccmode = GET_MODE (ccreg); + if (GET_MODE_CLASS (ccmode) == MODE_CC) + gcc_assert (XEXP (operands[1], 1) == const0_rtx); + else if (ccmode == QImode || ccmode == HImode) + FAIL; + else + { + ccreg = aarch64_gen_compare_reg (code, ccreg, XEXP (operands[1], 1)); + operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); + } } ) diff --git a/gcc/testsuite/gcc.target/aarch64/cmpbr-4.c b/gcc/testsuite/gcc.target/aarch64/cmpbr-4.c new file mode 100644 index 000000000000..e266ce1cc77f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/cmpbr-4.c @@ -0,0 +1,12 @@ +// { dg-do compile } +// { dg-options "-O2" } + +#pragma GCC target "+cmpbr" + +typedef unsigned short Quantum; + +double MagickMax(double x, double y) { return x > y ? x : y; } + +void ConvertRGBToHCL(Quantum red, Quantum green) { + if (red == MagickMax(red, green)) __builtin_abort(); +} diff --git a/gcc/testsuite/gcc.target/aarch64/cmpbr-5.c b/gcc/testsuite/gcc.target/aarch64/cmpbr-5.c new file mode 100644 index 000000000000..049e8c107f6b --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/cmpbr-5.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple -O1" } */ +#pragma GCC target "+cmpbr" +typedef unsigned short us; +__GIMPLE double +f (us x, us y, double a, double b) +{ + bool c; + double d; + c = x == y; + d = c ? a : b; + return d; +}
