On February 16, 2019 8:12:34 AM GMT+01:00, Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >Both the C and C++ standard guarantee that the argc argument to main is >non-negative, the following patch sets (or adjusts) the corresponding >SSA_NAME_RANGE_INFO. While main is just one, with IPA VRP it can also >propagate etc. I had to change one testcase because it started >optimizing >it better (the test has been folded away), so no sinking was done.
Can we handle this in _nonnegative_p? Also make it work independent of langhooks by looking up the translation unit decl from cfun via walking contexts? Is this a regression? Richard. >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > >2019-02-16 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/89350 > * gimple-ssa-evrp.c: Include tree-dfa.h and langhooks.h. > (maybe_set_main_argc_range): New function. > (execute_early_vrp): Call it. > > * gcc.dg/tree-ssa/vrp122.c: New test. > * gcc.dg/tree-ssa/ssa-sink-3.c (main): Rename to ... > (bar): ... this. > >--- gcc/gimple-ssa-evrp.c.jj 2019-01-01 12:37:15.712998659 +0100 >+++ gcc/gimple-ssa-evrp.c 2019-02-15 09:49:56.768534668 +0100 >@@ -41,6 +41,8 @@ along with GCC; see the file COPYING3. > #include "tree-cfgcleanup.h" > #include "vr-values.h" > #include "gimple-ssa-evrp-analyze.h" >+#include "tree-dfa.h" >+#include "langhooks.h" > > class evrp_folder : public substitute_and_fold_engine > { >@@ -291,6 +293,39 @@ evrp_dom_walker::cleanup (void) > evrp_folder.vr_values->cleanup_edges_and_switches (); > } > >+/* argc in main in C/C++ is guaranteed to be non-negative. Adjust the >+ range info for it. */ >+ >+static void >+maybe_set_main_argc_range (void) >+{ >+ if (!DECL_ARGUMENTS (current_function_decl) >+ || !(lang_GNU_C () || lang_GNU_CXX () || lang_GNU_OBJC ())) >+ return; >+ >+ tree argc = DECL_ARGUMENTS (current_function_decl); >+ if (TYPE_MAIN_VARIANT (TREE_TYPE (argc)) != integer_type_node) >+ return; >+ >+ argc = ssa_default_def (cfun, argc); >+ if (argc == NULL_TREE) >+ return; >+ >+ wide_int min, max; >+ value_range_kind kind = get_range_info (argc, &min, &max); >+ if (kind == VR_VARYING) >+ { >+ min = wi::zero (TYPE_PRECISION (integer_type_node)); >+ max = wi::to_wide (TYPE_MAX_VALUE (integer_type_node)); >+ } >+ else if (kind == VR_RANGE && wi::neg_p (min) && !wi::neg_p (max)) >+ min = wi::zero (TYPE_PRECISION (integer_type_node)); >+ else >+ return; >+ >+ set_range_info (argc, VR_RANGE, min, max); >+} >+ >/* Main entry point for the early vrp pass which is a simplified >non-iterative >version of vrp where basic blocks are visited in dominance order. >Value > ranges discovered in early vrp will also be used by ipa-vrp. */ >@@ -307,6 +342,10 @@ execute_early_vrp () > scev_initialize (); > calculate_dominance_info (CDI_DOMINATORS); > >+ /* argc in main in C/C++ is guaranteed to be non-negative. */ >+ if (MAIN_NAME_P (DECL_NAME (current_function_decl))) >+ maybe_set_main_argc_range (); >+ > /* Walk stmts in dominance order and propagate VRP. */ > evrp_dom_walker walker; > walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun)); >--- gcc/testsuite/gcc.dg/tree-ssa/vrp122.c.jj 2019-02-15 >09:54:07.016357759 +0100 >+++ gcc/testsuite/gcc.dg/tree-ssa/vrp122.c 2019-02-15 >09:53:59.299486561 +0100 >@@ -0,0 +1,14 @@ >+/* PR tree-optimization/89350 */ >+/* { dg-do compile } */ >+/* { dg-options "-O2 -fdump-tree-optimized" } */ >+/* { dg-final { scan-tree-dump-not "link_error \\\(" "optimized" } } >*/ >+ >+extern void link_error (void); >+ >+int >+main (int argc, const char *argv[]) >+{ >+ if (argc < 0) >+ link_error (); >+ return 0; >+} >--- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-3.c.jj 2015-05-29 >15:03:44.947546711 +0200 >+++ gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-3.c 2019-02-16 >08:04:29.951126611 +0100 >@@ -2,7 +2,7 @@ > /* { dg-options "-O2 -fdump-tree-sink-stats" } */ > extern void foo(int a); > int >-main (int argc) >+bar (int argc) > { > int a; > a = argc + 1; > > Jakub