On Thu, Aug 17, 2017 at 1:06 PM, Richard Sandiford
<richard.sandif...@linaro.org> wrote
> Richard Biener <richard.guent...@gmail.com> writes:
>> On Thu, Aug 17, 2017 at 11:49 AM, Richard Sandiford
>> <richard.sandif...@linaro.org> wrote:
>>> Internal functions that map directly to an optab can only throw an
>>> exception for -fnon-call-exceptions.  This patch handles that in
>>> internal_fn_flags, in a similar way to ATTR_*NOTHROW in builtins.def.
>>>
>>> (Functions that don't throw even for flag_non_call_exceptions should be
>>> explicitly marked ECF_NOTHROW in internal-fn.def.)
>>>
>>> Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK to install?
>>
>> Hmm.  Note the outcome of flag_non_call_exceptions depends on the
>> current function and thus IPA passes querying flags would need to
>> push an appropriate function context.  This means the function should
>> get a struct function * argument and opt_for_fn (fn, 
>> flag_non_call_exceptions)
>> should be used.  It doesn't help very much that all callers don't have
>> any such context either which means this "optimization" looks like
>> in the wrong place :/  (the global value of flag_non_call_exceptions in
>> the IPA case isn't necessarily conservative).
>>
>> So if you insist then add a comment and add a && cfun check so
>> we're sure we are in non-IPA context (or in properly setup context).
>
> Bah.  In that case, what should happen if a -fno-non-call-exceptions
> function is inlined into an -fnon-call-exceptions one?  Should the call
> keep the NOTHROWness of the original function, or should it lose
> NOTHROWness (and thus gain an exception edge)?

nothrow-ness is tracked on the GIMPLE stmt via gimple_call_[set_]nothrow_p,
GIMPLE shouldn't look at flag_non_call_exceptions, it is basically part
of the IL.

> I guess the path of least resistance would be to add an extra check
> for this case in the places that need it, rather than relying solely
> on gimple_call_flags.

Well, gimple_call_flags works fine already (looking at the above in
addition to internal_fn_flags).  call_expr_flags looks like it might not.

Richard.

>
> Thanks,
> Richard
>
>
>>
>> Richard.
>>
>>> Richard
>>>
>>>
>>> 2017-08-17  Richard Sandiford  <richard.sandif...@linaro.org>
>>>
>>> gcc/
>>>         * internal-fn.h (internal_fn_flags): Just declare and move
>>>         the actual implementation out-of-line to...
>>>         * internal-fn.c (internal_fn_flags): ...here.  Set ECF_NOTHROW for
>>>         directly-mapped internal functions if !flag_non_call_exceptions.
>>>
>>> Index: gcc/internal-fn.h
>>> ===================================================================
>>> --- gcc/internal-fn.h   2017-02-23 19:54:03.000000000 +0000
>>> +++ gcc/internal-fn.h   2017-08-17 09:05:37.459968561 +0100
>>> @@ -107,15 +107,7 @@ internal_fn_name (enum internal_fn fn)
>>>    return internal_fn_name_array[(int) fn];
>>>  }
>>>
>>> -/* Return the ECF_* flags for function FN.  */
>>> -
>>> -extern const int internal_fn_flags_array[];
>>> -
>>> -static inline int
>>> -internal_fn_flags (enum internal_fn fn)
>>> -{
>>> -  return internal_fn_flags_array[(int) fn];
>>> -}
>>> +extern int internal_fn_flags (enum internal_fn fn);
>>>
>>>  /* Return fnspec for function FN.  */
>>>
>>> Index: gcc/internal-fn.c
>>> ===================================================================
>>> --- gcc/internal-fn.c   2017-08-10 14:36:07.453493083 +0100
>>> +++ gcc/internal-fn.c   2017-08-17 09:05:37.459968561 +0100
>>> @@ -2814,3 +2814,18 @@ expand_PHI (internal_fn, gcall *)
>>>  {
>>>      gcc_unreachable ();
>>>  }
>>> +
>>> +/* Return the ECF_* flags for function FN.  */
>>> +
>>> +int
>>> +internal_fn_flags (enum internal_fn fn)
>>> +{
>>> +  int flags = internal_fn_flags_array[(int) fn];
>>> +  /* Functions that map to optabs can only throw a catchable exception
>>> +     when non-call exceptions are enabled.  The non-call exceptions in
>>> +     these cases will typically come from things like IEEE exceptions,
>>> +     divide by zero errors and SEGVs.  */
>>> +  if (direct_internal_fn_p (fn) && !flag_non_call_exceptions)
>>> +    flags |= ECF_NOTHROW;
>>> +  return flags;
>>> +}

Reply via email to