On Fri, Sep 26, 2014 at 10:29:57AM +0200, FX wrote:
> Hi,
> 
> I’m trying to make the Fortran front-end emit calls to some builtins we don’t 
> currently use (isfinite, isnormal). However, trying to use the same code as 
> isnan doesn’t work at all. Our gfc_define_builtin does three things:
> 
>   decl = add_builtin_function (name, type, code, BUILT_IN_NORMAL, 
> library_name, NULL_TREE);
>   set_call_expr_flags (decl, attr);
>   set_builtin_decl (code, decl, true);
> 
> While doing so works with isnan, it fails with isfinite or isnormal. When I 
> try to, I get an ICE in tree checking:
> 
>   * frame #0: 0x0000000100c02338 f951`build_call_expr_loc_array(loc=0, 
> fndecl=0x0000000000000000, n=2, argarray=0x00007fff5fbfeb20) + 24 at 
> tree.h:2846
>     frame #1: 0x0000000100c0259a f951`build_call_expr(fndecl=<unavailable>, 
> n=<unavailable>) + 186 at tree.c:10550
>     frame #2: 0x000000010046f671 
> f951`fold_builtin_interclass_mathfn(loc=<unavailable>, fndecl=<unavailable>, 
> arg=0x000000014340c990) + 337 at builtins.c:9393
>     frame #3: 0x0000000100485e34 f951`fold_builtin_1(loc=260, 
> fndecl=0x0000000143449360, arg0=0x000000014340c990, ignore=<unavailable>) + 
> 2964 at builtins.c:10050
>     frame #4: 0x000000010049030c f951`fold_builtin_n(loc=<unavailable>, 
> fndecl=<unavailable>, args=<unavailable>, nargs=<unavailable>, 
> ignore=<unavailable>) + 1116 at builtins.c:10409
>     frame #5: 0x0000000100491c33 f951`fold_builtin_call_array(loc=260, 
> type=0x0000000143405690, fn=0x000000014351fc40, n=1, 
> argarray=0x00007fff5fbfeeb0) + 355 at builtins.c:10575
>     frame #6: 0x0000000100c024c5 f951`build_call_expr_loc(loc=<unavailable>, 
> fndecl=<unavailable>, n=<unavailable>) + 181 at tree.c:10533
> 
> 
> I don’t understand how the middle-end builtins decl should work, would 
> someone have a hint of how to fix this?

Just look what foold_builtin_interclass_mathfn does:
isfinite(x) -> islessequal(fabs(x),DBL_MAX)
isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) & islessequal(fabs(x),DBL_MAX)

Thus, the middle-end assumes that if you have __builtin_{isfinite,isnormal},
you also have __builtin_is{less,greater}equal builtins too.
Just create those too and you'll be fine (they are also typegeneric, like
__builtin_is{finite,normal}), i.e. they take ... arguments and the FE is
supposed to verify they are ok (or, if the FE creates them artificially, it
will ensure that too).

        Jakub

Reply via email to