IPA-SPLIT when inserting the call to the split part of the function does not care for the possibility that its result may not be convertible to the result holding variable.
The following fixes that. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2011-05-30 Richard Guenther <rguent...@suse.de> PR tree-optimization/49210 * ipa-split.c (split_function): Care for the case where the call result is not trivially convertible to the result holding variable. * gnat.dg/boolean_subtype2.adb: New testcase. * gnat.dg/boolean_subtype2.ads: Likewise. * gnat.dg/boolean_subtype2_pkg.ads: Likewise. Index: gcc/ipa-split.c =================================================================== --- gcc/ipa-split.c (revision 174427) +++ gcc/ipa-split.c (working copy) @@ -1196,11 +1196,31 @@ split_function (struct split_point *spli } } if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) - gimple_call_set_lhs (call, build_simple_mem_ref (retval)); + { + gimple_call_set_lhs (call, build_simple_mem_ref (retval)); + gsi_insert_after (&gsi, call, GSI_NEW_STMT); + } else - gimple_call_set_lhs (call, retval); + { + tree restype; + restype = TREE_TYPE (DECL_RESULT (current_function_decl)); + gsi_insert_after (&gsi, call, GSI_NEW_STMT); + if (!useless_type_conversion_p (TREE_TYPE (retval), restype)) + { + gimple cpy; + tree tem = create_tmp_reg (restype, NULL); + tem = make_ssa_name (tem, call); + cpy = gimple_build_assign_with_ops (NOP_EXPR, retval, + tem, NULL_TREE); + gsi_insert_after (&gsi, cpy, GSI_NEW_STMT); + retval = tem; + } + gimple_call_set_lhs (call, retval); + update_stmt (call); + } } - gsi_insert_after (&gsi, call, GSI_NEW_STMT); + else + gsi_insert_after (&gsi, call, GSI_NEW_STMT); } /* We don't use return block (there is either no return in function or multiple of them). So create new basic block with return statement. Index: gcc/testsuite/gnat.dg/boolean_subtype2.adb =================================================================== --- gcc/testsuite/gnat.dg/boolean_subtype2.adb (revision 0) +++ gcc/testsuite/gnat.dg/boolean_subtype2.adb (revision 0) @@ -0,0 +1,40 @@ +-- { dg-do compile } +-- { dg-options "-O3 -gnata" } + +package body Boolean_Subtype2 is + + function Component_Type (Id : Entity_Id) return Entity_Id is + begin + pragma Assert (Is_String_Type (Id)); + return Node20 (Id); + end; + + function First_Index (Id : Entity_Id) return Node_Id is + begin + pragma Assert (Is_String_Type (Id)); + return Node20 (Id); + end ; + + function Is_Character_Type (Id : Entity_Id) return B is + begin + return Flag63 (Id); + end; + + function Number_Dimensions (Id : Entity_Id) return Positive is + N : Integer := 0; + T : Node_Id := First_Index (Id); + begin + if Present (T) then + N := N + 1; + end if; + return N; + end; + + function Is_String_Type (Id : Entity_Id) return B is + begin + return (Id /= 0 + and then Number_Dimensions (Id) = 1 + and then Is_Character_Type (Component_Type (Id))); + end; + +end Boolean_Subtype2; Index: gcc/testsuite/gnat.dg/boolean_subtype2.ads =================================================================== --- gcc/testsuite/gnat.dg/boolean_subtype2.ads (revision 0) +++ gcc/testsuite/gnat.dg/boolean_subtype2.ads (revision 0) @@ -0,0 +1,9 @@ +with Boolean_Subtype2_Pkg; use Boolean_Subtype2_Pkg; + +package Boolean_Subtype2 is + + subtype B is Boolean; + + function Is_String_Type (Id : Entity_Id) return B; + +end Boolean_Subtype2; Index: gcc/testsuite/gnat.dg/boolean_subtype2_pkg.ads =================================================================== --- gcc/testsuite/gnat.dg/boolean_subtype2_pkg.ads (revision 0) +++ gcc/testsuite/gnat.dg/boolean_subtype2_pkg.ads (revision 0) @@ -0,0 +1,10 @@ +package Boolean_Subtype2_Pkg is + + type Node_Id is range 0 .. 099_999_999; + subtype Entity_Id is Node_Id; + + function Node20 (N : Node_Id) return Node_Id; + function Flag63 (N : Node_Id) return Boolean; + function Present (N : Node_Id) return Boolean; + +end Boolean_Subtype2_Pkg;