99 lines
3.1 KiB
Diff
99 lines
3.1 KiB
Diff
|
|
From b8b3e29e4cceae2bab6e0774b1af994dbe713d97 Mon Sep 17 00:00:00 2001
|
||
|
|
From: zhanghaijian <z.zhanghaijian@huawei.com>
|
||
|
|
Date: Thu, 15 Jul 2021 09:13:11 +0800
|
||
|
|
Subject: [PATCH 10/13] [Backport]tree-optimization/94963 - avoid bogus uninit
|
||
|
|
warning with store-motion
|
||
|
|
|
||
|
|
Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=371905d12259c180efb9b1f1b5716e969feb60f9
|
||
|
|
|
||
|
|
Eliding the load for store-motion causes an uninitialized variable
|
||
|
|
flowing into the loop, conditionally initialized and used. The
|
||
|
|
uninit warning cannot relate the flag used to guard the initialization
|
||
|
|
and use with the actual initialization so the following robustifies
|
||
|
|
the previous approach of marking the conditional store as not to
|
||
|
|
be warned on by instead initializing the variable on loop entry
|
||
|
|
from an uninitialized variable we mark as not to be warned for.
|
||
|
|
|
||
|
|
diff --git a/gcc/testsuite/gcc.dg/pr94963.c b/gcc/testsuite/gcc.dg/pr94963.c
|
||
|
|
new file mode 100644
|
||
|
|
index 00000000000..09c0524fb3a
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.dg/pr94963.c
|
||
|
|
@@ -0,0 +1,35 @@
|
||
|
|
+/* { dg-do compile } */
|
||
|
|
+/* { dg-options "-O2 -Wall" } */
|
||
|
|
+
|
||
|
|
+typedef struct
|
||
|
|
+{
|
||
|
|
+ int p1;
|
||
|
|
+ int p2;
|
||
|
|
+ int p3;
|
||
|
|
+} P;
|
||
|
|
+struct S
|
||
|
|
+{
|
||
|
|
+ int field;
|
||
|
|
+};
|
||
|
|
+extern int v2;
|
||
|
|
+extern void foo (struct S *map);
|
||
|
|
+static struct S var;
|
||
|
|
+const P *pv;
|
||
|
|
+int ps;
|
||
|
|
+void
|
||
|
|
+f (void)
|
||
|
|
+{
|
||
|
|
+ if (pv != 0)
|
||
|
|
+ for (const P *ph = pv; ph < &pv[ps]; ++ph)
|
||
|
|
+ switch (ph->p1)
|
||
|
|
+ {
|
||
|
|
+ case 1:
|
||
|
|
+ v2 = ph->p2;
|
||
|
|
+ break;
|
||
|
|
+ case 2:
|
||
|
|
+ var.field = ph->p3;
|
||
|
|
+ break;
|
||
|
|
+ }
|
||
|
|
+ if (var.field != 0) /* { dg-bogus "uninitialized" } */
|
||
|
|
+ foo (&var);
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
|
||
|
|
index 8c33735b1fa..d74a46ef352 100644
|
||
|
|
--- a/gcc/tree-ssa-loop-im.c
|
||
|
|
+++ b/gcc/tree-ssa-loop-im.c
|
||
|
|
@@ -1994,8 +1994,6 @@ execute_sm_if_changed (edge ex, tree mem, tree tmp_var, tree flag,
|
||
|
|
gsi = gsi_start_bb (then_bb);
|
||
|
|
/* Insert actual store. */
|
||
|
|
stmt = gimple_build_assign (unshare_expr (mem), tmp_var);
|
||
|
|
- /* Make sure to not warn about maybe-uninit uses of tmp_var here. */
|
||
|
|
- gimple_set_no_warning (stmt, true);
|
||
|
|
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
|
||
|
|
|
||
|
|
edge e1 = single_succ_edge (new_bb);
|
||
|
|
@@ -2149,13 +2147,19 @@ execute_sm (class loop *loop, vec<edge> exits, im_mem_ref *ref)
|
||
|
|
store then. */
|
||
|
|
if ((!always_stored && !multi_threaded_model_p)
|
||
|
|
|| (ref->loaded && bitmap_bit_p (ref->loaded, loop->num)))
|
||
|
|
+ load = gimple_build_assign (tmp_var, unshare_expr (ref->mem.ref));
|
||
|
|
+ else
|
||
|
|
{
|
||
|
|
- load = gimple_build_assign (tmp_var, unshare_expr (ref->mem.ref));
|
||
|
|
- lim_data = init_lim_data (load);
|
||
|
|
- lim_data->max_loop = loop;
|
||
|
|
- lim_data->tgt_loop = loop;
|
||
|
|
- gsi_insert_before (&gsi, load, GSI_SAME_STMT);
|
||
|
|
+ /* If not emitting a load mark the uninitialized state on the
|
||
|
|
+ loop entry as not to be warned for. */
|
||
|
|
+ tree uninit = create_tmp_reg (TREE_TYPE (tmp_var));
|
||
|
|
+ TREE_NO_WARNING (uninit) = 1;
|
||
|
|
+ load = gimple_build_assign (tmp_var, uninit);
|
||
|
|
}
|
||
|
|
+ lim_data = init_lim_data (load);
|
||
|
|
+ lim_data->max_loop = loop;
|
||
|
|
+ lim_data->tgt_loop = loop;
|
||
|
|
+ gsi_insert_before (&gsi, load, GSI_SAME_STMT);
|
||
|
|
|
||
|
|
if (multi_threaded_model_p)
|
||
|
|
{
|
||
|
|
--
|
||
|
|
2.21.0.windows.1
|
||
|
|
|