I’m woking on TARGET_PROMOTE_FUNCTION_MODE for csky, and now there’s some confusion.
For csky, the “POMOTE_MODE” is: qi/hi -> si the code is #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \ if (GET_MODE_CLASS (MODE) == MODE_INT \ && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \ (MODE) = SImode; And the TARGET_PROMOTE_FUNCTION_MODE is default_promote_function_mode_always_promote. I expected it can work as “POMOTE_MODE” just as the description at “gcc internal”. But it calls promote_mode() and treat “libcalls” specially.: machine_mode promote_mode (const_tree type ATTRIBUTE_UNUSED, machine_mode mode, int *punsignedp ATTRIBUTE_UNUSED) { #ifdef PROMOTE_MODE enum tree_code code; int unsignedp; scalar_mode smode; #endif /* For libcalls this is invoked without TYPE from the backends TARGET_PROMOTE_FUNCTION_MODE hooks. Don't do anything in that case. */ if (type == NULL_TREE) return mode; …… Why don’t promote the mode here? And when I compile runtime library, the “char” and “short” args are promoted WITHOUT special treatment! So, I modified the code to make sure the TARGET_PROMOTE_FUNCTION_MODE work as POMOTE_MODE: #undef TARGET_PROMOTE_FUNCTION_MODE #define TARGET_PROMOTE_FUNCTION_MODE \ csky_promote_function_mode …… static machine_mode csky_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, machine_mode mode, int *punsignedp ATTRIBUTE_UNUSED, const_tree fntype ATTRIBUTE_UNUSED, int for_return ATTRIBUTE_UNUSED) { if (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE_SIZE (mode) < UNITS_PER_WORD) return SImode; return mode; } But this code could lead to another mistake when I use some builtin functions. The __sync_val_compare_and_swap_1() coded at “libgcc/config/csky/linux-atomic.c” use type “unsigned char” as its argrument. And this is consistent with the definition at gcc/builtins.def. But when the code run at emit_library_call_value_1, all of the args are treated as “signed”. Part of source code of emit_library_call_value_1 ↓. The “unsigned_p” was inited to 0, and was used at prmote_funciton_mode without reassignment. for (unsigned int i = 0; count < nargs; i++, count++) { rtx val = args[i].first; function_arg_info arg (args[i].second, /*named=*/true); int unsigned_p = 0; …… arg.mode = promote_function_mode (NULL_TREE, arg.mode, &unsigned_p, NULL_TREE, 0); argvec[count].mode = arg.mode; argvec[count].value = convert_modes (arg.mode, GET_MODE (val), val, unsigned_p); argvec[count].reg = targetm.calls.function_arg (args_so_far, arg); …… What’s reason for this act?