As the existing comment explains, we should always promote function arguments and return values. However, notwithstanding its name, default_promote_function_mode_always_promote does not always promote. Importantly, it does not for libcalls. This makes ftrapv-[12].c fail with 64-bit ABIs.
This patch introduces an rs6000_promote_function_mode that _does_ always promote, fixing this. Tested as usual (c,c++,fortran,ada; -m32,-m32/-mpowerpc64,-m64,-m64/-mlra). Is this okay for mainline? Segher 2015-01-14 Segher Boessenkool <seg...@kernel.crashing.org> gcc/ * config/rs6000/rs6000.c (TARGET_PROMOTE_FUNCTION_MODE): Implement as rs6000_promote_function_mode. Move comment to there. (rs6000_promote_function_mode): New function. --- gcc/config/rs6000/rs6000.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 4f8803d..ca5ce28 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1504,10 +1504,8 @@ static const struct attribute_spec rs6000_attribute_table[] = #undef TARGET_MEMBER_TYPE_FORCES_BLK #define TARGET_MEMBER_TYPE_FORCES_BLK rs6000_member_type_forces_blk -/* On rs6000, function arguments are promoted, as are function return - values. */ #undef TARGET_PROMOTE_FUNCTION_MODE -#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote +#define TARGET_PROMOTE_FUNCTION_MODE rs6000_promote_function_mode #undef TARGET_RETURN_IN_MEMORY #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory @@ -9301,6 +9299,20 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, } } +/* On rs6000, function arguments are promoted, as are function return + values. */ + +static machine_mode +rs6000_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, + machine_mode mode, + int *punsignedp ATTRIBUTE_UNUSED, + const_tree, int) +{ + PROMOTE_MODE (mode, *punsignedp, type); + + return mode; +} + /* Return true if TYPE must be passed on the stack and not in registers. */ static bool -- 1.8.1.4