Richard Biener <richard.guent...@gmail.com> writes:
> On Mon, Dec 6, 2021 at 11:10 AM Richard Sandiford
> <richard.sandif...@arm.com> wrote:
>>
>> Richard Biener <richard.guent...@gmail.com> writes:
>> > On Sun, Dec 5, 2021 at 10:59 PM Richard Sandiford via Gcc-patches
>> > <gcc-patches@gcc.gnu.org> wrote:
>> >>
>> >> When compiling an optabs.ii at -O2 with a release-checking build,
>> >> we spent a lot of time in call_may_clobber_ref_p.  One of the
>> >> first things the function tries is the get_modref_function_summary
>> >> approach, but that also seems to be the most expensive check.
>> >> At least for the optabs.ii test, most of the things g_m_f_s could
>> >> handle could also be handled by points-to analysis, which is much
>> >> cheaper.
>> >>
>> >> This patch therefore rearranges the tests in approximate order
>> >> of cheapness.  One wart is that points-to analysis can't be
>> >> used on its own for this purpose; it has to be used in
>> >> conjunction with check_fnspec.  This is because the argument
>> >> information in the fnspec is not reflected in the points-to
>> >> information, which instead contains overly optimistic (rather
>> >> than conservatively pessimistic) information.
>> >>
>> >> Specifically, find_func_aliases_for_builtin_call short-circuits
>> >> the handle_rhs_call/handle_call_arg logic and doesn't itself add
>> >> any compensating information about the arguments.  This means that:
>> >>
>> >>   free (foo)
>> >>
>> >> does not have an points-to information for foo (it has an empty
>> >> set instead).
>> >
>> > Huh?  The gimple_call_use/clobber_sets should be conservative
>> > and stand on their own.  Can you share a testcase that breaks when
>> > returning early if independent_pt?  Does this  problem also exist
>> > on the branch?
>>
>> With the attached patch to disable get_modref_function_summary,
>> do the PT query ahead of the fnspec query, and assert if the fnspec
>> query would have found an alias, I get the following results for
>> execute.exp on x86_64-linux-gnu (full log attached):
>>
>> # of expected passes            44554
>> # of unexpected failures        1710
>> # of unresolved testcases       855
>> # of unsupported tests          62
>>
>> E.g. for execute/20000703-1.c, the assertion trips for:
>>
>> 3786              if (stmt_may_clobber_ref_p_1 (def_stmt, ref, tbaa_p))
>> (gdb) call debug (def_stmt)
>> __builtin_memset (p_3(D), 0, 28);
>> (gdb) call debug (ref.base)
>> *p_3(D)
>> (gdb) call pt_solution_includes (&((gcall *) def_stmt)->call_clobbered, 
>> ref.base)
>> $3 = false
>
> huh, well - *p_3(D) isn't a DECL and pt_solution_includes just works for 
> decls.
> In fact it should eventually ICE even ;)

Oops, yes.  That's what comes of trying to be fancy and doing things
in a gdb session rather than printfs. :-)  It is of course the:

  else if ((TREE_CODE (base) == MEM_REF
            || TREE_CODE (base) == TARGET_MEM_REF)
           && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
    {
      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
      if (pi
          && !pt_solutions_intersect (gimple_call_clobber_set (call), &pi->pt))
        {

path that fails the assert.

> That said, nothing should
> really iniitalize
> the call_clobber set besides pt_solution_reset at GIMPLE stmt allocation time
> or IPA PTA when enabled.  pt_solutuon_reset sets ->anything to true so the
> function should return true ...

Yeah, it works OK in the reset state.

> It looks like Honza added computation of these sets at some point, also maybe
> forgetting to set some bits here.
>
> I prefer to investigate / fix this before refactoring the uses in this way.  
> Can
> you file a bugreport please?  I can reproduce the memcpy FAIL with
> just moving check_fnspec down.

OK, filed as PR103584 (for the list).

Thanks,
Richard

>
> Thanks,
> Richard.
>
>> Setting ASSERTS to 0 gives:
>>
>> FAIL: gcc.c-torture/execute/memcpy-1.c   -O2  execution test
>> FAIL: gcc.c-torture/execute/memcpy-1.c   -O2 -flto -fno-use-linker-plugin 
>> -flto-partition=none  execution test
>> FAIL: gcc.c-torture/execute/memcpy-1.c   -O2 -flto -fuse-linker-plugin 
>> -fno-fat-lto-objects  execution test
>> FAIL: gcc.c-torture/execute/memcpy-1.c   -O3 -fomit-frame-pointer 
>> -funroll-loops -fpeel-loops -ftracer -finline-functions  execution test
>> FAIL: gcc.c-torture/execute/memcpy-1.c   -O3 -g  execution test
>> FAIL: gcc.c-torture/execute/memcpy-1.c   -Os  execution test
>> FAIL: gcc.c-torture/execute/memset-3.c   -O3 -fomit-frame-pointer 
>> -funroll-loops -fpeel-loops -ftracer -finline-functions  execution test
>> FAIL: gcc.c-torture/execute/memset-3.c   -O3 -g  execution test
>>
>> # of expected passes            23138
>> # of unexpected failures        8
>> # of unsupported tests          24
>>
>> (same for -m32).
>>
>> Originally I saw it as a bootstrap failure building stage 2
>> build-side libcpp, due to a bogus uninitialised warning.
>>
>> But alongside the memset and free examples, there's:
>>
>>       /* All the following functions do not return pointers, do not
>>          modify the points-to sets of memory reachable from their
>>          arguments and do not add to the ESCAPED solution.  */
>>       case BUILT_IN_SINCOS:
>>       case BUILT_IN_SINCOSF:
>>       ...
>>         return true;
>>
>> (always an empty set), whereas check_fnspec takes errno into account.
>>
>> > I wonder if, at this point, we should split the patch up to do the
>> > trivial move of the ao_ref_base dependent and volatile checks
>> > and leave this more complicated detail for a second patch?
>>
>> Yeah, that'd work, but in practice it was the PT part that was the
>> high-value part.  IIRC the early base checks caught less than 1% of
>> cases (I can rerun tonight to get exact numbers).
>>
>> Thanks,
>> Richard
>>

Reply via email to