]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
x86/aarch64: Fix compile time hog with ccmp [PR99782]
authorAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Fri, 24 Oct 2025 04:20:24 +0000 (21:20 -0700)
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Fri, 5 Dec 2025 05:41:44 +0000 (21:41 -0800)
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 <andrew.pinski@oss.qualcomm.com>
gcc/config/aarch64/aarch64.cc
gcc/config/i386/i386-expand.cc
gcc/testsuite/gcc.dg/torture/pr99782-1.c [new file with mode: 0644]

index db914417c1a81b572f41024bc6b1931186e6f841..0ef22e8e52c85696002b9b1f89de2774a48f36a6 100644 (file)
@@ -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);
 
index c131f7c44c1103310adde2a2cb99cef1bc2591cc..fd9bcaa8541a79dd6ae230df5f15084e846a25af 100644 (file)
@@ -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 (file)
index 0000000..76aab18
--- /dev/null
@@ -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;
+    }
+}