From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by sourceware.org (Postfix) with ESMTPS id BD49F3858D35 for ; Thu, 23 Nov 2023 07:24:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BD49F3858D35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org BD49F3858D35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::635 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700724261; cv=none; b=AnNDO4OkwX62zCnFl8q3zXOyq/hBGJ3CacLS/qx5fytCtf/pmvs5kQ2KnN1HYozul/tOi1yY/L8Am7amQF7F+bq3uDTN+nPrfhWGL9B78Sdoz4s+mtQ12IkXcogxFs1SiQBVrj/w+IyzetmGDkvzLglwS+CP800vrT3Yq0/pDIw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700724261; c=relaxed/simple; bh=ESqtzY97piOTEIFo6fGrlXDmQ1R/U02bBiwLs3m5Rbw=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=Bl/ATY3/kuJrNUZ/EMeiPXlbi//sdHuzqnovK/TOUZXgMHHF9HYxS9NNUmJ//9pHWjSKQfat+pQwnDiuWQMpu9m+PNIO4p7ouFzYb123SWnhnT5C7qlWzd7ihu32QSqtzNGV2GHrP80x/WsLY7aGTmHjWwosBqzkMh2+veSkdbg= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x635.google.com with SMTP id d9443c01a7336-1cc0d0a0355so4072525ad.3 for ; Wed, 22 Nov 2023 23:24:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700724256; x=1701329056; darn=gcc.gnu.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=UV58iHLS+JwGPQu4kqVRTm4Q5kjKpV73djURqOs3HtE=; b=ZU5c0Kw1HpKLHeJb9RWRZGh8VXxIiHdll9uAaruQ9EK9fZRLiOBtU2KT/oYJ9DS1ID 94Ok1q3A0dNdt8vZYsSEtC5Ew81gwcNbkdnxRFjr5bWNVEqy83dVJN92qpN+NFo44FI8 /rlqh4UIO6FVkUPCFTVhpwUH5An2HBle2l9uJJNbakzK8+t2PRx42bNWypNaXL5JLMDs WjwBrdOZufe1gVhXMh36W+Q6SxeFDBViLkqWsjeOOCr09Hwz7EYMpe+y207sa3/XyJLl sClHs0PaDp931R//iKQ5lNj1IgKmp0JT5suf1e0ysLPJdfP2t0tmhaRZVZJp6Jlatsv6 ZAxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700724256; x=1701329056; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UV58iHLS+JwGPQu4kqVRTm4Q5kjKpV73djURqOs3HtE=; b=KiA1mFT+NsGhr7/xN7/p33vOfsNfACriUsk+PDR7/ex8oOtTuXOcfeC5AHKRHP4u4U gOhAWnwfyEEDjHJRHycwxNWyu4kIN8IKwsuBrkrMh3tc3q2Hg9GY3+ih6L6i2+82tpnW NtKP4Ilv4R+oxYTHTK0Kgi2I1tT4S0vxgbCPlFhD2hM+bSVZn3+bejlVku99CgqYQs2z m25RRFxRDA0L1KrlS7pbRjXhAbhXU/ADhvtAERYEdivLdrjfo7ZLtvTY/rCPDRzALmzh LVcvAbQLomH8KcTt2JCLF2tGPOYvzz7FSMR8YjxzF6FEXRxzo8qmpcOMNsUJ1kKsNUBH 8SBw== X-Gm-Message-State: AOJu0Yxv1tGBmDRFUWP9OkvEKXtHMYDN25i8nhHE3W3gHapEew4D8CJF zdxl9ylSp4HExMaEg2veZ2EZ9r97x5hIrA8/nW0LBmU4evRodA== X-Google-Smtp-Source: AGHT+IH1mQs/+M5Eh6Iqa8Pemo6QbtV/E/zGaB4pEO8h/4ej2lnk3VmyO7jjSgIBKPNGwf/ox44uDtvr3yyeD2NcdgY= X-Received: by 2002:a17:90b:17c9:b0:27d:661f:59ac with SMTP id me9-20020a17090b17c900b0027d661f59acmr4717718pjb.38.1700724255364; Wed, 22 Nov 2023 23:24:15 -0800 (PST) MIME-Version: 1.0 References: <871qcmkmgd.fsf@gentoo.org> In-Reply-To: From: Andrew Pinski Date: Wed, 22 Nov 2023 23:24:03 -0800 Message-ID: Subject: Re: Propagate value ranges of return values To: Jan Hubicka , "Andrew Pinski (QUIC)" Cc: Christophe Lyon , Sam James , gcc-patches@gcc.gnu.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-8.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,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: On Tue, Nov 21, 2023 at 6:07=E2=80=AFAM Jan Hubicka wrote: > > > 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, l= sl 16 > > FAIL: gcc.target/aarch64/movk.c scan-assembler movk\tx[0-9]+, 0x7a3d, l= sl 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. This is the other change that needs to happen I think: diff --git a/gcc/testsuite/gcc.target/aarch64/simd/vmulx.x b/gcc/testsuite/gcc.target/aarch64/simd/vmulx.x index 8968a64a95c..869e7485646 100644 --- a/gcc/testsuite/gcc.target/aarch64/simd/vmulx.x +++ b/gcc/testsuite/gcc.target/aarch64/simd/vmulx.x @@ -33,13 +33,13 @@ while (0) \ /* Functions used to return values that won't be optimised away. */ -float32_t __attribute__ ((noinline)) +float32_t __attribute__ ((noipa)) foo32 () { return 1.0; } -float64_t __attribute__ ((noinline)) +float64_t __attribute__ ((noipa)) foo64 () { return 1.0; Thanks, Andrew Pinski > > 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) =3D tree_cons (get_identifier (at= tr), > > > + NULL_TREE, DECL_ATTRIBUTES (= node->decl)); > > > + *changed =3D true; > > > + } > > > + > > > + ipa_ref *ref; > > > + FOR_EACH_ALIAS (node, ref) > > > + { > > > + cgraph_node *alias =3D dyn_cast (ref->referring= ); > > > + if (alias->get_availability () > AVAIL_INTERPOSABLE) > > > + add_detected_attribute_1 (alias, attr, changed); > > > + } > > > + > > > + for (cgraph_edge *e =3D node->callers; e; e =3D 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 =3D 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 =3D dyn_cast (ref->referr= ing); > > > + 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 *chang= ed) > > > 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_n= ode : 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 functio= n. > > > When INCLUDE_OVERWRITABLE is false, overwritable aliases and th= unks 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=3Dmalloc > > > Common Var(warn_suggest_attribute_malloc) Warning > > > Warn about functions which might be candidates for __attribute__((ma= lloc)). > > > > > > +Wsuggest-attribute=3Dreturns_nonnull > > > +Common Warning > > > +Warn about functions which might be candidates for __attribute__((re= turns_nonnull)). > > > + > > > Wsuggest-final-types > > > Common Var(warn_suggest_final_types) Warning > > > Warn about C++ polymorphic types where adding final keyword would im= prove 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=3D > > > @opindex Wno-suggest-attribute=3D > > > -@item -Wsuggest-attribute=3D@r{[}pure@r{|}const@r{|}noreturn@r{|}for= mat@r{|}cold@r{|}malloc@r{]} > > > +@item -Wsuggest-attribute=3D@r{[}pure@r{|}const@r{|}noreturn@r{|}for= mat@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 belo= w. > > > @itemx -Wsuggest-attribute=3Dnoreturn > > > @itemx -Wmissing-noreturn > > > @itemx -Wsuggest-attribute=3Dmalloc > > > +@itemx -Wsuggest-attribute=3Dreturns_nonnull > > > +@itemx -Wno-suggest-attribute=3Dreturns_nonnull > > > > > > Warn about functions that might be candidates for attributes > > > -@code{pure}, @code{const} or @code{noreturn} or @code{malloc}. The c= ompiler > > > +@code{pure}, @code{const}, @code{noreturn}, @code{malloc} or @code{r= eturns_nonnull}. The compiler > > > only warns for functions visible in other compilation units or (in t= he case of > > > @code{pure} and @code{const}) if it cannot prove that the function r= eturns > > > normally. A function returns normally if it doesn't contain an infin= ite 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, gc= all *call, fur_source &) > > > else > > > r.set_varying (type); > > > > > > + tree callee =3D 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=3D*data; > > > + } > > > +}; > > > + > > > +/* Variable hoding the return value summary. */ > > > +static GTY(()) function_summary *ipa_re= turn_value_sum; > > > + > > > > > > /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl as= sociated > > > with NODE should prevent us from analyzing it for the purposes of= IPA-CP. */ > > > @@ -5915,5 +5944,49 @@ ipcp_transform_function (struct cgraph_node *n= ode) > > > 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 =3D cgraph_node::get (current_function_decl); > > > + if (!ipa_return_value_sum) > > > + { > > > + if (!ipa_vr_hash_table) > > > + ipa_vr_hash_table =3D hash_table::cre= ate_ggc (37); > > > + ipa_return_value_sum =3D 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 =3D 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 =3D cgraph_node::get (decl); > > > + if (!n || !ipa_return_value_sum) > > > + return false; > > > + enum availability avail; > > > + n =3D n->ultimate_alias_target (&avail); > > > + if (avail < AVAIL_AVAILABLE) > > > + return false; > > > + if (n->decl !=3D decl && !useless_type_conversion_p (TREE_TYPE (de= cl), TREE_TYPE (n->decl))) > > > + return false; > > > + ipa_return_value_summary *v =3D 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 va= l) > > > 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 > > > + =3D suggest_attribute (OPT_Wsuggest_attribute_returns_nonnull, d= ecl, > > > + true, warned_about, "returns_nonnull"); > > > +} > > > + > > > /* Check to see if the use (or definition when CHECKING_WRITE is tru= e) > > > 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: > > > =3D 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 !=3D 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 ca= ll > > > 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 inline= d > > > 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 wh= en > > > 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) eve= n > > > 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 -fn= o-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 u= noptimized > > > 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-constex= pr -flto -fdump-ipa-inline-details" } } */ > > > +/* { dg-lto-options { "-O2 -fno-early-inlining -fno-implicit-constex= pr -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/tes= tsuite/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/gc= c/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__((noinli= ne)); > > > -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__((noinli= ne,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/test= suite/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/gc= c.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/gc= c.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-opti= mized" } */ > > > +/* { dg-options "-O2 -fdump-ipa-icf-optimized -flto -fdump-tree-opti= mized -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-c= onst -fdump-tree-optimized -fno-early-inlining -fgnu89-inline" } */ > > > +/* { dg-options "-O3 -fno-ipa-vrp -fdump-tree-local-pure-const1 -fdu= mp-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 -f= dump-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/t= estsuite/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/t= estsuite/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 =3D 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-n= ull-pointer-checks -fno-thread-jumps" } */ > > > +/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining -fdelete-n= ull-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/g= cc/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 "evr= p"} } */ > > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp05.c b/gcc/testsuite/gc= c.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-threa= d-jumps" } */ > > > +/* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining -fno-threa= d-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_unre= achable > > > // 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_dec= l))) > > > + && flag_ipa_vrp > > > + && !lookup_attribute ("noipa", DECL_ATTRIBUTES (current_functi= on_decl))) > > > + { > > > + edge e; > > > + edge_iterator ei; > > > + bool found =3D false; > > > + Value_Range return_range (TREE_TYPE (TREE_TYPE (current_functi= on_decl))); > > > + FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) > > > + if (greturn *ret =3D dyn_cast (*gsi_last_bb (e->s= rc))) > > > + { > > > + tree retval =3D gimple_return_retval (ret); > > > + if (!retval) > > > + { > > > + return_range.set_varying (TREE_TYPE (TREE_TYPE (curre= nt_function_decl))); > > > + found =3D 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 =3D r; > > > + else > > > + return_range.union_ (r); > > > + } > > > + else > > > + return_range.set_varying (TREE_TYPE (retval)); > > > + found =3D 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 ();