From patchwork Fri Feb 4 13:49:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 50797 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B79673858C3A for ; Fri, 4 Feb 2022 13:49:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B79673858C3A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1643982586; bh=VmBS/Bdam6bveDWNxLZB5jAwBHc3CagVbeD7fGNvWnY=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=FilwrtfYbdS3q9XPWkYzvWelZD0fWQ+9Ewld7BgMUayLu70lT97VG7ske3kzgFEG9 XgGApbXxeuKOU3pt2o+EsUN6ONqg0ZpvCWr/f2vFD4FwycAfFcDaI1Sl47GypWpNni Lr/t17xKLgiKFPegaj0QtlR6i5OAz/nvFcYM0FcE= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by sourceware.org (Postfix) with ESMTPS id 7040E3858D20 for ; Fri, 4 Feb 2022 13:49:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7040E3858D20 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 467021F382; Fri, 4 Feb 2022 13:49:14 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 25D7C13A96; Fri, 4 Feb 2022 13:49:14 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id TtAMCNou/WGbegAAMHmgww (envelope-from ); Fri, 04 Feb 2022 13:49:14 +0000 Date: Fri, 4 Feb 2022 14:49:13 +0100 (CET) To: gcc-patches@gcc.gnu.org Subject: [PATCH 1/4][RFC] middle-end/90348 - add explicit birth MIME-Version: 1.0 Message-Id: <20220204134914.25D7C13A96@imap2.suse-dmz.suse.de> X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Richard Biener via Gcc-patches From: Richard Biener Reply-To: Richard Biener Cc: Jakub Jelinek , matz@suse.de Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This adds explicit variable birth CLOBBERs in an attempt to fix PR90348 and duplicates. The birth / death CLOBBER pairs are used to compute liveness and conflicts for stack variable coalescing where the lack of an explicit birth but instead use of first mention causes misrepresentation of variable life ranges when optimization moves the first mention upwards the original birth point at the variables bind expression start. Birth CLOBBERs are represented as traditional CLOBBERs with all the accompaning effect on optimization. While they do not serve as a barrier for address mentions they act as barrier for the actual accesses which is enough for determining conflicts in the context of stack slot sharing. The birth CLOBBERs are distinguished from death CLOBBERs by setting CLOBBER_MARKS_BIRTH using the private_flag on the CONSTRUCTOR node and amend the CLOBBER_MARK_EOL marked clobbers introduced earlier. The patch changes how we handle stack variables that are not marked with CLOBBERs. For those the first mention started live which then lasted upon function exit which means effectively all not marked variables conflicted with each other variable. This property is best represented by an extra flag rather than the full conflict bitmap which is what the patch introduces with conflicts_represented which is cleared at start and set to true once we visit the first birth CLOBBER. From that on we assume all variable accesses are properly fenced by birth/death CLOBBERs. Variables without explicit births will not take part in stack slot sharing after this change. Currently birth CLOBBERs are added when gimplification adds corresponding end-of-life CLOBBERs, during bind and target expression gimplification. Generally inserting births at DECL_EXPRs is more precise so we also do it there (also noting not all such variables are mentioned in BINDs). Avoiding redundant births is on the TOOD list and might also remove the need for the warn_switch_unreachable_r hunk. This is the meat of the PR90348 fix, the following 3 patches perform testcase adjustments and followup fixes to avoid regressions. Bootstrapped on x86_64-unknown-linux-gnu - re-testing in progress. Any comments? I have mixed feelings with proposing this for GCC 12 but like to hear from others as well. I didn't try to evaluate the quality of stack slot sharing before/after this change besides fixing the testsuite fallout (we have a few testcases checking for specific instances). Thanks, Richard. 2022-02-01 Richard Biener PR middle-end/90348 PR middle-end/103006 * tree-core.h (clobber_kind): Add CLOBBER_BIRTH. * gimplify.cc (gimplify_bind_expr): Also add birth CLOBBERs. (gimplify_target_expr): Likewise. (gimplify_decl_expr): Likewise. (warn_switch_unreachable_r): Do not treat birth CLOBBERs as real stmt - they get added at BIND starts but that's before the case labels. * tree-pretty-print.cc (dump_generic_node): Mark birth CLOBBERs. * cfgexpand.cc (stack_var::conflicts_represented): New. (add_stack_var): Initialize conflicts_represented. (add_stack_var_conflict): Assert the conflicts for the vars are represented. (stack_var_conflict_p): Honor conflicts_represented flag. (visit_op): Remove. (visit_conflict): Likewise. (add_scope_conflicts_1): Simplify by only considering birth and death CLOBBERs. (add_scope_conflicts): Adjust comment. (add_stack_protection_conflicts): Only add conflicts for variables that have them represented. * gcc.dg/torture/pr103006-1.c: New testcase. * gcc.dg/torture/pr103006-2.c: Likewise. * gcc.dg/torture/pr90348.c: Likewise. --- gcc/cfgexpand.cc | 157 +++++++++------------- gcc/gimplify.cc | 83 +++++++++++- gcc/testsuite/gcc.dg/torture/pr103006-1.c | 27 ++++ gcc/testsuite/gcc.dg/torture/pr103006-2.c | 29 ++++ gcc/testsuite/gcc.dg/torture/pr90348.c | 40 ++++++ gcc/tree-core.h | 2 + gcc/tree-pretty-print.cc | 4 +- 7 files changed, 244 insertions(+), 98 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr103006-1.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr103006-2.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr90348.c diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc index d51af2e3084..02467874996 100644 --- a/gcc/cfgexpand.cc +++ b/gcc/cfgexpand.cc @@ -319,6 +319,10 @@ public: size, the alignment for this partition. */ unsigned int alignb; + /* Whether this variable has conflicts represented in the CONFLICTS + bitmap. If not, it conflicts with all other stack variables. */ + bool conflicts_represented; + /* The partition representative. */ size_t representative; @@ -479,7 +483,8 @@ add_stack_var (tree decl, bool really_expand) v->representative = stack_vars_num; v->next = EOC; - /* All variables initially conflict with no other. */ + /* All variables initially conflict with each other. */ + v->conflicts_represented = false; v->conflicts = NULL; /* Ensure that this decl doesn't get put onto the list twice. */ @@ -497,6 +502,7 @@ add_stack_var_conflict (size_t x, size_t y) class stack_var *b = &stack_vars[y]; if (x == y) return; + gcc_assert (a->conflicts_represented && b->conflicts_represented); if (!a->conflicts) a->conflicts = BITMAP_ALLOC (&stack_var_bitmap_obstack); if (!b->conflicts) @@ -520,57 +526,16 @@ stack_var_conflict_p (size_t x, size_t y) if (TREE_CODE (a->decl) == SSA_NAME || TREE_CODE (b->decl) == SSA_NAME) return true; + /* If we cannot compute lifeness in a meaningful way for either variable + they conflict. */ + if (!a->conflicts_represented || !b->conflicts_represented) + return true; + if (!a->conflicts || !b->conflicts) return false; return bitmap_bit_p (a->conflicts, y); } -/* Callback for walk_stmt_ops. If OP is a decl touched by add_stack_var - enter its partition number into bitmap DATA. */ - -static bool -visit_op (gimple *, tree op, tree, void *data) -{ - bitmap active = (bitmap)data; - op = get_base_address (op); - if (op - && DECL_P (op) - && DECL_RTL_IF_SET (op) == pc_rtx) - { - size_t *v = decl_to_stack_part->get (op); - if (v) - bitmap_set_bit (active, *v); - } - return false; -} - -/* Callback for walk_stmt_ops. If OP is a decl touched by add_stack_var - record conflicts between it and all currently active other partitions - from bitmap DATA. */ - -static bool -visit_conflict (gimple *, tree op, tree, void *data) -{ - bitmap active = (bitmap)data; - op = get_base_address (op); - if (op - && DECL_P (op) - && DECL_RTL_IF_SET (op) == pc_rtx) - { - size_t *v = decl_to_stack_part->get (op); - if (v && bitmap_set_bit (active, *v)) - { - size_t num = *v; - bitmap_iterator bi; - unsigned i; - gcc_assert (num < stack_vars_num); - EXECUTE_IF_SET_IN_BITMAP (active, 0, i, bi) - add_stack_var_conflict (num, i); - } - } - return false; -} - /* Helper routine for add_scope_conflicts, calculating the active partitions at the end of BB, leaving the result in WORK. We're called to generate conflicts when FOR_CONFLICT is true, otherwise we're just tracking @@ -582,58 +547,63 @@ add_scope_conflicts_1 (basic_block bb, bitmap work, bool for_conflict) edge e; edge_iterator ei; gimple_stmt_iterator gsi; - walk_stmt_load_store_addr_fn visit; + bitmap_iterator bi; + unsigned i; bitmap_clear (work); FOR_EACH_EDGE (e, ei, bb->preds) bitmap_ior_into (work, (bitmap)e->src->aux); - visit = visit_op; + /* Since we do not get to see the birth clobber for variables being + live only via backedges add conflicts for everything live at + the start of the block. */ + if (for_conflict) + EXECUTE_IF_SET_IN_BITMAP (work, 0, i, bi) + { + class stack_var *a = &stack_vars[i]; + if (!a->conflicts) + a->conflicts = BITMAP_ALLOC (&stack_var_bitmap_obstack); + bitmap_ior_into (a->conflicts, work); + } - for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple *stmt = gsi_stmt (gsi); - walk_stmt_load_store_addr_ops (stmt, work, NULL, NULL, visit); - } + /* Now do the local dataflow. */ for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple *stmt = gsi_stmt (gsi); + if (!gimple_clobber_p (stmt)) + continue; - if (gimple_clobber_p (stmt)) - { - tree lhs = gimple_assign_lhs (stmt); - size_t *v; - /* Nested function lowering might introduce LHSs - that are COMPONENT_REFs. */ - if (!VAR_P (lhs)) - continue; - if (DECL_RTL_IF_SET (lhs) == pc_rtx - && (v = decl_to_stack_part->get (lhs))) - bitmap_clear_bit (work, *v); - } - else if (!is_gimple_debug (stmt)) + tree lhs = gimple_assign_lhs (stmt); + size_t *v; + /* Nested function lowering might introduce LHSs + that are COMPONENT_REFs. */ + if (!VAR_P (lhs)) + continue; + if (DECL_RTL_IF_SET (lhs) == pc_rtx + && (v = decl_to_stack_part->get (lhs))) { - if (for_conflict - && visit == visit_op) + size_t num = *v; + if (CLOBBER_KIND (gimple_assign_rhs1 (stmt)) == CLOBBER_BIRTH) { - /* If this is the first real instruction in this BB we need - to add conflicts for everything live at this point now. - Unlike classical liveness for named objects we can't - rely on seeing a def/use of the names we're interested in. - There might merely be indirect loads/stores. We'd not add any - conflicts for such partitions. */ - bitmap_iterator bi; - unsigned i; - EXECUTE_IF_SET_IN_BITMAP (work, 0, i, bi) + /* Birth. */ + if (for_conflict) { - class stack_var *a = &stack_vars[i]; - if (!a->conflicts) - a->conflicts = BITMAP_ALLOC (&stack_var_bitmap_obstack); - bitmap_ior_into (a->conflicts, work); + /* The births are where we add conflicts. */ + if (bitmap_set_bit (work, num)) + EXECUTE_IF_SET_IN_BITMAP (work, 0, i, bi) + add_stack_var_conflict (num, i); + } + else + { + /* We've seen a birth, assume life-ranges are + properly represented by birth and death CLOBBERs. */ + stack_vars[num].conflicts_represented = true; + bitmap_set_bit (work, num); } - visit = visit_conflict; } - walk_stmt_load_store_addr_ops (stmt, work, visit, visit, visit); + else if (CLOBBER_KIND (gimple_assign_rhs1 (stmt)) == CLOBBER_EOL) + /* Death. */ + bitmap_clear_bit (work, num); } } } @@ -650,13 +620,13 @@ add_scope_conflicts (void) int *rpo; int n_bbs; - /* We approximate the live range of a stack variable by taking the first - mention of its name as starting point(s), and by the end-of-scope - death clobber added by gimplify as ending point(s) of the range. - This overapproximates in the case we for instance moved an address-taken - operation upward, without also moving a dereference to it upwards. - But it's conservatively correct as a variable never can hold values - before its name is mentioned at least once. + /* We approximate the live range of a stack variable by using the + birth and death CLOBBERs as added by for example gimplification + based on the scopes the variables were declared in. + For variables we never see mentioned in a birth CLOBBER we have + to assume conflicts with all other stack variables. We could + improve this for the case of stack variables that do not have + their address taken as we can precisely track all mentions. We then do a mostly classical bitmap liveness algorithm. */ @@ -2022,9 +1992,12 @@ add_stack_protection_conflicts (void) for (i = 0; i < n; ++i) { + if (!stack_vars[i].conflicts_represented) + continue; unsigned char ph_i = phase[i]; for (j = i + 1; j < n; ++j) - if (ph_i != phase[j]) + if (stack_vars[j].conflicts_represented + && ph_i != phase[j]) add_stack_var_conflict (i, j); } diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 875b115d02d..37c80d609c4 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -1355,6 +1355,7 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) tree temp = voidify_wrapper_expr (bind_expr, NULL); /* Mark variables seen in this bind expr. */ + body = NULL; for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t)) { if (VAR_P (t)) @@ -1412,6 +1413,43 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun) cfun->has_local_explicit_reg_vars = true; + + /* For variables we add clobbers for in the cleanup, add + corresponding births at the start. */ + /* ??? We'd like to not add the birth here if we knew that + we'd see a DECL_EXPR for this variable later. Incidentially + OMP also seems to have a need to know that (see find_decl_expr). + Adding the birth here for example causes us to have a spurious + one for + switch (..) + { + case 1: + S s; + } + leading to bogus diagnostic we now mitigate in + warn_switch_unreachable_r as the birth will appear before + the case label in that case. + It might be possible to hijack the GENERIC body walk + we do in unshare_body to set a flag on all decls that + we discover having a DECL_EXPR or alternatively wrap + all builders of DECL_EXPR with a function doing that. */ + if (!is_global_var (t) + && DECL_CONTEXT (t) == current_function_decl + && !DECL_HARD_REGISTER (t) + && !TREE_THIS_VOLATILE (t) + && !DECL_HAS_VALUE_EXPR_P (t) + /* Only care for variables that have to be in memory. Others + will be rewritten into SSA names, hence moved to the + top-level. */ + && !is_gimple_reg (t) + && flag_stack_reuse != SR_NONE) + { + tree clobber = build_clobber (TREE_TYPE (t), CLOBBER_BIRTH); + gimple *clobber_stmt; + clobber_stmt = gimple_build_assign (t, clobber); + gimple_set_location (clobber_stmt, start_locus); + gimplify_seq_add_stmt (&body, clobber_stmt); + } } } @@ -1423,7 +1461,6 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) gimplify_ctxp->save_stack = false; /* Gimplify the body into the GIMPLE_BIND tuple's body. */ - body = NULL; gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body); gimple_bind_set_body (bind_stmt, body); @@ -1901,6 +1938,23 @@ gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p) is_vla = true; } + /* This mostly copies the condition we used for building a CLOBBER + when visiting a BIND_EXPR. We should rather remember that though, + we approximate it by checking DECL_SEEN_IN_BIND_EXPR_P. */ + if (!decl_had_value_expr_p + && !is_global_var (decl) + && !TREE_THIS_VOLATILE (decl) + && !DECL_HARD_REGISTER (decl) + && !is_gimple_reg (decl) + && DECL_SEEN_IN_BIND_EXPR_P (decl) + && flag_stack_reuse != SR_NONE) + { + tree clobber = build_clobber (TREE_TYPE (decl), CLOBBER_BIRTH); + gimple *clobber_stmt = gimple_build_assign (decl, clobber); + gimple_set_location (clobber_stmt, EXPR_LOCATION (stmt)); + gimplify_seq_add_stmt (seq_p, clobber_stmt); + } + if (asan_poisoned_variables && !is_vla && TREE_ADDRESSABLE (decl) @@ -2075,7 +2129,10 @@ warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p, } /* Fall through. */ default: - /* Save the first "real" statement (not a decl/lexical scope/...). */ + /* Save the first "real" statement (not a decl/lexical scope/...) + but avoid clobbers we add for the birth of variables. */ + if (gimple_clobber_p (stmt, CLOBBER_BIRTH)) + break; wi->info = stmt; return integer_zero_node; } @@ -6917,7 +6974,7 @@ gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) enum gimplify_status ret; bool unpoison_empty_seq = false; - gimple_stmt_iterator unpoison_it; + gimple_stmt_iterator unpoison_it = gsi_none (); if (init) { @@ -6935,8 +6992,9 @@ gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) } else { - /* Save location where we need to place unpoisoning. It's possible - that a variable will be converted to needs_to_live_in_memory. */ + /* Save location where we need to place unpoisoning or birth. + It's possible that a variable will be converted to + needs_to_live_in_memory. */ unpoison_it = gsi_last (*pre_p); unpoison_empty_seq = gsi_end_p (unpoison_it); @@ -6984,6 +7042,21 @@ gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) tree clobber = build_clobber (TREE_TYPE (temp), CLOBBER_EOL); clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber); gimple_push_cleanup (temp, clobber, false, pre_p, true); + + /* Replace the placed NOP with a birth clobber. */ + clobber = build_clobber (TREE_TYPE (temp), CLOBBER_BIRTH); + clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber); + gimple_seq stmts = NULL; + gimplify_and_add (clobber, &stmts); + if (unpoison_empty_seq) + { + gimple_stmt_iterator si = gsi_start (*pre_p); + gsi_insert_seq_before_without_update (&si, stmts, + GSI_SAME_STMT); + } + else + gsi_insert_seq_after_without_update (&unpoison_it, stmts, + GSI_LAST_NEW_STMT); } if (asan_poisoned_variables && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT diff --git a/gcc/testsuite/gcc.dg/torture/pr103006-1.c b/gcc/testsuite/gcc.dg/torture/pr103006-1.c new file mode 100644 index 00000000000..0053896f19f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr103006-1.c @@ -0,0 +1,27 @@ +/* { dg-do run } */ + +int printf(const char *, ...); +int a, *b, c, e, f; +void g() { + int *d[7]; + d[6] = b = (int *)d; + printf("0\n"); +} +int i() { + for (c = 0; c < 2; c++) { + long h[6][2]; + for (e = 0; e < 6; e++) + for (f = 0; f < 2; f++) + h[e][f] = 1; + if (c) { + g(); + return h[3][0]; + } + } + return 0; +} +int main() { + if (i() != 1) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr103006-2.c b/gcc/testsuite/gcc.dg/torture/pr103006-2.c new file mode 100644 index 00000000000..38acf85c4b9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr103006-2.c @@ -0,0 +1,29 @@ +/* { dg-do run } */ + +__attribute__((noipa)) void ff(void){} +int a, *b, c, e, f; +__attribute__((always_inline)) +static inline void g() { + int *d[7]; + d[6] = b = (int *)d; + ff(); +} +__attribute__((noinline)) +int i() { + for (c = 0; c < 2; c++) { + long h[6][2]; + for (e = 0; e < 6; e++) + for (f = 0; f < 2; f++) + h[e][f] = 1; + if (c) { + g(); + return h[3][0]; + } + } + return 0; +} +int main() { + if (i() != 1) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr90348.c b/gcc/testsuite/gcc.dg/torture/pr90348.c new file mode 100644 index 00000000000..132aff7861f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr90348.c @@ -0,0 +1,40 @@ +/* { dg-do run } */ + +void __attribute__ ((noipa)) +set_one (unsigned char* ptr) +{ + *ptr = 1; +} + +int __attribute__ ((noipa)) +check_nonzero (unsigned char const* in, unsigned int len) +{ + for (unsigned int i = 0; i < len; ++i) + if (in[i] != 0) + return 1; + return 0; +} + +void +set_one_on_stack () +{ + unsigned char buf[1]; + set_one (buf); +} + +int +main () +{ + for (int i = 0; i < 5; ++i) + { + unsigned char in[4]; + for (int j = 0; j < i; ++j) + { + in[j] = 0; + set_one_on_stack (); + } + if (check_nonzero (in, i)) + __builtin_abort (); + } +} + diff --git a/gcc/tree-core.h b/gcc/tree-core.h index bf2efa61330..786bc91571d 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -967,6 +967,8 @@ enum annot_expr_kind { enum clobber_kind { /* Unspecified, this clobber acts as a store of an undefined value. */ CLOBBER_UNDEF, + /* This clobber starts the lifetime of the storage. */ + CLOBBER_BIRTH, /* This clobber ends the lifetime of the storage. */ CLOBBER_EOL, CLOBBER_LAST diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc index 666b7a70ea2..d601f3f980d 100644 --- a/gcc/tree-pretty-print.cc +++ b/gcc/tree-pretty-print.cc @@ -2502,7 +2502,9 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags, if (TREE_CLOBBER_P (node)) { pp_string (pp, "CLOBBER"); - if (CLOBBER_KIND (node) == CLOBBER_EOL) + if (CLOBBER_KIND (node) == CLOBBER_BIRTH) + pp_string (pp, "(birth)"); + else if (CLOBBER_KIND (node) == CLOBBER_EOL) pp_string (pp, "(eol)"); } else if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE From patchwork Fri Feb 4 13:49:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 50798 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DBC1D3858D28 for ; Fri, 4 Feb 2022 13:50:49 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DBC1D3858D28 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1643982649; bh=sdxoWhXD0vCeDbLDn4aC72dRHASicZ5Gq0V4zl6z09c=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=fWGarDsuzryVIuaVLEXhhKzbCq2VG/YBYDJWRdBdgxBSpCV1C6qKbgLa279bLlfOi j65Lws1V9kLTIHhta6WYS/gEwEmjHUT7hnyz67FhZ5q8AiuYPoa6BYoUe3i5VJoy1r WPBwb3kOZa7A6j2KMEfOYifsHe084SmMXSdgHlyY= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by sourceware.org (Postfix) with ESMTPS id D15483858403 for ; Fri, 4 Feb 2022 13:49:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D15483858403 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 05925210F8 for ; Fri, 4 Feb 2022 13:49:20 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id E5D3013A96 for ; Fri, 4 Feb 2022 13:49:19 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id HWX/Nt8u/WGvegAAMHmgww (envelope-from ) for ; Fri, 04 Feb 2022 13:49:19 +0000 Date: Fri, 4 Feb 2022 14:49:19 +0100 (CET) To: gcc-patches@gcc.gnu.org Subject: [PATCH 2/4] Testcase adjustments for birth CLOBBERs MIME-Version: 1.0 Message-Id: <20220204134919.E5D3013A96@imap2.suse-dmz.suse.de> X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Richard Biener via Gcc-patches From: Richard Biener Reply-To: Richard Biener Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Mostly decl shuffling, using patterns to make the scans less error-prone and adjustments for now appearing birth CLOBBERs. 2022-02-02 Richard Biener * gcc.dg/pr87052.c: Adjust. * gcc.dg/tm/memopt-3.c: Likewise. * gcc.dg/torture/pta-ptrarith-1.c: Likewise. * gcc.dg/torture/pta-ptrarith-2.c: Likewise. * gcc.dg/tree-ssa/20031015-1.c: Likewise. * gcc.dg/tree-ssa/alias-19.c: Likewise. * gcc.dg/tree-ssa/dse-points-to.c: Likewise. * gcc.dg/tree-ssa/pta-callused.c: Likewise. --- gcc/testsuite/gcc.dg/pr87052.c | 3 ++- gcc/testsuite/gcc.dg/tm/memopt-3.c | 2 +- gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c | 2 +- gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c | 6 ++++-- gcc/testsuite/gcc.dg/tree-ssa/alias-19.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/dse-points-to.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c | 2 +- 8 files changed, 12 insertions(+), 9 deletions(-) diff --git a/gcc/testsuite/gcc.dg/pr87052.c b/gcc/testsuite/gcc.dg/pr87052.c index 18e092c4674..c67d9ae02f8 100644 --- a/gcc/testsuite/gcc.dg/pr87052.c +++ b/gcc/testsuite/gcc.dg/pr87052.c @@ -37,5 +37,6 @@ void test (void) { dg-final { scan-tree-dump-times "b = \"a\\\\x00bc\";" 1 "gimple" } } { dg-final { scan-tree-dump-times "c = \"\";" 1 "gimple" } } { dg-final { scan-tree-dump-times "d = { *};" 1 "gimple" } } - { dg-final { scan-tree-dump-times "e = " 1 "gimple" } } + { dg-final { scan-tree-dump-times "e = " 3 "gimple" } } + { dg-final { scan-tree-dump-times "e = {CLOBBER\\(birth\\)}" 2 "gimple" } } { dg-final { scan-tree-dump-times "e = {CLOBBER\\(eol\\)}" 1 "gimple" } } */ diff --git a/gcc/testsuite/gcc.dg/tm/memopt-3.c b/gcc/testsuite/gcc.dg/tm/memopt-3.c index 5316f9cae20..299494a1d2b 100644 --- a/gcc/testsuite/gcc.dg/tm/memopt-3.c +++ b/gcc/testsuite/gcc.dg/tm/memopt-3.c @@ -17,4 +17,4 @@ int f() return lala.x[0]; } -/* { dg-final { scan-tree-dump-times "logging: lala.x\\\[i_4\\\]" 1 "tmmark" } } */ +/* { dg-final { scan-tree-dump-times "logging: lala.x\\\[i_\[0-9\]+\\\]" 1 "tmmark" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c index 85b68068b12..4e272222b12 100644 --- a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c +++ b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c @@ -32,4 +32,4 @@ int main() return 0; } -/* { dg-final { scan-tree-dump "ESCAPED = {\[^\n\}\]* i f \[^\n\}\]*}" "alias" } } */ +/* { dg-final { scan-tree-dump "ESCAPED = {\[^\n\}\]* (i f|f i) \[^\n\}\]*}" "alias" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c index 4f5556acc93..5083d6367fa 100644 --- a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c +++ b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c @@ -32,4 +32,4 @@ int main() /* In theory = { i } is the correct solution. But it's not easy to scan for that reliably, so just use what we create now. */ -/* { dg-final { scan-tree-dump "= { i j }" "alias" } } */ +/* { dg-final { scan-tree-dump "= { (i j|j i) }" "alias" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c index faa6853f571..b97b4475132 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c @@ -13,5 +13,7 @@ main(void) return 0; } -/* The VDEF comes from the initial assignment, the asm, and the clobber. */ -/* { dg-final { scan-tree-dump-times "DEF" 3 "alias" } } */ +/* The VDEF comes from the birth clobber, initial assignment, the asm, and + the clobber. + ??? The birth clobber is duplicate. */ +/* { dg-final { scan-tree-dump-times "DEF" 5 "alias" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-19.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-19.c index 330ec001705..15f44a1c284 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/alias-19.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-19.c @@ -25,4 +25,4 @@ int main() return 0; } -/* { dg-final { scan-tree-dump "q_. = { a b }" "alias" } } */ +/* { dg-final { scan-tree-dump "q_. = { (a b|b a) }" "alias" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/dse-points-to.c b/gcc/testsuite/gcc.dg/tree-ssa/dse-points-to.c index 762d6720143..fced53fe50b 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/dse-points-to.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/dse-points-to.c @@ -11,4 +11,4 @@ f () return a; } -/* { dg-final { scan-tree-dump-times "Deleted dead store.*p_1" 1 "dse1"} } */ +/* { dg-final { scan-tree-dump-times "Deleted dead store: \\*p_\[0-9\]+ = 1" 1 "dse1"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c index b9a57d8d135..45826415d56 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c @@ -22,5 +22,5 @@ int bar (int b) return *foo (&q); } -/* { dg-final { scan-tree-dump "CALLUSED\\(\[0-9\]+\\) = { ESCAPED NONLOCAL f.* i q }" "alias" } } */ +/* { dg-final { scan-tree-dump "CALLUSED\\(\[0-9\]+\\) = { ESCAPED NONLOCAL (i f.*|f.* i) q }" "alias" } } */ From patchwork Fri Feb 4 13:49:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 50799 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5E8693858415 for ; Fri, 4 Feb 2022 13:51:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5E8693858415 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1643982706; bh=2nCqZ3jqmLon9/7a2Lt6YV6SJ+WM9EQmfBrUs7m+hPU=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=V7GlczNWEt7N9BIZ7uAHWXlB0X5BGPwZctPzdebprPoSctUOY9VHnDlCZaVMnLQlx f1C1qHE77dhCCG/4wPtDQJMWl+FfRGU2W236MRqEjqAoZSu6Qe1/Fll0BS9jj1xZ+0 QQ2x90S8z5HYiP4l2XvG4Iq7/KE4t3rWUtHMUn2o= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by sourceware.org (Postfix) with ESMTPS id 160AF3858D35 for ; Fri, 4 Feb 2022 13:49:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 160AF3858D35 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id E7F48210F8 for ; Fri, 4 Feb 2022 13:49:26 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id D470013A96 for ; Fri, 4 Feb 2022 13:49:26 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id +uqsMuYu/WHFegAAMHmgww (envelope-from ) for ; Fri, 04 Feb 2022 13:49:26 +0000 Date: Fri, 4 Feb 2022 14:49:26 +0100 (CET) To: gcc-patches@gcc.gnu.org Subject: [PATCH 3/4] Diagnostic passes adjustments MIME-Version: 1.0 Message-Id: <20220204134926.D470013A96@imap2.suse-dmz.suse.de> X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Richard Biener via Gcc-patches From: Richard Biener Reply-To: Richard Biener Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This adjusts diagnostic passes for the birth CLOBBERs where necessary. In particular the uninit diagnostics relies on particular shaped IL to simplify the expression printed (to be cleaned up independently) in gcc.dg/pr86058.c. 2022-02-02 Richard Biener * tree-ssa-uninit.cc (check_defs_data::found_full_clobber): New member. (check_defs): Set it. (maybe_warn_operand): Use it to treat expression simplification the same way as when the function entry was reached. --- gcc/tree-ssa-uninit.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gcc/tree-ssa-uninit.cc b/gcc/tree-ssa-uninit.cc index 02e88d58e1f..f2b15439113 100644 --- a/gcc/tree-ssa-uninit.cc +++ b/gcc/tree-ssa-uninit.cc @@ -319,6 +319,8 @@ struct check_defs_data { /* If we found any may-defs besides must-def clobbers. */ bool found_may_defs; + /* If we found a GIMPLE clobber that made the whole ref undefined. */ + bool found_full_clobber; }; /* Return true if STMT is a call to built-in function all of whose @@ -501,7 +503,10 @@ check_defs (ao_ref *ref, tree vdef, void *data_) if (gimple_clobber_p (def_stmt)) { if (stmt_kills_ref_p (def_stmt, ref)) - return true; + { + data->found_full_clobber = true; + return true; + } return false; } @@ -601,6 +606,7 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs, check_defs_data data; bool fentry_reached = false; data.found_may_defs = false; + data.found_full_clobber = false; tree use = gimple_vuse (stmt); if (!use) return NULL_TREE; @@ -666,7 +672,10 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs, if (tree ba = get_base_address (base)) base = ba; } + } + if (fentry_reached || data.found_full_clobber) + { /* Replace the RHS expression with BASE so that it refers to it in the diagnostic (instead of to ''). */ From patchwork Fri Feb 4 13:49:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 50800 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B2D783858416 for ; Fri, 4 Feb 2022 13:52:42 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B2D783858416 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1643982762; bh=c5b5ooghjVdj0vtMql0yryH7jKRKiIgIKhx6KT4ZhfE=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=h4Uu9vIEE9+6RsnWVosHj644mHE59f/zHwzvAh8HVvujnvQaT2GaRiaYsH0hQTkKK u8VPQoVrqK6EAo/YyCMZoKRZNvjIbqdxjZNV6R4O84zSjQe+rWXuZQ8+WhwCfz5dTh KgpH6QRuI1JJPxuzmU8PjV/h5AuHBqDFuoxUfZuY= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by sourceware.org (Postfix) with ESMTPS id 1B3503858D3C for ; Fri, 4 Feb 2022 13:49:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1B3503858D3C Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 389C0210FE for ; Fri, 4 Feb 2022 13:49:33 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 250F213A96 for ; Fri, 4 Feb 2022 13:49:33 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 7m7zB+0u/WHXegAAMHmgww (envelope-from ) for ; Fri, 04 Feb 2022 13:49:33 +0000 Date: Fri, 4 Feb 2022 14:49:32 +0100 (CET) To: gcc-patches@gcc.gnu.org Subject: [PATCH 4/4] Optimization passes adjustments for birth CLOBBERs MIME-Version: 1.0 Message-Id: <20220204134933.250F213A96@imap2.suse-dmz.suse.de> X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Richard Biener via Gcc-patches From: Richard Biener Reply-To: Richard Biener Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Since stack slot sharing now only works when RTL expansion sees the point of birth of variables explicitely marked we have to insert those markers during optimization. One case is when CCP simplifies a VLA allocation done with __builtin_stack_{save,restore} to a decl with constant size. There we already place the proper end-of-life CLOBBERs and the patch changes us to also emit birth CLOBBERs. gcc.dg/pr51491.c is where the effect is visible. A similar case happens when inlining produces declarations for arguments and result variables. This is visible in g++.dg/opt/pr81715.C for example. 2022-02-02 Richard Biener * tree-inline.cc (expand_call_inline): Also insert birth CLOBBERs for parameter and return declarations. * tree-ssa-ccp.c (insert_clobbers_for_var): Also insert birth CLOBBERs. * gcc.dg/pr51491-2.c: Adjust. --- gcc/testsuite/gcc.dg/pr51491-2.c | 3 ++- gcc/tree-inline.cc | 27 ++++++++++++++++++++++++++- gcc/tree-ssa-ccp.cc | 5 +++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/gcc.dg/pr51491-2.c b/gcc/testsuite/gcc.dg/pr51491-2.c index 429ee4e5914..910be3ddeec 100644 --- a/gcc/testsuite/gcc.dg/pr51491-2.c +++ b/gcc/testsuite/gcc.dg/pr51491-2.c @@ -31,4 +31,5 @@ f (int n) return tt; } -/* { dg-final { scan-tree-dump-times "CLOBBER" 2 "ccp1"} } */ +/* There is one redundant birth before the a[4] due to a DECL_EXPR + BIND. */ +/* { dg-final { scan-tree-dump-times "CLOBBER" 5 "ccp1"} } */ diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc index ca66a8266b1..cb825077bde 100644 --- a/gcc/tree-inline.cc +++ b/gcc/tree-inline.cc @@ -4767,7 +4767,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id, cgraph_inline_failed_t reason; basic_block return_block; edge e; - gimple_stmt_iterator gsi, stmt_gsi; + gimple_stmt_iterator gsi, stmt_gsi, birth_gsi; bool successfully_inlined = false; bool purge_dead_abnormal_edges; gcall *call_stmt; @@ -4924,6 +4924,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id, /* Split the block before the GIMPLE_CALL. */ stmt_gsi = gsi_for_stmt (stmt); gsi_prev (&stmt_gsi); + birth_gsi = stmt_gsi; e = split_block (bb, gsi_end_p (stmt_gsi) ? NULL : gsi_stmt (stmt_gsi)); bb = e->src; return_block = e->dest; @@ -5143,6 +5144,18 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id, clobber_stmt = gimple_build_assign (*varp, clobber); gimple_set_location (clobber_stmt, gimple_location (stmt)); gsi_insert_before (&stmt_gsi, clobber_stmt, GSI_SAME_STMT); + + clobber = build_clobber (TREE_TYPE (*varp), CLOBBER_BIRTH); + clobber_stmt = gimple_build_assign (*varp, clobber); + gimple_set_location (clobber_stmt, gimple_location (stmt)); + if (gsi_end_p (birth_gsi)) + { + birth_gsi = gsi_start_bb (gsi_bb (birth_gsi)); + gsi_insert_before (&birth_gsi, clobber_stmt, GSI_NEW_STMT); + } + else + gsi_insert_after (&birth_gsi, clobber_stmt, + GSI_CONTINUE_LINKING); } } @@ -5212,6 +5225,18 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id, clobber_stmt = gimple_build_assign (id->retvar, clobber); gimple_set_location (clobber_stmt, gimple_location (old_stmt)); gsi_insert_after (&stmt_gsi, clobber_stmt, GSI_SAME_STMT); + + clobber = build_clobber (TREE_TYPE (id->retvar), CLOBBER_BIRTH); + clobber_stmt = gimple_build_assign (id->retvar, clobber); + gimple_set_location (clobber_stmt, gimple_location (call_stmt)); + if (gsi_end_p (birth_gsi)) + { + birth_gsi = gsi_start_bb (gsi_bb (birth_gsi)); + gsi_insert_before (&birth_gsi, clobber_stmt, GSI_NEW_STMT); + } + else + gsi_insert_after (&birth_gsi, clobber_stmt, + GSI_CONTINUE_LINKING); } } else diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc index 9164efe3037..77910715755 100644 --- a/gcc/tree-ssa-ccp.cc +++ b/gcc/tree-ssa-ccp.cc @@ -2573,6 +2573,11 @@ insert_clobbers_for_var (gimple_stmt_iterator i, tree var) if (saved_val == NULL_TREE) continue; + /* Place a birth after the stack-save. */ + tree clobber = build_clobber (TREE_TYPE (var), CLOBBER_BIRTH); + gimple *clobber_stmt = gimple_build_assign (var, clobber); + gsi_insert_after (&i, clobber_stmt, GSI_SAME_STMT); + insert_clobber_before_stack_restore (saved_val, var, &visited); break; }