From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from nikam.ms.mff.cuni.cz (nikam.ms.mff.cuni.cz [195.113.20.16]) by sourceware.org (Postfix) with ESMTPS id 17CCF3858D37 for ; Tue, 21 Nov 2023 14:06:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 17CCF3858D37 Authentication-Results: sourceware.org; dmarc=fail (p=none dis=none) header.from=ucw.cz Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=kam.mff.cuni.cz ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 17CCF3858D37 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=195.113.20.16 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700575620; cv=none; b=O6KRQaOrb90uIRazLsBk3tBda984OEUWXDGzZ5GYpvjJmY5VcLRDkyzud0Zr/4vRUKSewnhjxBT7uz4Mb7rI6rJL9tbfz7t9uD1PsXRaXghYPsXI3AqQ1htdxMoH7J3slkfqlZcl0iwB1v76ezS1Aaahd8sUped3GLOMBN8N2QQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700575620; c=relaxed/simple; bh=ypBgeC1sEy7yKJoQSq3/4zHISf9yOZPnwmm7zGpc70E=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=dB3y8FESb2IqWzjLoNnLMox8UpDxOcmBbHHWpKV5IP3TAuovDjHZIu+ygPTh2F0ZQZ6xO7753+Y73fClYA8e0G0gktMdDXCli9MRHP8cn501W9JLuFqc1/q+2BBwX9M85TM20XHHtP+KWW5GX77+2ZlfnCfCor4RwU9sRbfhG9M= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id D20D628B8AE; Tue, 21 Nov 2023 15:06:54 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ucw.cz; s=gen1; t=1700575614; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=39q/IazJeaKch9t2yKYYU8BQ8l+XSFUog4roCOO62/Q=; b=MNd12zhVb8r9VQy0Ed1P9w7/jeEO2ysQcTTXT5omTgI4dVo2Z1IYPz1BcgtIntI2aYLZZS hrdkK5XI7GrSBYrCTF9BRepgJooOp578+xtnHPrZS24HhzW7EBCr2n/GM+7CWGqg/l9S3d SYOsvLDAJ008V2wLLqvARhimlQgPpHQ= Date: Tue, 21 Nov 2023 15:06:54 +0100 From: Jan Hubicka To: Christophe Lyon Cc: Sam James , gcc-patches@gcc.gnu.org Subject: Re: Propagate value ranges of return values Message-ID: References: <871qcmkmgd.fsf@gentoo.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Spam-Status: No, score=-11.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,GIT_PATCH_0,HEADER_FROM_DIFFERENT_DOMAINS,JMQ_SPF_NEUTRAL,KAM_SHORT,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: > After this patch in addition to the problem already reported about > vlda1.c and return-value-range-1.c, we have noticed these regressions > on aarch64: > Running gcc:gcc.target/aarch64/aarch64.exp ... > FAIL: gcc.target/aarch64/movk.c scan-assembler movk\tx[0-9]+, 0x4667, lsl 16 > FAIL: gcc.target/aarch64/movk.c scan-assembler movk\tx[0-9]+, 0x7a3d, lsl 32 > > Running gcc:gcc.target/aarch64/simd/simd.exp ... > FAIL: gcc.target/aarch64/simd/vmulxd_f64_2.c scan-assembler-times > fmul[ \t]+[dD][0-9]+, ?[dD][0-9]+, ?[dD][0-9]+\n 1 > FAIL: gcc.target/aarch64/simd/vmulxd_f64_2.c scan-assembler-times > fmulx[ \t]+[dD][0-9]+, ?[dD][0-9]+, ?[dD][0-9]+\n 4 > FAIL: gcc.target/aarch64/simd/vmulxs_f32_2.c scan-assembler-times > fmul[ \t]+[sS][0-9]+, ?[sS][0-9]+, ?[sS][0-9]+\n 1 > FAIL: gcc.target/aarch64/simd/vmulxs_f32_2.c scan-assembler-times > fmulx[ \t]+[sS][0-9]+, ?[sS][0-9]+, ?[sS][0-9]+\n 4 Sorry for that - I guess we will see some on various targets. This is quite common issue - the testcase is having dummy_number_generator function returning constant and prevents inlining to avoid constant being visible to compiler. This no longer works, since we get it from the return value range. This should fix it. return-value_range-1.c should be fixed now and I do not have vlda1.c in my tree. I will check. diff --git a/gcc/testsuite/gcc.target/aarch64/movk.c b/gcc/testsuite/gcc.target/aarch64/movk.c index e6e4e3a8961..6b1f3f8ecf5 100644 --- a/gcc/testsuite/gcc.target/aarch64/movk.c +++ b/gcc/testsuite/gcc.target/aarch64/movk.c @@ -1,8 +1,9 @@ /* { dg-do run } */ -/* { dg-options "-O2 --save-temps -fno-inline" } */ +/* { dg-options "-O2 --save-temps" } */ extern void abort (void); +__attribute__ ((noipa)) long long int dummy_number_generator () { > > We have already sent you a notification for the regression on arm, but > it includes on vla-1.c and return-value-range-1.c. > The notification email contains a pointer to the page where we record > all the configurations that regress because of this patch: > > https://linaro.atlassian.net/browse/GNU-1025 > > Can you have a look? > > Thanks, > > Christophe > > > > > > diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc > > index e41e5ad3ae7..71dacf23ce1 100644 > > --- a/gcc/cgraph.cc > > +++ b/gcc/cgraph.cc > > @@ -2629,6 +2629,54 @@ cgraph_node::set_malloc_flag (bool malloc_p) > > return changed; > > } > > > > +/* Worker to set malloc flag. */ > > +static void > > +add_detected_attribute_1 (cgraph_node *node, const char *attr, bool *changed) > > +{ > > + if (!lookup_attribute (attr, DECL_ATTRIBUTES (node->decl))) > > + { > > + DECL_ATTRIBUTES (node->decl) = tree_cons (get_identifier (attr), > > + NULL_TREE, DECL_ATTRIBUTES (node->decl)); > > + *changed = true; > > + } > > + > > + ipa_ref *ref; > > + FOR_EACH_ALIAS (node, ref) > > + { > > + cgraph_node *alias = dyn_cast (ref->referring); > > + if (alias->get_availability () > AVAIL_INTERPOSABLE) > > + add_detected_attribute_1 (alias, attr, changed); > > + } > > + > > + for (cgraph_edge *e = node->callers; e; e = e->next_caller) > > + if (e->caller->thunk > > + && (e->caller->get_availability () > AVAIL_INTERPOSABLE)) > > + add_detected_attribute_1 (e->caller, attr, changed); > > +} > > + > > +/* Set DECL_IS_MALLOC on NODE's decl and on NODE's aliases if any. */ > > + > > +bool > > +cgraph_node::add_detected_attribute (const char *attr) > > +{ > > + bool changed = false; > > + > > + if (get_availability () > AVAIL_INTERPOSABLE) > > + add_detected_attribute_1 (this, attr, &changed); > > + else > > + { > > + ipa_ref *ref; > > + > > + FOR_EACH_ALIAS (this, ref) > > + { > > + cgraph_node *alias = dyn_cast (ref->referring); > > + if (alias->get_availability () > AVAIL_INTERPOSABLE) > > + add_detected_attribute_1 (alias, attr, &changed); > > + } > > + } > > + return changed; > > +} > > + > > /* Worker to set noreturng flag. */ > > static void > > set_noreturn_flag_1 (cgraph_node *node, bool noreturn_p, bool *changed) > > diff --git a/gcc/cgraph.h b/gcc/cgraph.h > > index cedaaac3a45..cfdd9f693a8 100644 > > --- a/gcc/cgraph.h > > +++ b/gcc/cgraph.h > > @@ -1190,6 +1190,10 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node > > > > bool set_pure_flag (bool pure, bool looping); > > > > + /* Add attribute ATTR to cgraph_node's decl and on aliases of the node > > + if any. */ > > + bool add_detected_attribute (const char *attr); > > + > > /* Call callback on function and aliases associated to the function. > > When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are > > skipped. */ > > diff --git a/gcc/common.opt b/gcc/common.opt > > index d21db5d4a20..c6599c7147b 100644 > > --- a/gcc/common.opt > > +++ b/gcc/common.opt > > @@ -781,6 +781,10 @@ Wsuggest-attribute=malloc > > Common Var(warn_suggest_attribute_malloc) Warning > > Warn about functions which might be candidates for __attribute__((malloc)). > > > > +Wsuggest-attribute=returns_nonnull > > +Common Warning > > +Warn about functions which might be candidates for __attribute__((returns_nonnull)). > > + > > Wsuggest-final-types > > Common Var(warn_suggest_final_types) Warning > > Warn about C++ polymorphic types where adding final keyword would improve code quality. > > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > > index 1f109679c70..3c33104df0a 100644 > > --- a/gcc/doc/invoke.texi > > +++ b/gcc/doc/invoke.texi > > @@ -8093,7 +8093,7 @@ if the array is referenced as a flexible array member. > > > > @opindex Wsuggest-attribute= > > @opindex Wno-suggest-attribute= > > -@item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]} > > +@item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]}returns_nonnull@r{|} > > Warn for cases where adding an attribute may be beneficial. The > > attributes currently supported are listed below. > > > > @@ -8113,9 +8113,11 @@ attributes currently supported are listed below. > > @itemx -Wsuggest-attribute=noreturn > > @itemx -Wmissing-noreturn > > @itemx -Wsuggest-attribute=malloc > > +@itemx -Wsuggest-attribute=returns_nonnull > > +@itemx -Wno-suggest-attribute=returns_nonnull > > > > Warn about functions that might be candidates for attributes > > -@code{pure}, @code{const} or @code{noreturn} or @code{malloc}. The compiler > > +@code{pure}, @code{const}, @code{noreturn}, @code{malloc} or @code{returns_nonnull}. The compiler > > only warns for functions visible in other compilation units or (in the case of > > @code{pure} and @code{const}) if it cannot prove that the function returns > > normally. A function returns normally if it doesn't contain an infinite loop or > > diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc > > index 6e9530c3d7f..998b7608d78 100644 > > --- a/gcc/gimple-range-fold.cc > > +++ b/gcc/gimple-range-fold.cc > > @@ -44,6 +44,11 @@ along with GCC; see the file COPYING3. If not see > > #include "value-query.h" > > #include "gimple-range-op.h" > > #include "gimple-range.h" > > +#include "cgraph.h" > > +#include "alloc-pool.h" > > +#include "symbol-summary.h" > > +#include "ipa-utils.h" > > +#include "ipa-prop.h" > > // Construct a fur_source, and set the m_query field. > > > > fur_source::fur_source (range_query *q) > > @@ -1013,6 +1018,25 @@ fold_using_range::range_of_call (vrange &r, gcall *call, fur_source &) > > else > > r.set_varying (type); > > > > + tree callee = gimple_call_fndecl (call); > > + if (callee > > + && useless_type_conversion_p (TREE_TYPE (TREE_TYPE (callee)), type)) > > + { > > + Value_Range val; > > + if (ipa_return_value_range (val, callee)) > > + { > > + r.intersect (val); > > + if (dump_file && (dump_flags & TDF_DETAILS)) > > + { > > + fprintf (dump_file, "Using return value range of "); > > + print_generic_expr (dump_file, callee, TDF_SLIM); > > + fprintf (dump_file, ": "); > > + val.dump (dump_file); > > + fprintf (dump_file, "\n"); > > + } > > + } > > + } > > + > > // If there is an LHS, intersect that with what is known. > > if (lhs) > > { > > diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc > > index 7de2b788185..e77bc9c340b 100644 > > --- a/gcc/ipa-prop.cc > > +++ b/gcc/ipa-prop.cc > > @@ -237,6 +237,35 @@ gt_ggc_mx (ipa_vr *&x) > > return gt_ggc_mx ((ipa_vr *) x); > > } > > > > +/* Analysis summery of function call return value. */ > > +struct GTY(()) ipa_return_value_summary > > +{ > > + /* Known value range. > > + This needs to be wrapped in struccture due to specific way > > + we allocate ipa_vr. */ > > + ipa_vr *vr; > > +}; > > + > > +/* Function summary for return values. */ > > +class ipa_return_value_sum_t : public function_summary > > +{ > > +public: > > + ipa_return_value_sum_t (symbol_table *table, bool ggc): > > + function_summary (table, ggc) { } > > + > > + /* Hook that is called by summary when a node is duplicated. */ > > + void duplicate (cgraph_node *, > > + cgraph_node *, > > + ipa_return_value_summary *data, > > + ipa_return_value_summary *data2) final override > > + { > > + *data2=*data; > > + } > > +}; > > + > > +/* Variable hoding the return value summary. */ > > +static GTY(()) function_summary *ipa_return_value_sum; > > + > > > > /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated > > with NODE should prevent us from analyzing it for the purposes of IPA-CP. */ > > @@ -5915,5 +5944,49 @@ ipcp_transform_function (struct cgraph_node *node) > > return modified_mem_access ? TODO_update_ssa_only_virtuals : 0; > > } > > > > +/* Record that current function return value range is VAL. */ > > + > > +void > > +ipa_record_return_value_range (Value_Range val) > > +{ > > + cgraph_node *n = cgraph_node::get (current_function_decl); > > + if (!ipa_return_value_sum) > > + { > > + if (!ipa_vr_hash_table) > > + ipa_vr_hash_table = hash_table::create_ggc (37); > > + ipa_return_value_sum = new (ggc_alloc_no_dtor ()) > > + ipa_return_value_sum_t (symtab, true); > > + ipa_return_value_sum->disable_insertion_hook (); > > + } > > + ipa_return_value_sum->get_create (n)->vr = ipa_get_value_range (val); > > + if (dump_file && (dump_flags & TDF_DETAILS)) > > + { > > + fprintf (dump_file, "Recording return range "); > > + val.dump (dump_file); > > + fprintf (dump_file, "\n"); > > + } > > +} > > + > > +/* Return true if value range of DECL is known and if so initialize RANGE. */ > > + > > +bool > > +ipa_return_value_range (Value_Range &range, tree decl) > > +{ > > + cgraph_node *n = cgraph_node::get (decl); > > + if (!n || !ipa_return_value_sum) > > + return false; > > + enum availability avail; > > + n = n->ultimate_alias_target (&avail); > > + if (avail < AVAIL_AVAILABLE) > > + return false; > > + if (n->decl != decl && !useless_type_conversion_p (TREE_TYPE (decl), TREE_TYPE (n->decl))) > > + return false; > > + ipa_return_value_summary *v = ipa_return_value_sum->get (n); > > + if (!v) > > + return false; > > + v->vr->get_vrange (range); > > + return true; > > +} > > + > > > > #include "gt-ipa-prop.h" > > diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h > > index fcd0e5c638f..5901c805c40 100644 > > --- a/gcc/ipa-prop.h > > +++ b/gcc/ipa-prop.h > > @@ -309,7 +309,7 @@ public: > > void get_vrange (Value_Range &) const; > > bool equal_p (const vrange &) const; > > const vrange_storage *storage () const { return m_storage; } > > - void streamer_read (lto_input_block *, data_in *); > > + void streamer_read (lto_input_block *, class data_in *); > > void streamer_write (output_block *) const; > > void dump (FILE *) const; > > > > @@ -1274,4 +1274,7 @@ ipa_range_set_and_normalize (vrange &r, tree val) > > r.set (val, val); > > } > > > > +bool ipa_return_value_range (Value_Range &range, tree decl); > > +void ipa_record_return_value_range (Value_Range val); > > + > > #endif /* IPA_PROP_H */ > > diff --git a/gcc/ipa-pure-const.cc b/gcc/ipa-pure-const.cc > > index 058a7dd3019..3060ffeefcd 100644 > > --- a/gcc/ipa-pure-const.cc > > +++ b/gcc/ipa-pure-const.cc > > @@ -292,6 +292,15 @@ warn_function_cold (tree decl) > > true, warned_about, "cold"); > > } > > > > +void > > +warn_function_returns_nonnull (tree decl) > > +{ > > + static hash_set *warned_about; > > + warned_about > > + = suggest_attribute (OPT_Wsuggest_attribute_returns_nonnull, decl, > > + true, warned_about, "returns_nonnull"); > > +} > > + > > /* Check to see if the use (or definition when CHECKING_WRITE is true) > > variable T is legal in a function that is either pure or const. */ > > > > diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h > > index 0eefcf40d44..84728c589ea 100644 > > --- a/gcc/ipa-utils.h > > +++ b/gcc/ipa-utils.h > > @@ -105,6 +105,7 @@ tree prevailing_odr_type (tree type); > > void enable_odr_based_tbaa (tree type); > > bool odr_based_tbaa_p (const_tree type); > > void set_type_canonical_for_odr_type (tree type, tree canonical); > > +void warn_function_returns_nonnull (tree); > > > > void register_odr_enum (tree type); > > > > diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h > > index 3ed61627382..5fd49a2552e 100644 > > --- a/gcc/symbol-summary.h > > +++ b/gcc/symbol-summary.h > > @@ -71,7 +71,7 @@ public: > > = m_symtab->add_cgraph_insertion_hook (m_symtab_insertion, this); > > } > > > > - /* Enable insertion hook invocation. */ > > + /* Disable insertion hook invocation. */ > > void disable_insertion_hook () > > { > > if (m_symtab_insertion_hook != NULL) > > diff --git a/gcc/testsuite/g++.dg/ipa/devirt-2.C b/gcc/testsuite/g++.dg/ipa/devirt-2.C > > index 48a94e09828..1797db6c81c 100644 > > --- a/gcc/testsuite/g++.dg/ipa/devirt-2.C > > +++ b/gcc/testsuite/g++.dg/ipa/devirt-2.C > > @@ -43,7 +43,7 @@ int C::foo (int i) > > return i + 3; > > } > > > > -int __attribute__ ((noinline,noclone)) get_input(void) > > +int __attribute__ ((noinline,noclone,noipa)) get_input(void) > > { > > return 1; > > } > > diff --git a/gcc/testsuite/g++.dg/ipa/devirt-7.C b/gcc/testsuite/g++.dg/ipa/devirt-7.C > > index f27a264fd1e..b24b2bca5f9 100644 > > --- a/gcc/testsuite/g++.dg/ipa/devirt-7.C > > +++ b/gcc/testsuite/g++.dg/ipa/devirt-7.C > > @@ -1,7 +1,7 @@ > > /* Verify that IPA-CP can do devirtualization even if the virtual call > > comes from a method that has been early-inlined into a descendant. */ > > /* { dg-do run } */ > > -/* { dg-options "-O3 -fdump-ipa-cp" } */ > > +/* { dg-options "-O3 -fdump-ipa-cp -fno-ipa-vrp" } */ > > /* { dg-add-options bind_pic_locally } */ > > > > extern "C" void abort (void); > > diff --git a/gcc/testsuite/g++.dg/ipa/ipa-icf-2.C b/gcc/testsuite/g++.dg/ipa/ipa-icf-2.C > > index 7f56189eebb..ae121e8a762 100644 > > --- a/gcc/testsuite/g++.dg/ipa/ipa-icf-2.C > > +++ b/gcc/testsuite/g++.dg/ipa/ipa-icf-2.C > > @@ -1,5 +1,5 @@ > > /* { dg-do compile } */ > > -/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */ > > +/* { dg-options "-O2 -fdump-ipa-icf-optimized -fno-ipa-vrp" } */ > > > > class A > > { > > diff --git a/gcc/testsuite/g++.dg/ipa/ipa-icf-3.C b/gcc/testsuite/g++.dg/ipa/ipa-icf-3.C > > index 5a3cca24fa2..03c10f12db2 100644 > > --- a/gcc/testsuite/g++.dg/ipa/ipa-icf-3.C > > +++ b/gcc/testsuite/g++.dg/ipa/ipa-icf-3.C > > @@ -1,5 +1,5 @@ > > /* { dg-do compile } */ > > -/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */ > > +/* { dg-options "-O2 -fdump-ipa-icf-optimized -fno-ipa-vrp" } */ > > > > __attribute__ ((noinline)) > > int zero() > > diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-1.C b/gcc/testsuite/g++.dg/ipa/ivinline-1.C > > index 2d988bc6d55..ccb1870ec69 100644 > > --- a/gcc/testsuite/g++.dg/ipa/ivinline-1.C > > +++ b/gcc/testsuite/g++.dg/ipa/ivinline-1.C > > @@ -1,7 +1,7 @@ > > /* Verify that simple virtual calls are inlined even without early > > inlining. */ > > /* { dg-do run { target { nonpic || pie_enabled } } } */ > > -/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ > > +/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp -fno-ipa-vrp" } */ > > > > extern "C" void abort (void); > > > > diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-3.C b/gcc/testsuite/g++.dg/ipa/ivinline-3.C > > index f756a16bae9..02e7e443fa9 100644 > > --- a/gcc/testsuite/g++.dg/ipa/ivinline-3.C > > +++ b/gcc/testsuite/g++.dg/ipa/ivinline-3.C > > @@ -1,7 +1,7 @@ > > /* Verify that simple virtual calls on an object refrence are inlined > > even without early inlining. */ > > /* { dg-do run { target { nonpic || pie_enabled } } } */ > > -/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ > > +/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp -fno-ipa-vrp" } */ > > > > extern "C" void abort (void); > > > > diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-5.C b/gcc/testsuite/g++.dg/ipa/ivinline-5.C > > index 6c19907686e..cb889d1e84f 100644 > > --- a/gcc/testsuite/g++.dg/ipa/ivinline-5.C > > +++ b/gcc/testsuite/g++.dg/ipa/ivinline-5.C > > @@ -1,7 +1,7 @@ > > /* Verify that virtual call inlining does not pick a wrong method when > > there is a user defined ancestor in an object. */ > > /* { dg-do run { target { nonpic || pie_enabled } } } */ > > -/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ > > +/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp -fno-ipa-vrp" } */ > > > > extern "C" void abort (void); > > > > diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-8.C b/gcc/testsuite/g++.dg/ipa/ivinline-8.C > > index bc81abfe347..f29e818e357 100644 > > --- a/gcc/testsuite/g++.dg/ipa/ivinline-8.C > > +++ b/gcc/testsuite/g++.dg/ipa/ivinline-8.C > > @@ -1,7 +1,7 @@ > > /* Verify that virtual calls are inlined (ithout early inlining) even > > when their caller is itself indirectly inlined. */ > > /* { dg-do run { target { nonpic || pie_enabled } } } */ > > -/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ > > +/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp -fno-ipa-vrp" } */ > > > > extern "C" void abort (void); > > > > diff --git a/gcc/testsuite/g++.dg/ipa/nothrow-1.C b/gcc/testsuite/g++.dg/ipa/nothrow-1.C > > index b30b0215924..1f243109619 100644 > > --- a/gcc/testsuite/g++.dg/ipa/nothrow-1.C > > +++ b/gcc/testsuite/g++.dg/ipa/nothrow-1.C > > @@ -1,5 +1,5 @@ > > /* { dg-do compile } */ > > -/* { dg-options "-O2 -fnon-call-exceptions -fdump-tree-optimized" } */ > > +/* { dg-options "-O2 -fnon-call-exceptions -fdump-tree-optimized -fno-ipa-vrp" } */ > > int *ptr; > > static int barvar; > > > > diff --git a/gcc/testsuite/g++.dg/ipa/pure-const-1.C b/gcc/testsuite/g++.dg/ipa/pure-const-1.C > > index 61940c670e7..c18278cae11 100644 > > --- a/gcc/testsuite/g++.dg/ipa/pure-const-1.C > > +++ b/gcc/testsuite/g++.dg/ipa/pure-const-1.C > > @@ -1,5 +1,5 @@ > > /* { dg-do compile } */ > > -/* { dg-options "-O2 -fdump-tree-optimized" } */ > > +/* { dg-options "-O2 -fdump-tree-optimized -fno-ipa-vrp" } */ > > int *ptr; > > static int barvar; > > > > diff --git a/gcc/testsuite/g++.dg/ipa/pure-const-2.C b/gcc/testsuite/g++.dg/ipa/pure-const-2.C > > index 6e739de4ade..d5f18bfa9be 100644 > > --- a/gcc/testsuite/g++.dg/ipa/pure-const-2.C > > +++ b/gcc/testsuite/g++.dg/ipa/pure-const-2.C > > @@ -1,5 +1,5 @@ > > /* { dg-do compile } */ > > -/* { dg-options "-O2 -fdump-tree-optimized" } */ > > +/* { dg-options "-O2 -fdump-tree-optimized -fno-ipa-vrp" } */ > > int *ptr; > > static int barvar; > > /* We can not detect A to be const because it may be interposed by unoptimized > > diff --git a/gcc/testsuite/g++.dg/lto/inline-crossmodule-1_0.C b/gcc/testsuite/g++.dg/lto/inline-crossmodule-1_0.C > > index 0294dcc4bfb..c56360ef66e 100644 > > --- a/gcc/testsuite/g++.dg/lto/inline-crossmodule-1_0.C > > +++ b/gcc/testsuite/g++.dg/lto/inline-crossmodule-1_0.C > > @@ -1,5 +1,5 @@ > > // { dg-lto-do link } > > -/* { dg-lto-options { "-O2 -fno-early-inlining -fno-implicit-constexpr -flto -fdump-ipa-inline-details" } } */ > > +/* { dg-lto-options { "-O2 -fno-early-inlining -fno-implicit-constexpr -flto -fdump-ipa-inline-details -fno-ipa-vrp" } } */ > > #include "inline-crossmodule-1.h" > > int a::key () > > { > > diff --git a/gcc/testsuite/gcc.c-torture/compile/pr106433.c b/gcc/testsuite/gcc.c-torture/compile/pr106433.c > > index b840e5ecd93..e02ad5ffe15 100644 > > --- a/gcc/testsuite/gcc.c-torture/compile/pr106433.c > > +++ b/gcc/testsuite/gcc.c-torture/compile/pr106433.c > > @@ -2,7 +2,7 @@ > > > > int m, *p; > > > > -__attribute__ ((simd)) int > > +__attribute__ ((simd,noipa)) int > > bar (int x) > > { > > if (x) > > diff --git a/gcc/testsuite/gcc.c-torture/execute/frame-address.c b/gcc/testsuite/gcc.c-torture/execute/frame-address.c > > index 5afa691e409..5950581054d 100644 > > --- a/gcc/testsuite/gcc.c-torture/execute/frame-address.c > > +++ b/gcc/testsuite/gcc.c-torture/execute/frame-address.c > > @@ -1,10 +1,10 @@ > > /* { dg-require-effective-target return_address } */ > > void abort (void); > > > > -int check_fa_work (const char *, const char *) __attribute__((noinline)); > > -int check_fa_mid (const char *) __attribute__((noinline)); > > -int check_fa (char *) __attribute__((noinline)); > > -int how_much (void) __attribute__((noinline)); > > +int check_fa_work (const char *, const char *) __attribute__((noinline,noipa)); > > +int check_fa_mid (const char *) __attribute__((noinline,noipa)); > > +int check_fa (char *) __attribute__((noinline,noipa)); > > +int how_much (void) __attribute__((noinline,noipa)); > > > > int check_fa_work (const char *c, const char *f) > > { > > diff --git a/gcc/testsuite/gcc.dg/ipa/fopt-info-inline-1.c b/gcc/testsuite/gcc.dg/ipa/fopt-info-inline-1.c > > index 4032ad13e19..155a6829b88 100644 > > --- a/gcc/testsuite/gcc.dg/ipa/fopt-info-inline-1.c > > +++ b/gcc/testsuite/gcc.dg/ipa/fopt-info-inline-1.c > > @@ -1,4 +1,4 @@ > > -/* { dg-options "-O3 -fopt-info-inline-optimized-missed" } */ > > +/* { dg-options "-O3 -fopt-info-inline-optimized-missed -fno-ipa-vrp" } */ > > > > static int foo (int a) > > { > > diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-25.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-25.c > > index fad0891283e..cbda6858890 100644 > > --- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-25.c > > +++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-25.c > > @@ -1,5 +1,5 @@ > > /* { dg-do compile } */ > > -/* { dg-options "-O2 -fdump-ipa-icf-optimized-all" } */ > > +/* { dg-options "-O2 -fdump-ipa-icf-optimized-all -fno-ipa-vrp" } */ > > > > static int zip(); > > static int zap(); > > diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c > > index 57c5262dd4a..a8824d040e5 100644 > > --- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c > > +++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c > > @@ -1,6 +1,6 @@ > > /* { dg-do link } */ > > /* { dg-require-alias "" } */ > > -/* { dg-options "-O2 -fdump-ipa-icf-optimized -flto -fdump-tree-optimized" } */ > > +/* { dg-options "-O2 -fdump-ipa-icf-optimized -flto -fdump-tree-optimized -fno-ipa-vrp" } */ > > /* { dg-require-effective-target lto } */ > > /* { dg-additional-sources "ipa-icf-38a.c" }*/ > > > > diff --git a/gcc/testsuite/gcc.dg/ipa/pure-const-1.c b/gcc/testsuite/gcc.dg/ipa/pure-const-1.c > > index dd58457b629..10b572781c7 100644 > > --- a/gcc/testsuite/gcc.dg/ipa/pure-const-1.c > > +++ b/gcc/testsuite/gcc.dg/ipa/pure-const-1.c > > @@ -1,5 +1,5 @@ > > /* { dg-do compile { target { nonpic || pie_enabled } } } */ > > -/* { dg-options "-O3 -fdump-tree-local-pure-const1 -fdump-ipa-pure-const -fdump-tree-optimized -fno-early-inlining -fgnu89-inline" } */ > > +/* { dg-options "-O3 -fno-ipa-vrp -fdump-tree-local-pure-const1 -fdump-ipa-pure-const -fdump-tree-optimized -fno-early-inlining -fgnu89-inline" } */ > > void abort (void); > > int error_code; > > static int val; > > diff --git a/gcc/testsuite/gcc.dg/ipa/remref-0.c b/gcc/testsuite/gcc.dg/ipa/remref-0.c > > index 6073c028a98..497136e3607 100644 > > --- a/gcc/testsuite/gcc.dg/ipa/remref-0.c > > +++ b/gcc/testsuite/gcc.dg/ipa/remref-0.c > > @@ -3,7 +3,7 @@ > > /* { dg-do compile } */ > > /* { dg-options "-O3 -fno-early-inlining -fno-ipa-sra -fno-ipa-cp -fdump-ipa-inline -fdump-tree-optimized" } */ > > > > -extern int __attribute__ ((noinline, noclone, used)) > > +extern int __attribute__ ((noinline, noclone, used, noipa)) > > stuff (int i) > > { > > return 0; > > diff --git a/gcc/testsuite/gcc.dg/tree-prof/time-profiler-1.c b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-1.c > > index 455f923f3f4..3f1d1e04619 100644 > > --- a/gcc/testsuite/gcc.dg/tree-prof/time-profiler-1.c > > +++ b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-1.c > > @@ -1,4 +1,4 @@ > > -/* { dg-options "-O2 -fdump-ipa-profile" } */ > > +/* { dg-options "-O2 -fdump-ipa-profile -fno-ipa-vrp" } */ > > > > __attribute__ ((noinline)) > > int foo() > > diff --git a/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c > > index e6eaeb99810..eed0b1dd08d 100644 > > --- a/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c > > +++ b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c > > @@ -1,4 +1,4 @@ > > -/* { dg-options "-O2 -fdump-ipa-profile" } */ > > +/* { dg-options "-O2 -fdump-ipa-profile -fno-ipa-vrp" } */ > > > > #include > > > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110269.c b/gcc/testsuite/gcc.dg/tree-ssa/pr110269.c > > index c68a6f91604..dd5022f3b0c 100644 > > --- a/gcc/testsuite/gcc.dg/tree-ssa/pr110269.c > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110269.c > > @@ -1,5 +1,5 @@ > > /* { dg-do compile } */ > > -/* { dg-options "-O2 -fdump-tree-ccp2 -fdump-tree-optimized" } */ > > +/* { dg-options "-O2 -fdump-tree-ccp2 -fdump-tree-optimized -fno-ipa-vrp" } */ > > > > void foo(void); > > static int a = 1, c; > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c b/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c > > index f05076cafac..3a7c03b27ff 100644 > > --- a/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c > > @@ -1,5 +1,5 @@ > > /* { dg-do compile } */ > > -/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining -fdelete-null-pointer-checks -fno-thread-jumps" } */ > > +/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining -fdelete-null-pointer-checks -fno-thread-jumps -fno-ipa-vrp" } */ > > > > typedef struct { > > int code; > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/return-value-range-1.c b/gcc/testsuite/gcc.dg/tree-ssa/return-value-range-1.c > > new file mode 100644 > > index 00000000000..4db52233c5d > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/return-value-range-1.c > > @@ -0,0 +1,22 @@ > > +/* { dg-do ling } */ > > +/* { dg-options "-O1 -dump-tree-evrp-details" } */ > > +__attribute__ ((__noinline__)) > > +int a(char c) > > +{ > > + return c; > > +} > > +void link_error (); > > + > > +void > > +test(int d) > > +{ > > + if (a(d) > 200) > > + link_error (); > > +} > > +int > > +main(int argc, char **argv) > > +{ > > + test(argc); > > + return 0; > > +} > > +/* { dg-final { scan-tree-dump-times "Recording return range" 2 "evrp"} } */ > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp05.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp05.c > > index 7f38e8d3852..f7ba16c20bb 100644 > > --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp05.c > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp05.c > > @@ -1,5 +1,5 @@ > > /* { dg-do compile } */ > > -/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining -fno-thread-jumps" } */ > > +/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining -fno-thread-jumps -fno-ipa-vrp" } */ > > > > > > inline int ten() > > diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc > > index 917fa873714..82001eff20e 100644 > > --- a/gcc/tree-vrp.cc > > +++ b/gcc/tree-vrp.cc > > @@ -52,6 +52,12 @@ along with GCC; see the file COPYING3. If not see > > #include "gimple-fold.h" > > #include "tree-dfa.h" > > #include "tree-ssa-dce.h" > > +#include "alloc-pool.h" > > +#include "cgraph.h" > > +#include "symbol-summary.h" > > +#include "ipa-utils.h" > > +#include "ipa-prop.h" > > +#include "attribs.h" > > > > // This class is utilized by VRP and ranger to remove __builtin_unreachable > > // calls, and reflect any resulting global ranges. > > @@ -1081,6 +1087,51 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p, > > array_checker.check (); > > } > > > > + > > + if (Value_Range::supports_type_p (TREE_TYPE > > + (TREE_TYPE (current_function_decl))) > > + && flag_ipa_vrp > > + && !lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl))) > > + { > > + edge e; > > + edge_iterator ei; > > + bool found = false; > > + Value_Range return_range (TREE_TYPE (TREE_TYPE (current_function_decl))); > > + FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) > > + if (greturn *ret = dyn_cast (*gsi_last_bb (e->src))) > > + { > > + tree retval = gimple_return_retval (ret); > > + if (!retval) > > + { > > + return_range.set_varying (TREE_TYPE (TREE_TYPE (current_function_decl))); > > + found = true; > > + continue; > > + } > > + Value_Range r (TREE_TYPE (retval)); > > + if (ranger->range_of_expr (r, retval, ret) > > + && !r.undefined_p () > > + && !r.varying_p ()) > > + { > > + if (!found) > > + return_range = r; > > + else > > + return_range.union_ (r); > > + } > > + else > > + return_range.set_varying (TREE_TYPE (retval)); > > + found = true; > > + } > > + if (found && !return_range.varying_p ()) > > + { > > + ipa_record_return_value_range (return_range); > > + if (POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))) > > + && return_range.nonzero_p () > > + && cgraph_node::get (current_function_decl) > > + ->add_detected_attribute ("returns_nonnull")) > > + warn_function_returns_nonnull (current_function_decl); > > + } > > + } > > + > > phi_analysis_finalize (); > > disable_ranger (fun); > > scev_finalize ();