Message ID | be73b77b16d2abd6c9194b873fd27efe8c8e4dfe.1420765404.git.segher@kernel.crashing.org |
---|---|
State | New |
Headers | show |
On Thu, Jan 8, 2015 at 8:10 PM, Segher Boessenkool <segher@kernel.crashing.org> wrote: > 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-08 Segher Boessenkool <segher@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. rs6000_promote_function_mode should use the PROMOTE_MODE macro. I think that the macro has a bug for -m32 -mpowerpc64 in its use of UNITS_PER_WORD. But I prefer one definition of the behavior to avoid divergence. Thanks David
--- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1498,10 +1498,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 @@ -9295,6 +9293,19 @@ 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, machine_mode mode, int *, + const_tree, int) +{ + if (GET_MODE_CLASS (mode) == MODE_INT + && GET_MODE_SIZE (mode) < GET_MODE_SIZE (Pmode)) + return Pmode; + + return mode; +} + /* Return true if TYPE must be passed on the stack and not in registers. */ static bool