]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH] combine: Check against CLOBBER in make_compound_operation_int [PR125209]
authorBoudewijn van der Heide <boudewijn@delta-utec.com>
Mon, 11 May 2026 03:46:48 +0000 (21:46 -0600)
committerJeff Law <jeffrey.law@oss.qualcomm.com>
Mon, 11 May 2026 03:46:48 +0000 (21:46 -0600)
In combine_simplify_rtx, CLOBBER can be returned, which is propagated to
make_compound_operation.  When make_compound_operation_int then calls
simplify_subreg, it triggers a gcc_assert, because the mode is neither inner,
nor void. This results in an ICE.

We fix this by checking if we got CLOBBER before calling simplify_subreg from
make_compound_operation and bail out; we return NULL_RTX.

Testcase from the bug report by Zhendong Su.

Bootstrapped and tested on x86_64-linux-gnu.

PR rtl-optimization/125209

gcc/
* combine.cc (make_compound_operation_int): Return NULL_RTX if we got CLOBBER.

gcc/testsuite/
* gcc.dg/pr125209.c: New test.

Signed-off-by: Boudewijn van der Heide <boudewijn@delta-utec.com>
gcc/combine.cc
gcc/testsuite/gcc.dg/pr125209.c [new file with mode: 0644]

index d401ca10083bb37ee9a0a8c0124b2120e0afdce0..f98c36cf020063367b1c1e250efa8acef98fef84 100644 (file)
@@ -8390,6 +8390,12 @@ make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr,
 
        tem = make_compound_operation (inner, subreg_code);
 
+       /* TEM's code might be CLOBBER if combine_simplify_rtx
+          could not transform a subexpression, e.g. a volatile MEM.
+          simplify_subreg cannot be called with clobber, so bail out.  */
+       if (GET_CODE (tem) == CLOBBER)
+         return NULL_RTX;
+
        simplified
          = simplify_subreg (mode, tem, GET_MODE (inner), SUBREG_BYTE (x));
        if (simplified)
diff --git a/gcc/testsuite/gcc.dg/pr125209.c b/gcc/testsuite/gcc.dg/pr125209.c
new file mode 100644 (file)
index 0000000..8fb81cc
--- /dev/null
@@ -0,0 +1,13 @@
+/* PR rtl-optimization/125209 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fno-tree-sink" } */
+
+int a, b;
+volatile unsigned c;
+extern void d(unsigned short);
+int e(long f) { return a ? f : 0; }
+int main() {
+  int g = e(c ^ !b);
+  d(g);
+  return 0;
+}