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; >>> +}