new file mode 100644
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O -ftrivial-auto-var-init=zero -fdump-tree-ssa" } */
+
+int a;
+int foo (void);
+int bar (void);
+
+void
+baz (void)
+{
+ int *b[6];
+ if (foo ())
+ a |= bar ();
+}
+
+/* { dg-final { scan-tree-dump-not "DEFERRED_INIT" "ssa" } } */
@@ -813,6 +813,12 @@ remove_unused_locals (void)
continue;
}
+ if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
+ {
+ have_local_clobbers = true;
+ continue;
+ }
+
if (b)
TREE_USED (b) = true;
@@ -856,7 +862,7 @@ remove_unused_locals (void)
to remove them if they are the only references to a local variable,
but we want to retain them when there's any other. So the first pass
ignores them, and the second pass (if there were any) tries to remove
- them. */
+ them. We do the same for .DEFERRED_INIT. */
if (have_local_clobbers)
FOR_EACH_BB_FN (bb, cfun)
{
@@ -888,6 +894,19 @@ remove_unused_locals (void)
if (b)
TREE_USED (b) = true;
}
+ else if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
+ {
+ tree lhs = gimple_call_lhs (stmt);
+ if (DECL_P (lhs) && !is_used_p (lhs))
+ {
+ unlink_stmt_vdef (stmt);
+ gsi_remove (&gsi, true);
+ release_defs (stmt);
+ continue;
+ }
+ if (b)
+ TREE_USED (b) = true;
+ }
else if (gimple_debug_bind_p (stmt))
{
tree var = gimple_debug_bind_get_var (stmt);