> On 24 Oct 2025, at 06:20, Andrew Pinski <[email protected]> 
> wrote:
> 
> 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 patch to aarch64's aarch64_gen_ccmp_next is needed.
> 
> 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 <[email protected]>
> ---
> gcc/config/aarch64/aarch64.cc            |  6 ++++++
> gcc/config/i386/i386-expand.cc           | 15 +++++++--------
> gcc/testsuite/gcc.dg/torture/pr99782-1.c | 17 +++++++++++++++++
> 3 files changed, 30 insertions(+), 8 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/torture/pr99782-1.c
> 
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> index 6f6dea67e0d..93cf511f0ad 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -28305,6 +28305,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;

I wonder if there’s another way of expressing these modes so that we don’t 
forget to adjust this list in the future if necessary.
But the aarch64 changes are ok anyway.
Thanks,
Kyrill


> +
>   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 a1f1b26f78a..3196d4b600b 100644
> --- a/gcc/config/i386/i386-expand.cc
> +++ b/gcc/config/i386/i386-expand.cc
> @@ -26377,18 +26377,17 @@ 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. */
> +  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);
> 
> +  cmp_mode = op_mode = GET_MODE (op0);
>   icode = code_for_ccmp (op_mode);
> 
>   op0 = prepare_operand (icode, op0, 2, op_mode, cmp_mode, unsignedp);
> 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;
> +    }
> +}
> -- 
> 2.43.0
> 

Reply via email to