From: Jakub Jelinek Date: Thu, 10 Feb 2005 17:11:11 +0000 (+0100) Subject: re PR rtl-optimization/19579 (-march=i686 generates a bogus program for x86*) X-Git-Tag: releases/gcc-3.4.4~237 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c465b9e6c00602b49d31cef4865e3a41193e1349;p=thirdparty%2Fgcc.git re PR rtl-optimization/19579 (-march=i686 generates a bogus program for x86*) PR rtl-optimization/19579 * ifcvt.c (noce_try_cmove_arith): If emitting instructions to set up both A and B, see if they don't clobber registers the other expr uses. * gcc.c-torture/execute/20050124-1.c: New test. From-SVN: r94835 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eb394b821812..19e4d7bd956b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-02-10 Jakub Jelinek + + PR rtl-optimization/19579 + * ifcvt.c (noce_try_cmove_arith): If emitting instructions to set up + both A and B, see if they don't clobber registers the other expr uses. + 2005-02-08 Alan Modra PR target/19803 diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 640ab2cf2f9c..b9a50387dc82 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1193,6 +1193,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) rtx a = if_info->a; rtx b = if_info->b; rtx x = if_info->x; + rtx orig_a, orig_b; rtx insn_a, insn_b; rtx tmp, target; int is_mem = 0; @@ -1248,6 +1249,9 @@ noce_try_cmove_arith (struct noce_if_info *if_info) start_sequence (); + orig_a = a; + orig_b = b; + /* If either operand is complex, load it into a register first. The best way to do this is to copy the original insn. In this way we preserve any clobbers etc that the insn may have had. @@ -1279,7 +1283,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) } if (! general_operand (b, GET_MODE (b))) { - rtx set; + rtx set, last; if (no_new_pseudos) goto end_seq_and_fail; @@ -1287,9 +1291,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) if (is_mem) { tmp = gen_reg_rtx (GET_MODE (b)); - tmp = emit_insn (gen_rtx_SET (VOIDmode, - tmp, - b)); + tmp = gen_rtx_SET (VOIDmode, tmp, b); } else if (! insn_b) goto end_seq_and_fail; @@ -1299,8 +1301,22 @@ noce_try_cmove_arith (struct noce_if_info *if_info) tmp = copy_rtx (insn_b); set = single_set (tmp); SET_DEST (set) = b; - tmp = emit_insn (PATTERN (tmp)); + tmp = PATTERN (tmp); + } + + /* If insn to set up A clobbers any registers B depends on, try to + swap insn that sets up A with the one that sets up B. If even + that doesn't help, punt. */ + last = get_last_insn (); + if (last && modified_in_p (orig_b, last)) + { + tmp = emit_insn_before (tmp, get_insns ()); + if (modified_in_p (orig_a, tmp)) + goto end_seq_and_fail; } + else + tmp = emit_insn (tmp); + if (recog_memoized (tmp) < 0) goto end_seq_and_fail; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d13ae5c69674..3f14579324c4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-02-10 Jakub Jelinek + + PR rtl-optimization/19579 + * gcc.c-torture/execute/20050124-1.c: New test. + 2005-02-09 Mark Mitchell PR c++/19787