On Tue, Oct 6, 2020 at 9:21 AM Alexandre Oliva <ol...@adacore.com> wrote: > > On Oct 6, 2020, Richard Biener <richard.guent...@gmail.com> wrote: > > > On October 6, 2020 3:15:02 AM GMT+02:00, Alexandre Oliva > > <ol...@adacore.com> wrote: > >> > >> This is a first step towards enabling the sincos optimization in Ada. > >> > >> The issue this patch solves is that sincos takes the type to be looked > >> up with mathfn_built_in from variables or temporaries in which results > >> of sin and cos are stored. In Ada, sin and cos are declared in an > >> internal aux package, with uses thereof in a standard generic package, > >> which ensures that the types are not what mathfn_built_in expects. > > > But are they not compatible? > > They are, in that they use the same underlying representation, but > they're distinct types, not associated with the same TYPE_MAIN_VARIANT. > > In Ada it's not unusual to have multiple floating-point types unrelated > to each other, even if they share identical underlying representation. > Each such type is a distinct type, in a similar sense that in C++ each > struct type holding a single double field is a distinct type. > > Each such distinct FP type gets a different instantiation of > Ada.Numerics.Generic_Elementary_Functions, just as a C++ template taking > a parameter type would get different instantiations for such different > struct types. > > > Overall, it's a very confusing situation. We use these alternate types > to declare the Sin and Cos functions imported from libm as intrinsics > (separate patch I've written very recently, yet to be contributed), and > they get matched to the libm intrinsics despite the distinct types, we > issue calls to them, passing variables of the alternate types without > explicit conversions, but when the sincos pass looks up the sincos/cexpi > intrinsic, it uses the alternate type taken from the variable and fails, > rather than the types declared as taken by the builtins.
OK, I see. mathfn_built_in expects a type inter-operating with the C ABI types (float_type_node, double_type_node, etc.) where "inter-operating" means having the same main variant. Now, I guess for the sincos pass we want to combine sinl + cosl to sincosl, independent on the case where the result would be assigned to a 'double' when 'double == long double'? Now what about sinl + cos when 'double == long double'? What I'm after is rather than going with sth like your patch use the original builtin code to derive the canonical C ABI type, sort-of a "reverse" mathfn_built_in. In execute_cse_sincos_1 we have the switch (gimple_call_combined_fn (use_stmt)) { CASE_CFN_COS: seen_cos |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0; break; CASE_CFN_SIN: seen_sin |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0; break; CASE_CFN_CEXPI: seen_cexpi |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0; break; default:; } switch so we _do_ have an idea what builtins we call and thus we could add a tree mathfn_type (combined_fn fn) { switch (fn) { case all-double-typed-fns: return double_type_node; case ...: ... } function that might prove useful in other places we're trying to find a "matching" alternate builtin function? Maybe this function can also simply look at the implicit/explicit defined decls but at least for the case of lrint using the return value will be misleading. Richard. > -- > Alexandre Oliva, happy hacker > https://FSFLA.org/blogs/lxo/ > Free Software Activist > GNU Toolchain Engineer