From 3386d77eb83f3043afcc46503356165bc5ddfdba Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 13 Mar 2014 13:24:56 -0700 Subject: [PATCH] re PR debug/60438 (dwarf2cfi :2239 still assert,not the same cause as PR 59575) PR debug/60438 * config/i386/i386.c (ix86_split_fp_branch): Remove pushed argument. (ix86_force_to_memory, ix86_free_from_memory): Remove. * config/i386/i386-protos.h: Likewise. * config/i386/i386.md (floathi2): Use assign_386_stack_local in the expander instead of a splitter. (float2): Use assign_386_stack_local if there is any possibility of requiring a memory. (*floatsi2_vector_mixed): Remove, and the splitters. (*floatsi2_vector_sse): Remove, and the splitters. (fp branch splitters): Update for ix86_split_fp_branch. (*jcc__i387): Remove r/f alternative. (*jcc__r_i387): Likewise. (splitter for jcc__i387 r/f): Remove. (*fop__2_i387): Remove f/r alternative. (*fop__3_i387): Likewise. (*fop_xf_2_i387, *fop_xf_3_i387): Likewise. (splitters for the fop_* register patterns): Remove. (fscalexf4_i387): Rename from *fscalexf4_i387. (ldexpxf3): Use gen_floatsixf2 and gen_fscalexf4_i387. From-SVN: r208556 --- gcc/ChangeLog | 23 ++ gcc/config/i386/i386-protos.h | 4 +- gcc/config/i386/i386.c | 105 +------- gcc/config/i386/i386.md | 318 ++++++----------------- gcc/testsuite/ChangeLog | 5 + gcc/testsuite/g++.dg/torture/pr60438-1.C | 26 ++ gcc/testsuite/g++.dg/torture/pr60438-2.C | 3 + 7 files changed, 133 insertions(+), 351 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr60438-1.C create mode 100644 gcc/testsuite/g++.dg/torture/pr60438-2.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a16001b703a..8f92d2db809 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2014-03-13 Richard Henderson + + PR debug/60438 + * config/i386/i386.c (ix86_split_fp_branch): Remove pushed argument. + (ix86_force_to_memory, ix86_free_from_memory): Remove. + * config/i386/i386-protos.h: Likewise. + * config/i386/i386.md (floathi2): Use assign_386_stack_local + in the expander instead of a splitter. + (float2): Use assign_386_stack_local if there is + any possibility of requiring a memory. + (*floatsi2_vector_mixed): Remove, and the splitters. + (*floatsi2_vector_sse): Remove, and the splitters. + (fp branch splitters): Update for ix86_split_fp_branch. + (*jcc__i387): Remove r/f alternative. + (*jcc__r_i387): Likewise. + (splitter for jcc__i387 r/f): Remove. + (*fop__2_i387): Remove f/r alternative. + (*fop__3_i387): Likewise. + (*fop_xf_2_i387, *fop_xf_3_i387): Likewise. + (splitters for the fop_* register patterns): Remove. + (fscalexf4_i387): Rename from *fscalexf4_i387. + (ldexpxf3): Use gen_floatsixf2 and gen_fscalexf4_i387. + 2014-03-13 Jakub Jelinek PR tree-optimization/59779 diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 3493904864f..6e329788088 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -154,13 +154,11 @@ extern enum machine_mode ix86_fp_compare_mode (enum rtx_code); extern rtx ix86_libcall_value (enum machine_mode); extern bool ix86_function_arg_regno_p (int); extern void ix86_asm_output_function_label (FILE *, const char *, tree); -extern rtx ix86_force_to_memory (enum machine_mode, rtx); -extern void ix86_free_from_memory (enum machine_mode); extern void ix86_call_abi_override (const_tree); extern int ix86_reg_parm_stack_space (const_tree); extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx, - rtx, rtx, rtx, rtx); + rtx, rtx, rtx); extern bool ix86_hard_regno_mode_ok (int, enum machine_mode); extern bool ix86_modes_tieable_p (enum machine_mode, enum machine_mode); extern bool ix86_secondary_memory_needed (enum reg_class, enum reg_class, diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 9e33d5309fc..64b8e0a956b 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -19993,7 +19993,7 @@ ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label) /* Split branch based on floating point condition. */ void ix86_split_fp_branch (enum rtx_code code, rtx op1, rtx op2, - rtx target1, rtx target2, rtx tmp, rtx pushed) + rtx target1, rtx target2, rtx tmp) { rtx condition; rtx i; @@ -20009,10 +20009,6 @@ ix86_split_fp_branch (enum rtx_code code, rtx op1, rtx op2, condition = ix86_expand_fp_compare (code, op1, op2, tmp); - /* Remove pushed operand from stack. */ - if (pushed) - ix86_free_from_memory (GET_MODE (pushed)); - i = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, gen_rtx_IF_THEN_ELSE (VOIDmode, @@ -36994,105 +36990,6 @@ avx_vperm2f128_parallel (rtx par, enum machine_mode mode) return mask + 1; } -/* Store OPERAND to the memory after reload is completed. This means - that we can't easily use assign_stack_local. */ -rtx -ix86_force_to_memory (enum machine_mode mode, rtx operand) -{ - rtx result; - - gcc_assert (reload_completed); - if (ix86_using_red_zone ()) - { - result = gen_rtx_MEM (mode, - gen_rtx_PLUS (Pmode, - stack_pointer_rtx, - GEN_INT (-RED_ZONE_SIZE))); - emit_move_insn (result, operand); - } - else if (TARGET_64BIT) - { - switch (mode) - { - case HImode: - case SImode: - operand = gen_lowpart (DImode, operand); - /* FALLTHRU */ - case DImode: - emit_insn ( - gen_rtx_SET (VOIDmode, - gen_rtx_MEM (DImode, - gen_rtx_PRE_DEC (DImode, - stack_pointer_rtx)), - operand)); - break; - default: - gcc_unreachable (); - } - result = gen_rtx_MEM (mode, stack_pointer_rtx); - } - else - { - switch (mode) - { - case DImode: - { - rtx operands[2]; - split_double_mode (mode, &operand, 1, operands, operands + 1); - emit_insn ( - gen_rtx_SET (VOIDmode, - gen_rtx_MEM (SImode, - gen_rtx_PRE_DEC (Pmode, - stack_pointer_rtx)), - operands[1])); - emit_insn ( - gen_rtx_SET (VOIDmode, - gen_rtx_MEM (SImode, - gen_rtx_PRE_DEC (Pmode, - stack_pointer_rtx)), - operands[0])); - } - break; - case HImode: - /* Store HImodes as SImodes. */ - operand = gen_lowpart (SImode, operand); - /* FALLTHRU */ - case SImode: - emit_insn ( - gen_rtx_SET (VOIDmode, - gen_rtx_MEM (GET_MODE (operand), - gen_rtx_PRE_DEC (SImode, - stack_pointer_rtx)), - operand)); - break; - default: - gcc_unreachable (); - } - result = gen_rtx_MEM (mode, stack_pointer_rtx); - } - return result; -} - -/* Free operand from the memory. */ -void -ix86_free_from_memory (enum machine_mode mode) -{ - if (!ix86_using_red_zone ()) - { - int size; - - if (mode == DImode || TARGET_64BIT) - size = 8; - else - size = 4; - /* Use LEA to deallocate stack space. In peephole2 it will be converted - to pop or add instruction if registers are available. */ - emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx, - gen_rtx_PLUS (Pmode, stack_pointer_rtx, - GEN_INT (size)))); - } -} - /* Return a register priority for hard reg REGNO. */ static int ix86_register_priority (int hard_regno) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index ea1d85f76a5..03939fd71cc 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -4656,26 +4656,16 @@ ;; wants to be able to do this between registers. (define_expand "floathi2" - [(set (match_operand:X87MODEF 0 "register_operand") - (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))] + [(parallel [(set (match_operand:X87MODEF 0 "register_operand") + (float:X87MODEF + (match_operand:HI 1 "nonimmediate_operand"))) + (clobber (match_dup 2))])] "TARGET_80387 && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) - || TARGET_MIX_SSE_I387)") - -;; Pre-reload splitter to add memory clobber to the pattern. -(define_insn_and_split "*floathi2_1" - [(set (match_operand:X87MODEF 0 "register_operand") - (float:X87MODEF (match_operand:HI 1 "register_operand")))] - "TARGET_80387 - && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) - || TARGET_MIX_SSE_I387) - && can_create_pseudo_p ()" - "#" - "&& 1" - [(parallel [(set (match_dup 0) - (float:X87MODEF (match_dup 1))) - (clobber (match_dup 2))])] - "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);") + || TARGET_MIX_SSE_I387)" +{ + operands[2] = assign_386_stack_local (HImode, SLOT_TEMP); +}) (define_insn "*floathi2_i387_with_temp" [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") @@ -4723,14 +4713,17 @@ [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]) (define_expand "float2" - [(set (match_operand:X87MODEF 0 "register_operand") - (float:X87MODEF - (match_operand:SWI48x 1 "nonimmediate_operand")))] + [(parallel [(set (match_operand:X87MODEF 0 "register_operand") + (float:X87MODEF + (match_operand:SWI48x 1 "nonimmediate_operand"))) + (clobber (match_dup 2))])] "TARGET_80387 || ((mode != DImode || TARGET_64BIT) && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)" { - if (!((mode != DImode || TARGET_64BIT) + bool native_int = TARGET_64BIT || mode != DImode; + + if (!(native_int && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) && !X87_ENABLE_FLOAT (mode, mode)) { @@ -4749,44 +4742,34 @@ emit_insn (insn (operands[0], reg)); DONE; } -}) - -;; Pre-reload splitter to add memory clobber to the pattern. -(define_insn_and_split "*float2_1" - [(set (match_operand:X87MODEF 0 "register_operand") - (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))] - "((TARGET_80387 - && X87_ENABLE_FLOAT (mode, mode) - && (!((mode != DImode || TARGET_64BIT) - && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) - || TARGET_MIX_SSE_I387)) - || ((mode != DImode || TARGET_64BIT) - && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH - && ((mode == SImode - && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS - && optimize_function_for_speed_p (cfun) - && flag_trapping_math) - || !(TARGET_INTER_UNIT_CONVERSIONS - || optimize_function_for_size_p (cfun))))) - && can_create_pseudo_p ()" - "#" - "&& 1" - [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1))) - (clobber (match_dup 2))])] -{ - operands[2] = assign_386_stack_local (mode, SLOT_TEMP); /* Avoid store forwarding (partial memory) stall penalty by passing DImode value through XMM registers. */ - if (mode == DImode && !TARGET_64BIT + if (!native_int && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC && optimize_function_for_speed_p (cfun)) { + operands[2] = assign_386_stack_local (mode, SLOT_TEMP); emit_insn (gen_floatdi2_i387_with_xmm (operands[0], operands[1], operands[2])); DONE; } + + /* Notice when we'd convert directly from general registers. */ + if (native_int + && (TARGET_MIX_SSE_I387 || TARGET_SSE_MATH) + && SSE_FLOAT_MODE_P (mode) + && (TARGET_INTER_UNIT_CONVERSIONS + || optimize_function_for_size_p (cfun))) + { + emit_insn (gen_rtx_SET + (VOIDmode, operands[0], + gen_rtx_FLOAT (mode, operands[1]))); + DONE; + } + + operands[2] = assign_386_stack_local (mode, SLOT_TEMP); }) (define_insn "*floatsi2_vector_mixed_with_temp" @@ -4805,22 +4788,6 @@ (set_attr "bdver1_decode" "*,*,double,direct,double") (set_attr "fp_int_src" "true")]) -(define_insn "*floatsi2_vector_mixed" - [(set (match_operand:MODEF 0 "register_operand" "=f,x") - (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))] - "TARGET_SSE2 && TARGET_MIX_SSE_I387 - && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" - "@ - fild%Z1\t%1 - #" - [(set_attr "type" "fmov,sseicvt") - (set_attr "mode" ",") - (set_attr "unit" "i387,*") - (set_attr "athlon_decode" "*,direct") - (set_attr "amdfam10_decode" "*,double") - (set_attr "bdver1_decode" "*,direct") - (set_attr "fp_int_src" "true")]) - (define_insn "*float2_mixed_with_temp" [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x") (float:MODEF @@ -4836,15 +4803,6 @@ (set_attr "bdver1_decode" "*,*,double,direct") (set_attr "fp_int_src" "true")]) -(define_split - [(set (match_operand:MODEF 0 "register_operand") - (float:MODEF (match_operand:SWI48 1 "register_operand"))) - (clobber (match_operand:SWI48 2 "memory_operand"))] - "SSE_FLOAT_MODE_P (mode) && TARGET_MIX_SSE_I387 - && TARGET_INTER_UNIT_CONVERSIONS - && reload_completed && SSE_REG_P (operands[0])" - [(set (match_dup 0) (float:MODEF (match_dup 1)))]) - (define_split [(set (match_operand:MODEF 0 "register_operand") (float:MODEF (match_operand:SWI48 1 "register_operand"))) @@ -4918,19 +4876,6 @@ (set_attr "bdver1_decode" "double,direct,double") (set_attr "fp_int_src" "true")]) -(define_insn "*floatsi2_vector_sse" - [(set (match_operand:MODEF 0 "register_operand" "=x") - (float:MODEF (match_operand:SI 1 "memory_operand" "m")))] - "TARGET_SSE2 && TARGET_SSE_MATH - && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" - "#" - [(set_attr "type" "sseicvt") - (set_attr "mode" "") - (set_attr "athlon_decode" "direct") - (set_attr "amdfam10_decode" "double") - (set_attr "bdver1_decode" "direct") - (set_attr "fp_int_src" "true")]) - (define_split [(set (match_operand:MODEF 0 "register_operand") (float:MODEF (match_operand:SI 1 "register_operand"))) @@ -4993,49 +4938,6 @@ DONE; }) -(define_split - [(set (match_operand:MODEF 0 "register_operand") - (float:MODEF (match_operand:SI 1 "register_operand")))] - "TARGET_SSE2 && TARGET_SSE_MATH - && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) - && reload_completed && SSE_REG_P (operands[0])" - [(const_int 0)] -{ - rtx op1 = operands[1]; - - operands[3] = simplify_gen_subreg (mode, operands[0], - mode, 0); - if (GET_CODE (op1) == SUBREG) - op1 = SUBREG_REG (op1); - - if (GENERAL_REG_P (op1)) - { - operands[4] = simplify_gen_subreg (V4SImode, operands[0], mode, 0); - if (TARGET_INTER_UNIT_MOVES_TO_VEC) - emit_insn (gen_sse2_loadld (operands[4], - CONST0_RTX (V4SImode), operands[1])); - else - { - operands[5] = ix86_force_to_memory (GET_MODE (operands[1]), - operands[1]); - emit_insn (gen_sse2_loadld (operands[4], - CONST0_RTX (V4SImode), operands[5])); - ix86_free_from_memory (GET_MODE (operands[1])); - } - } - /* We can ignore possible trapping value in the - high part of SSE register for non-trapping math. */ - else if (SSE_REG_P (op1) && !flag_trapping_math) - operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0); - else - gcc_unreachable (); - if (mode == V4SFmode) - emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); - else - emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); - DONE; -}) - (define_split [(set (match_operand:MODEF 0 "register_operand") (float:MODEF (match_operand:SI 1 "memory_operand")))] @@ -5134,14 +5036,6 @@ [(set (match_dup 2) (match_dup 1)) (set (match_dup 0) (float:MODEF (match_dup 2)))]) -(define_split - [(set (match_operand:MODEF 0 "register_operand") - (float:MODEF (match_operand:SWI48 1 "memory_operand"))) - (clobber (match_operand:SWI48 2 "memory_operand"))] - "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH - && reload_completed && SSE_REG_P (operands[0])" - [(set (match_dup 0) (float:MODEF (match_dup 1)))]) - (define_insn "*float2_i387_with_temp" [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") (float:X87MODEF @@ -11370,7 +11264,7 @@ [(const_int 0)] { ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], - operands[3], operands[4], NULL_RTX, NULL_RTX); + operands[3], operands[4], NULL_RTX); DONE; }) @@ -11389,7 +11283,7 @@ [(const_int 0)] { ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], - operands[3], operands[4], operands[5], NULL_RTX); + operands[3], operands[4], operands[5]); DONE; }) @@ -11403,13 +11297,13 @@ (if_then_else (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator" [(match_operator:X87MODEF 1 "float_operator" - [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")]) - (match_operand:X87MODEF 3 "register_operand" "f,f")]) + [(match_operand:SWI24 2 "nonimmediate_operand" "m")]) + (match_operand:X87MODEF 3 "register_operand" "f")]) (label_ref (match_operand 4)) (pc))) (clobber (reg:CCFP FPSR_REG)) (clobber (reg:CCFP FLAGS_REG)) - (clobber (match_scratch:HI 5 "=a,a"))] + (clobber (match_scratch:HI 5 "=a"))] "TARGET_80387 && !TARGET_CMOVE && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))" @@ -11420,13 +11314,13 @@ (if_then_else (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator" [(match_operator:X87MODEF 1 "float_operator" - [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")]) - (match_operand:X87MODEF 3 "register_operand" "f,f")]) + [(match_operand:SWI24 2 "nonimmediate_operand" "m")]) + (match_operand:X87MODEF 3 "register_operand" "f")]) (pc) (label_ref (match_operand 4)))) (clobber (reg:CCFP FPSR_REG)) (clobber (reg:CCFP FLAGS_REG)) - (clobber (match_scratch:HI 5 "=a,a"))] + (clobber (match_scratch:HI 5 "=a"))] "TARGET_80387 && !TARGET_CMOVE && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))" @@ -11450,32 +11344,7 @@ { ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3], gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]), - operands[4], operands[5], operands[6], NULL_RTX); - DONE; -}) - -;; %%% Kill this when reload knows how to do it. -(define_split - [(set (pc) - (if_then_else - (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator" - [(match_operator:X87MODEF 1 "float_operator" - [(match_operand:SWI24 2 "register_operand")]) - (match_operand:X87MODEF 3 "register_operand")]) - (match_operand 4) - (match_operand 5))) - (clobber (reg:CCFP FPSR_REG)) - (clobber (reg:CCFP FLAGS_REG)) - (clobber (match_scratch:HI 6))] - "TARGET_80387 && !TARGET_CMOVE - && reload_completed" - [(const_int 0)] -{ - operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); - - ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3], - gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]), - operands[4], operands[5], operands[6], operands[2]); + operands[4], operands[5], operands[6]); DONE; }) @@ -13423,15 +13292,16 @@ ;; ??? Add SSE splitters for these! (define_insn "*fop__2_i387" - [(set (match_operand:MODEF 0 "register_operand" "=f,f") + [(set (match_operand:MODEF 0 "register_operand" "=f") (match_operator:MODEF 3 "binary_fp_operator" [(float:MODEF - (match_operand:SWI24 1 "nonimmediate_operand" "m,?r")) - (match_operand:MODEF 2 "register_operand" "0,0")]))] + (match_operand:SWI24 1 "nonimmediate_operand" "m")) + (match_operand:MODEF 2 "register_operand" "0")]))] "TARGET_80387 && X87_ENABLE_FLOAT (mode, mode) && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) - && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))" - "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" + && (TARGET_USE_MODE_FIOP + || optimize_function_for_size_p (cfun))" + { return output_387_binary_op (insn, operands); } [(set (attr "type") (cond [(match_operand:MODEF 3 "mult_operator") (const_string "fmul") @@ -13443,15 +13313,16 @@ (set_attr "mode" "")]) (define_insn "*fop__3_i387" - [(set (match_operand:MODEF 0 "register_operand" "=f,f") + [(set (match_operand:MODEF 0 "register_operand" "=f") (match_operator:MODEF 3 "binary_fp_operator" - [(match_operand:MODEF 1 "register_operand" "0,0") + [(match_operand:MODEF 1 "register_operand" "0") (float:MODEF - (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))] + (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))] "TARGET_80387 && X87_ENABLE_FLOAT (mode, mode) && !(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) - && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))" - "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" + && (TARGET_USE_MODE_FIOP + || optimize_function_for_size_p (cfun))" + { return output_387_binary_op (insn, operands); } [(set (attr "type") (cond [(match_operand:MODEF 3 "mult_operator") (const_string "fmul") @@ -13550,13 +13421,14 @@ (set_attr "mode" "XF")]) (define_insn "*fop_xf_2_i387" - [(set (match_operand:XF 0 "register_operand" "=f,f") + [(set (match_operand:XF 0 "register_operand" "=f") (match_operator:XF 3 "binary_fp_operator" [(float:XF - (match_operand:SWI24 1 "nonimmediate_operand" "m,?r")) - (match_operand:XF 2 "register_operand" "0,0")]))] - "TARGET_80387 && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))" - "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" + (match_operand:SWI24 1 "nonimmediate_operand" "m")) + (match_operand:XF 2 "register_operand" "0")]))] + "TARGET_80387 + && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))" + { return output_387_binary_op (insn, operands); } [(set (attr "type") (cond [(match_operand:XF 3 "mult_operator") (const_string "fmul") @@ -13568,13 +13440,14 @@ (set_attr "mode" "")]) (define_insn "*fop_xf_3_i387" - [(set (match_operand:XF 0 "register_operand" "=f,f") + [(set (match_operand:XF 0 "register_operand" "=f") (match_operator:XF 3 "binary_fp_operator" - [(match_operand:XF 1 "register_operand" "0,0") + [(match_operand:XF 1 "register_operand" "0") (float:XF - (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))] - "TARGET_80387 && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))" - "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" + (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))] + "TARGET_80387 + && (TARGET_USE_MODE_FIOP || optimize_function_for_size_p (cfun))" + { return output_387_binary_op (insn, operands); } [(set (attr "type") (cond [(match_operand:XF 3 "mult_operator") (const_string "fmul") @@ -13636,48 +13509,6 @@ ] (const_string "fop"))) (set_attr "mode" "")]) - -(define_split - [(set (match_operand 0 "register_operand") - (match_operator 3 "binary_fp_operator" - [(float (match_operand:SWI24 1 "register_operand")) - (match_operand 2 "register_operand")]))] - "reload_completed - && X87_FLOAT_MODE_P (GET_MODE (operands[0])) - && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))" - [(const_int 0)] -{ - operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); - operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_fmt_ee (GET_CODE (operands[3]), - GET_MODE (operands[3]), - operands[4], - operands[2]))); - ix86_free_from_memory (GET_MODE (operands[1])); - DONE; -}) - -(define_split - [(set (match_operand 0 "register_operand") - (match_operator 3 "binary_fp_operator" - [(match_operand 1 "register_operand") - (float (match_operand:SWI24 2 "register_operand"))]))] - "reload_completed - && X87_FLOAT_MODE_P (GET_MODE (operands[0])) - && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))" - [(const_int 0)] -{ - operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); - operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_fmt_ee (GET_CODE (operands[3]), - GET_MODE (operands[3]), - operands[1], - operands[4]))); - ix86_free_from_memory (GET_MODE (operands[2])); - DONE; -}) ;; FPU special functions. @@ -14567,7 +14398,7 @@ [(set_attr "type" "fpspc") (set_attr "mode" "XF")]) -(define_insn "*fscalexf4_i387" +(define_insn "fscalexf4_i387" [(set (match_operand:XF 0 "register_operand" "=f") (unspec:XF [(match_operand:XF 2 "register_operand" "0") (match_operand:XF 3 "register_operand" "1")] @@ -14791,15 +14622,9 @@ }) (define_expand "ldexpxf3" - [(set (match_dup 3) - (float:XF (match_operand:SI 2 "register_operand"))) - (parallel [(set (match_operand:XF 0 " register_operand") - (unspec:XF [(match_operand:XF 1 "register_operand") - (match_dup 3)] - UNSPEC_FSCALE_FRACT)) - (set (match_dup 4) - (unspec:XF [(match_dup 1) (match_dup 3)] - UNSPEC_FSCALE_EXP))])] + [(match_operand:XF 0 "register_operand") + (match_operand:XF 1 "register_operand") + (match_operand:SI 2 "register_operand")] "TARGET_USE_FANCY_MATH_387 && flag_unsafe_math_optimizations" { @@ -14808,6 +14633,11 @@ operands[3] = gen_reg_rtx (XFmode); operands[4] = gen_reg_rtx (XFmode); + + emit_insn (gen_floatsixf2 (operands[3], operands[2])); + emit_insn (gen_fscalexf4_i387 (operands[0], operands[4], + operands[1], operands[3])); + DONE; }) (define_expand "ldexp3" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ba1b7e8c992..d5f33a79cc2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-03-13 Richard Henderson + + PR debug/60438 + * g++.dg/torture/pr60438-1.C, g++.dg/torture/pr60438-2.C: New. + 2014-03-13 Paolo Carlini PR c++/60383 diff --git a/gcc/testsuite/g++.dg/torture/pr60438-1.C b/gcc/testsuite/g++.dg/torture/pr60438-1.C new file mode 100644 index 00000000000..748295aabe0 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr60438-1.C @@ -0,0 +1,26 @@ +// { dg-do compile } +// { dg-options "-fomit-frame-pointer" } + +struct A { int a; }; +struct B { A foo (); }; +struct C { B *foo (); }; +int foo (struct C *, float); +void bar (struct C *); +void baz (struct A *); +int a, b, c; + +int +foo (struct C *y, float x) +{ + struct A d; + if (c) + bar (y); + else + { + C g; + g.foo ()->foo (); + a = b; + d.a = (int) (b * x); + } + baz (&d); +} diff --git a/gcc/testsuite/g++.dg/torture/pr60438-2.C b/gcc/testsuite/g++.dg/torture/pr60438-2.C new file mode 100644 index 00000000000..b32576f67c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr60438-2.C @@ -0,0 +1,3 @@ +// { dg-do compile } +// { dg-options "-fomit-frame-pointer -fno-crossjumping" } +#include "pr60438-1.C"