Debug stmts are allowed by the verifier before the returns_twice calls.
More importantly, they don't have a lhs, so the current handling of
arg_stmts statements to force them on the edges ICEs.
The following patch just keeps them where they were before.
2024-04-09 Jakub Jelinek <jakub@redhat.com>
PR middle-end/114628
* gimple-lower-bitint.cc (gimple_lower_bitint): Keep debug stmts
before returns_twice calls as is, don't push them into arg_stmts
vector/move to edges.
* gcc.dg/bitint-105.c: New test.
gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (stmt));
while (gsi_stmt (gsi) != stmt)
{
- arg_stmts.safe_push (gsi_stmt (gsi));
- gsi_remove (&gsi, false);
+ if (is_gimple_debug (gsi_stmt (gsi)))
+ gsi_next (&gsi);
+ else
+ {
+ arg_stmts.safe_push (gsi_stmt (gsi));
+ gsi_remove (&gsi, false);
+ }
}
gimple *g;
basic_block bb = NULL;
--- /dev/null
+/* PR middle-end/114628 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-O2 -g" } */
+
+int foo (int);
+#if __BITINT_MAXWIDTH__ >= 129
+__attribute__((returns_twice)) int bar (_BitInt(129) x);
+
+void
+baz (int x, _BitInt(129) y)
+{
+ void *q[] = { &&l1, &&l2 };
+l2:
+ x = foo (foo (3));
+ bar (y);
+ goto *q[x & 1];
+l1:;
+}
+
+void
+qux (int x, _BitInt(129) y)
+{
+ void *q[] = { &&l1, &&l2 };
+l2:
+ x = foo (foo (3));
+ bar (y);
+l1:;
+}
+#endif