From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1011) id 5DBE23858D1E; Tue, 8 Feb 2022 15:03:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5DBE23858D1E MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Andrew Macleod To: gcc-cvs@gcc.gnu.org Subject: [gcc r11-9543] Range on entry should only check dominators for non-null. X-Act-Checkin: gcc X-Git-Author: Andrew MacLeod X-Git-Refname: refs/heads/releases/gcc-11 X-Git-Oldrev: a2cad467f72f8f1cd2adbab73376e5b0236441ed X-Git-Newrev: ed35d4205e8c139d27d3d47c528aaa9f82f0ac1b Message-Id: <20220208150307.5DBE23858D1E@sourceware.org> Date: Tue, 8 Feb 2022 15:03:07 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 Feb 2022 15:03:07 -0000 https://gcc.gnu.org/g:ed35d4205e8c139d27d3d47c528aaa9f82f0ac1b commit r11-9543-ged35d4205e8c139d27d3d47c528aaa9f82f0ac1b Author: Andrew MacLeod Date: Mon Jan 31 11:37:16 2022 -0500 Range on entry should only check dominators for non-null. Range-on-entry checks should no check the state of non-null within the current block. If dominators are present, use the dominator. PR tree-optimization/104288 gcc/ * gimple-range-cache.cc (ssa_range_in_bb): Only use non-null from the dominator entry ranges. * gimple-range.cc (gimple_ranger::range_of_expr): Ditto. gcc/testsuite/ * gcc.dg/pr104288.c: New. Diff: --- gcc/gimple-range-cache.cc | 19 ++++++++++++------- gcc/gimple-range.cc | 16 ++++++++++------ gcc/testsuite/gcc.dg/pr104288.c | 23 +++++++++++++++++++++++ 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 6ddeca3766d..b05b804d513 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -905,14 +905,19 @@ ranger_cache::ssa_range_in_bb (irange &r, tree name, basic_block bb) // Try to pick up any known global value as a best guess for now. if (!m_globals.get_global_range (r, name)) r = gimple_range_global (name); + // Check for non-null on entry if dominators are available by + // resetting def_bb to the block we want to search. + if (dom_info_available_p (CDI_DOMINATORS)) + { + basic_block dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb); + // Check if pointers have any non-null dereferences. Non-call + // exceptions mean we could throw in the middle of the block, so just + // punt for now on those. + if (dom_bb && r.varying_p () && !cfun->can_throw_non_call_exceptions + && m_non_null.non_null_deref_p (name, dom_bb)) + r = range_nonzero (TREE_TYPE (name)); + } } - - // Check if pointers have any non-null dereferences. Non-call - // exceptions mean we could throw in the middle of the block, so just - // punt for now on those. - if (r.varying_p () && m_non_null.non_null_deref_p (name, bb) && - !cfun->can_throw_non_call_exceptions) - r = range_nonzero (TREE_TYPE (name)); } // Return a static range for NAME on entry to basic block BB in R. If diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index f861459ed96..42c637458ad 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -979,10 +979,14 @@ gimple_ranger::range_of_expr (irange &r, tree expr, gimple *stmt) // If name is defined in this block, try to get an range from S. if (def_stmt && gimple_bb (def_stmt) == bb) - range_of_stmt (r, def_stmt, expr); - else - // Otherwise OP comes from outside this block, use range on entry. - range_on_entry (r, bb, expr); + return range_of_stmt (r, def_stmt, expr); + + // Otherwise OP comes from outside this block, use range on entry. + range_on_entry (r, bb, expr); + // Check for non-null in the predecessor if dominators are available. + if (!dom_info_available_p (CDI_DOMINATORS)) + return true; + basic_block dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb); // No range yet, see if there is a dereference in the block. // We don't care if it's between the def and a use within a block @@ -992,8 +996,8 @@ gimple_ranger::range_of_expr (irange &r, tree expr, gimple *stmt) // in which case we may need to walk from S back to the def/top of block // to make sure the deref happens between S and there before claiming // there is a deref. Punt for now. - if (!cfun->can_throw_non_call_exceptions && r.varying_p () && - m_cache.m_non_null.non_null_deref_p (expr, bb)) + if (dom_bb && !cfun->can_throw_non_call_exceptions && r.varying_p () + && m_cache.m_non_null.non_null_deref_p (expr, dom_bb)) r = range_nonzero (TREE_TYPE (expr)); return true; diff --git a/gcc/testsuite/gcc.dg/pr104288.c b/gcc/testsuite/gcc.dg/pr104288.c new file mode 100644 index 00000000000..95eb196f9e4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104288.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp -fdelete-null-pointer-checks" } */ +/* { dg-skip-if "" { keeps_null_pointer_checks } } */ + +void keep(int result) __attribute__((noipa)); +void keep(int result) +{ + if (result) + __builtin_exit(0); +} + +void foo (void *p) __attribute__((nonnull(1))); + +void bar (void *p) +{ + keep (p == 0); + foo (p); + if (!p) + __builtin_abort (); +} + +/* { dg-final { scan-tree-dump-not "abort" "evrp" } } */ +/* { dg-final { scan-tree-dump-times "== 0B;" 1 "evrp" } } */