https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95558

--- Comment #22 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
It is ipa-pure-const marking w to be pure:

#0  ipa_make_function_pure (node=0x7ffff75fb220, looping=false, local=false) at
../../gcc/ipa-pure-const.cc:1539
#1  0x00000000016e9f93 in propagate_pure_const () at
../../gcc/ipa-pure-const.cc:1844
#2  0x00000000016eaa23 in (anonymous namespace)::pass_ipa_pure_const::execute
(this=0x4ad8fb0) at ../../gcc/ipa-pure-const.cc:2112
#3  0x00000000018aee56 in execute_one_pass (pass=0x4ad8fb0) at
../../gcc/passes.cc:2656
#4  0x00000000018aff5b in execute_ipa_pass_list (pass=0x4ad8fb0) at
../../gcc/passes.cc:3118
#5  0x00000000012bc103 in ipa_passes () at ../../gcc/cgraphunit.cc:2302
#6  0x00000000012bc2f4 in symbol_table::compile (this=0x7ffff7406000) at
../../gcc/cgraphunit.cc:2367
#7  0x00000000012bc901 in symbol_table::finalize_compilation_unit
(this=0x7ffff7406000) at ../../gcc/cgraphunit.cc:2626
#8  0x0000000001a46219 in compile_file () at ../../gcc/toplev.cc:482
#9  0x0000000001a4970d in do_compile () at ../../gcc/toplev.cc:2225
#10 0x0000000001a49b74 in toplev::main (this=0x7fffffffdc5a, argc=3,
argv=0x7fffffffdd88) at ../../gcc/toplev.cc:2389
#11 0x00000000038c7586 in main (argc=3, argv=0x7fffffffdd88) at
../../gcc/main.cc:39

tarting cycle
  Visiting dummy/1 state:const looping 0
Result const looping 0
Function found not to call free: dummy/1
Starting cycle
  Visiting w/3 state:const looping 0
    Call to weak/2 const
Dropping state to PURE because call to weak/2 may not bind to current def.
Result pure looping 0
Function found to be pure: w/3

So it drops to PURE but it should drop to NEITHER

diff --git a/gcc/ipa-pure-const.cc b/gcc/ipa-pure-const.cc
index 5024e488692..b1a3f93acad 100644
--- a/gcc/ipa-pure-const.cc
+++ b/gcc/ipa-pure-const.cc
@@ -517,6 +517,14 @@ worse_state (enum pure_const_state_e *state, bool
*looping,
                 "bind to current def.\n", to->dump_name ());
       state2 = IPA_PURE;
     }
+  if (*state == IPA_CONST && state2 == IPA_PURE
+      && to && !DECL_PURE_P (to->decl) && !to->binds_to_current_def_p (from))
+    {
+      if (dump_file && (dump_flags & TDF_DETAILS))
+       fprintf (dump_file, "Dropping state to NEITHER because call to %s may
not "
+                "bind to current def.\n", to->dump_name ());
+      state2 = IPA_NEITHER;
+    }
   *state = MAX (*state, state2);
   *looping = MAX (*looping, looping2);
 }

This just copies the earlier hunk that is trying to handle the problem of
semantic differences
  /* Consider function:

     bool a(int *p)
     {
       return *p==*p;
     }

     During early optimization we will turn this into:

     bool a(int *p)
     {
       return true;
     }

     Now if this function will be detected as CONST however when interposed it
     may end up being just pure.  We always must assume the worst scenario
here.
   */
  if (*state == IPA_CONST && state2 == IPA_CONST
      && to && !TREE_READONLY (to->decl) && !to->binds_to_current_def_p (from))
    { 
      if (dump_file && (dump_flags & TDF_DETAILS))
        fprintf (dump_file, "Dropping state to PURE because call to %s may not
"
                 "bind to current def.\n", to->dump_name ());
      state2 = IPA_PURE;
    }

We should use availability the call (since call may go through noninterposable
alias).
ipa-pure-const is organized in bit of awkward way so one can not check
availability inside of SCC components easily, but modref does same job and
should get this right.

Reply via email to