From: Andrew Pinski Date: Fri, 24 Oct 2025 04:20:24 +0000 (-0700) Subject: x86/aarch64: Fix compile time hog with ccmp [PR99782] X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e148a21f38327f7c0e1040bf28c676dd0d13ca38;p=thirdparty%2Fgcc.git x86/aarch64: Fix compile time hog with ccmp [PR99782] With ccmp, right now with TER, we hit an O(n^2) explosion in compile time. This can be stopped by returning NULL early in ix86_gen_ccmp_next before we expand the operands which will expand seperately at that point. A similar change aarch64's aarch64_gen_ccmp_next is done. Changes since v1: * v2: Change how cmp_mode is assigned in ix86_gen_ccmp_next. Reworded commit message about aarch64. Bootstrapped and tested on x86_64-linux-gnu and aarch64-linux-gnu. PR middle-end/99782 gcc/ChangeLog: * config/i386/i386-expand.cc (ix86_gen_ccmp_next): Move the check for mode earlier before expand_operands. * config/aarch64/aarch64.cc (aarch64_gen_ccmp_next): Likewise. gcc/testsuite/ChangeLog: * gcc.dg/torture/pr99782-1.c: New test. Signed-off-by: Andrew Pinski --- diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index db914417c1a..0ef22e8e52c 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -28657,6 +28657,12 @@ aarch64_gen_ccmp_next (rtx_insn **prep_seq, rtx_insn **gen_seq, rtx prev, struct expand_operand ops[6]; int aarch64_cond; + /* Exit early for modes that are ot handled to avoid O(n^2) part of expand_operands. */ + op_mode = TYPE_MODE (TREE_TYPE (treeop0)); + if (!(op_mode == QImode || op_mode == HImode || op_mode == SImode || op_mode == DImode + || op_mode == SFmode || op_mode == DFmode)) + return NULL_RTX; + push_to_sequence (*prep_seq); expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index c131f7c44c1..fd9bcaa8541 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -27125,17 +27125,15 @@ ix86_gen_ccmp_next (rtx_insn **prep_seq, rtx_insn **gen_seq, rtx prev, struct expand_operand ops[5]; int dfv; - push_to_sequence (*prep_seq); - expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); - - cmp_mode = op_mode = GET_MODE (op0); + /* Exit early for non integer modes to avoid O(n^2) part of expand_operands. */ + cmp_mode = op_mode = TYPE_MODE (TREE_TYPE (treeop0)); if (!(op_mode == DImode || op_mode == SImode || op_mode == HImode || op_mode == QImode)) - { - end_sequence (); - return NULL_RTX; - } + return NULL_RTX; + + push_to_sequence (*prep_seq); + expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); icode = code_for_ccmp (op_mode); diff --git a/gcc/testsuite/gcc.dg/torture/pr99782-1.c b/gcc/testsuite/gcc.dg/torture/pr99782-1.c new file mode 100644 index 00000000000..76aab18f361 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr99782-1.c @@ -0,0 +1,17 @@ +/* { dg-compile } */ +/* { dg-additional-options "-mapxf" { target { { i?86-*-* x86_64-*-* } && { ! ia32 } } } } */ +/* PR middle-end/99782 */ + +int hb; + +void +w4 (__int128 uv, int ng) +{ + int vh; + + for (vh = 0; vh < 14; ++vh) + { + ++ng; + hb = (hb == uv) && ng; + } +}