This fixes PR50712, an issue with IPA split uncovered by adding verifier calls after it ... we need to also gimplify reads of register typed memory when passing it as argument.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2011-10-13 Richard Guenther <rguent...@suse.de> PR tree-optimization/50712 * ipa-split.c (split_function): Always re-gimplify parameters when they are not gimple vals before passing them. Properly check for type compatibility. * gcc.target/i386/pr50712.c: New testcase. Index: gcc/ipa-split.c =================================================================== *** gcc/ipa-split.c (revision 179894) --- gcc/ipa-split.c (working copy) *************** split_function (struct split_point *spli *** 958,964 **** tree retval = NULL, real_retval = NULL; bool split_part_return_p = false; gimple last_stmt = NULL; - bool conv_needed = false; unsigned int i; tree arg; --- 958,963 ---- *************** split_function (struct split_point *spli *** 1000,1011 **** else arg = parm; ! if (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)) ! != TYPE_MAIN_VARIANT (TREE_TYPE (arg))) ! { ! conv_needed = true; ! arg = fold_convert (DECL_ARG_TYPE (parm), arg); ! } VEC_safe_push (tree, heap, args_to_pass, arg); } --- 999,1006 ---- else arg = parm; ! if (!useless_type_conversion_p (DECL_ARG_TYPE (parm), TREE_TYPE (arg))) ! arg = fold_convert (DECL_ARG_TYPE (parm), arg); VEC_safe_push (tree, heap, args_to_pass, arg); } *************** split_function (struct split_point *spli *** 1135,1148 **** /* Produce the call statement. */ gsi = gsi_last_bb (call_bb); ! if (conv_needed) ! FOR_EACH_VEC_ELT (tree, args_to_pass, i, arg) ! if (!is_gimple_val (arg)) ! { ! arg = force_gimple_operand_gsi (&gsi, arg, true, NULL_TREE, ! false, GSI_NEW_STMT); ! VEC_replace (tree, args_to_pass, i, arg); ! } call = gimple_build_call_vec (node->decl, args_to_pass); gimple_set_block (call, DECL_INITIAL (current_function_decl)); --- 1130,1142 ---- /* Produce the call statement. */ gsi = gsi_last_bb (call_bb); ! FOR_EACH_VEC_ELT (tree, args_to_pass, i, arg) ! if (!is_gimple_val (arg)) ! { ! arg = force_gimple_operand_gsi (&gsi, arg, true, NULL_TREE, ! false, GSI_NEW_STMT); ! VEC_replace (tree, args_to_pass, i, arg); ! } call = gimple_build_call_vec (node->decl, args_to_pass); gimple_set_block (call, DECL_INITIAL (current_function_decl)); Index: gcc/testsuite/gcc.target/i386/pr50712.c =================================================================== *** gcc/testsuite/gcc.target/i386/pr50712.c (revision 0) --- gcc/testsuite/gcc.target/i386/pr50712.c (revision 0) *************** *** 0 **** --- 1,33 ---- + /* { dg-do compile } */ + /* { dg-require-effective-target ilp32 } */ + /* { dg-options "-O2" } */ + + typedef __builtin_va_list __va_list; + typedef __va_list __gnuc_va_list; + typedef __gnuc_va_list va_list; + struct MSVCRT__iobuf { }; + typedef struct MSVCRT__iobuf MSVCRT_FILE; + typedef union _printf_arg { } printf_arg; + MSVCRT_FILE MSVCRT__iob[20]; + int pf_print_a (va_list *); + int __attribute__((__cdecl__)) + MSVCRT_vfprintf_s(MSVCRT_FILE* file, const char *format, va_list valist) + { + if(!((file != ((void *)0)) + || (MSVCRT__invalid_parameter(((void *)0), ((void *)0), + ((void *)0), 0, 0),0))) + return -1; + return pf_printf_a(&valist); + } + int __attribute__((__cdecl__)) + MSVCRT_vprintf_s(const char *format, va_list valist) + { + return MSVCRT_vfprintf_s((MSVCRT__iob+1),format,valist); + } + int __attribute__((__cdecl__)) + MSVCRT_fprintf_s(MSVCRT_FILE* file, const char *format, ...) + { + va_list valist; + va_start (valist, format); + return MSVCRT_vfprintf_s(file, format, valist); + }