This is both an ICE and an ABI bug dating back to the implementation of the 64-bit calling conventions in 1998: for structures larger than 8 bytes and not larger than 16 bytes containing a FP field in the second half and passed in slot #15 of the parameter array, the compiler passes the FP field in the %f32 register instead of on the stack; this results in an ICE for a 'float' and an ABI bug for a 'double'. The attached fix implements the detection and the handling of this case and shouldn't change anything in the other cases; however, since the existing code was suffering from excessive duplication (structure traversal was implemented 3 times, handling of FP fields twice and handling of integer fields 3 times), the code refactors the whole thing and in particular uses a function template for the traversal, which is then instantiated 3 times. Bootstrapped/regtested on SPARC64/Solaris and also compat-regtested (both bugs are rare enough as to go unnoticed by the compat testsuite). I also verified manually that GCC is now compatible with Sun CC in this case too. I'll document the ABI change in changes.html separately. 2016-02-29 Eric Botcazou PR target/69706 * config/sparc/sparc.c (ROUND_ADVANCE): Rename to... (NWORDS_UP): ...this (init_cumulative_args): Minor tweaks. (sparc_promote_function_mode): Likewise. (scan_record_type): Delete. (traverse_record_type): New function template. (classify_data_t): New structure type. (classify_registers): New inline function. (function_arg_slotno): In 64-bit mode, bail out early if FP slots are exhausted. Instantiate traverse_record_type on classify_registers and deal with the case of a structure passed in slot #15 with no FP field in the first word. (assign_data_t): New structure type. (compute_int_layout): New static function. (compute_fp_layout): Likewise. (count_registers): New inline function. (assign_int_registers): New static function. (assign_fp_registers): Likewise. (assign_registers): New inline function. (function_arg_record_value_1): Delete. (function_arg_record_value_2): Likewise. (function_arg_record_value_3): Likewise. (function_arg_record_value): Adjust to above changes. Instantiate traverse_record_type on count_registers to first count the number of registers to be used and then on assign_registers to assign them. (function_arg_union_value): Adjust to above renaming. (sparc_function_arg_1); Minor tweaks. Remove commented out code. (sparc_arg_partial_bytes): Adjust to above renaming. Deal with the case of a structure passed in slot #15 (sparc_function_arg_advance): Likewise. (function_arg_padding): Minor tweak. 2016-02-29 Eric Botcazou * gcc.target/sparc/20160229-1.c: New test. -- Eric Botcazou