https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95558
--- Comment #23 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.