目次: GCC
実はGCC 9.1ではcarg, atan2を並べてもエラーが発生しませんので、バグがどこかで直っています。GCC 9.1と8.3の動作の違いを調べることで、原因と直し方がわかるはずです。
GIMPLEを出力しながらコードを追っていくと、下記の関数でcargがatan2に変換され、その後internal compile errorになるようです。
// gcc/gcc/builtins.c
/* Fold a call to builtin carg(a+bi) -> atan2(b,a). */
static tree
fold_builtin_carg (location_t loc, tree arg, tree type)
{
if (validate_arg (arg, COMPLEX_TYPE)
&& TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
{
tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2); //★★この関数がNULL以外を返す条件がある
if (atan2_fn)
{
tree new_arg = builtin_save_expr (arg); //★★ここにくるとcarg → atan2に変換される
tree r_arg = fold_build1_loc (loc, REALPART_EXPR, type, new_arg);
tree i_arg = fold_build1_loc (loc, IMAGPART_EXPR, type, new_arg);
return build_call_expr_loc (loc, atan2_fn, 2, i_arg, r_arg);
}
}
return NULL_TREE;
}
関数mathfn_built_in() はbuiltin_info[uns_fncode].implicit_pがセットされていないとNULLを返す仕組みになっています。
// gcc/gcc/builtins.c
/* Like mathfn_built_in_1, but always use the implicit array. */
tree
mathfn_built_in (tree type, combined_fn fn)
{
return mathfn_built_in_1 (type, fn, /*implicit=*/ 1); //★★
}
/* Return mathematic function equivalent to FN but operating directly on TYPE,
if available. If IMPLICIT_P is true use the implicit builtin declaration,
otherwise use the explicit declaration. If we can't do the conversion,
return null. */
static tree
mathfn_built_in_1 (tree type, combined_fn fn, bool implicit_p)
{
built_in_function fcode2 = mathfn_built_in_2 (type, fn);
if (fcode2 == END_BUILTINS)
return NULL_TREE;
if (implicit_p && !builtin_decl_implicit_p (fcode2)) //★★implicit_pフラグがセットされないと変換されない
return NULL_TREE;
return builtin_decl_explicit (fcode2); //★★指定された数学関数のtreeを返す(今回はatan2f)
}
// gcc/gcc/tree.h
/* Return whether the standard builtin function can be used implicitly. */
static inline bool
builtin_decl_implicit_p (enum built_in_function fncode)
{
size_t uns_fncode = (size_t)fncode;
gcc_checking_assert (BUILTIN_VALID_P (fncode));
return (builtin_info[uns_fncode].decl != NULL_TREE
&& builtin_info[uns_fncode].implicit_p); //★★implicit_pフラグがセットされないと変換されない
}
// gcc/gcc/builtins.c
#define CASE_MATHFN(MATHFN) \
CASE_CFN_##MATHFN: \
fcode = BUILT_IN_##MATHFN; fcodef = BUILT_IN_##MATHFN##F ; \
fcodel = BUILT_IN_##MATHFN##L ; break;
/* Return a function equivalent to FN but operating on floating-point
values of type TYPE, or END_BUILTINS if no such function exists.
This is purely an operation on function codes; it does not guarantee
that the target actually has an implementation of the function. */
static built_in_function
mathfn_built_in_2 (tree type, combined_fn fn)
{
tree mtype;
...
switch (fn)
{
...
CASE_MATHFN (ATAN)
CASE_MATHFN (ATAN2) //★★ここにヒットしてbreak
CASE_MATHFN (ATANH)
CASE_MATHFN (CBRT)
...
default:
return END_BUILTINS;
}
mtype = TYPE_MAIN_VARIANT (type);
if (mtype == double_type_node)
return fcode;
else if (mtype == float_type_node)
return fcodef; //★★ここにくる、返り値はBUILTIN_ATAN2F
else if (mtype == long_double_type_node)
return fcodel;
...
else if (mtype == float128x_type_node)
return fcodef128x;
else
return END_BUILTINS;
}
しかし、cargf → atan2f変換自体はおかしいことではないはずです。
GCC 9.1と動作を比較してみます。
GCC 9.1 (OK) | GCC 8.3 (NG) |
---|---|
analyze_functions(true) でimplicit_p: false → true | analyze_functions(true) でimplicit_p: false → true |
pass_lower_cfでcargf → atan2fに置き換え | pass_forwpropでcargf → atan2fに置き換え |
pass_lower_cfでimplicit_p: true → true | pass_forwpropでimplicit_p: true → true |
pass_build_ssaでvuseがSSA_NAMEに置き換わる | (VAR_DECLのまま) |
pass_forwpropでsimplify_builtin_call() | pass_forwpropでsimplify_builtin_call() → エラー!! |
パスの実行順序は早い順にpass_lower_cf (008t.lower), pass_build_ssa (019t.ssa), pass_forwprop (029t.forwprop1) になります。カッコ内はGCC 9.1でdump-tree-allを指定したときのダンプファイルとの対応です。8.3の場合はpass_forwprop (033t.forwprop) になります。
動作の違いはcargf() → atan2f() の変換が行われるパスです。GCC 9.1はpass_lower_cfですが、GCC 8.3はpass_forwpropです。GCC 9.1は序盤のパスでcargf() → atan2f() の変換が行われるため、pass_build_ssaでvuseが適切に書き換えられて救われるようです。
光明が見えてきました。
< | 2021 | > | ||||
<< | < | 04 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | - | 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | - |
合計:
本日:
管理者: Katsuhiro Suzuki(katsuhiro( a t )katsuster.net)
This is Simple Diary 1.0
Copyright(C) Katsuhiro Suzuki 2006-2023.
Powered by PHP 8.2.15.
using GD bundled (2.1.0 compatible)(png support.)