This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[3.3 PATCH] Backport of PR19579
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Gabriel Dos Reis <gdr at cs dot tamu dot edu>, Jakub Jelinek <jakub at redhat dot com>
- Date: Sat, 30 Apr 2005 20:38:30 -0600 (MDT)
- Subject: [3.3 PATCH] Backport of PR19579
Hi Gaby,
I've now successfully bootstrapped and regression tested Jakub's patch
for PR19579 against the gcc-3_3-branch with a full "make bootstrap"
on i686-pc-linux-gnu, all languages except Ada, and regression tested
with a top-level "make -k check" with no new failures. The patch fixes
the miscompilation of the testcase below when compiled with -march=i686.
Ok to commit to the gcc-3_3-branch?
2005-04-30 Roger Sayle <roger@eyesopen.com>
PR rtl-optimization/19579
Backport from mainline
2005-01-26 Jakub Jelinek <jakub@redhat.com>
* 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.
Index: ifcvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ifcvt.c,v
retrieving revision 1.105.4.9
diff -c -3 -p -r1.105.4.9 ifcvt.c
*** ifcvt.c 21 Dec 2003 16:08:04 -0000 1.105.4.9
--- ifcvt.c 30 Apr 2005 23:05:12 -0000
*************** noce_try_cmove_arith (if_info)
*** 1082,1087 ****
--- 1082,1088 ----
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;
*************** noce_try_cmove_arith (if_info)
*** 1137,1142 ****
--- 1138,1146 ----
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.
*************** noce_try_cmove_arith (if_info)
*** 1168,1174 ****
}
if (! general_operand (b, GET_MODE (b)))
{
! rtx set;
if (no_new_pseudos)
goto end_seq_and_fail;
--- 1172,1178 ----
}
if (! general_operand (b, GET_MODE (b)))
{
! rtx set, last;
if (no_new_pseudos)
goto end_seq_and_fail;
*************** noce_try_cmove_arith (if_info)
*** 1176,1182 ****
if (is_mem)
{
tmp = gen_reg_rtx (GET_MODE (b));
! tmp = emit_insn (gen_rtx_SET (VOIDmode, tmp, b));
}
else if (! insn_b
#if 0
--- 1180,1186 ----
if (is_mem)
{
tmp = gen_reg_rtx (GET_MODE (b));
! tmp = gen_rtx_SET (VOIDmode, tmp, b);
}
else if (! insn_b
#if 0
*************** noce_try_cmove_arith (if_info)
*** 1195,1202 ****
tmp = copy_rtx (insn_b);
set = single_set (tmp);
SET_DEST (set) = b;
! tmp = emit_insn (PATTERN (tmp));
}
if (recog_memoized (tmp) < 0)
goto end_seq_and_fail;
}
--- 1199,1220 ----
tmp = copy_rtx (insn_b);
set = single_set (tmp);
SET_DEST (set) = b;
! 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;
}
/* PR rtl-optimization/19579 */
extern void abort (void);
int
foo (int i, int j)
{
int k = i + 1;
if (j)
{
if (k > 0)
k++;
else if (k < 0)
k--;
}
return k;
}
int
main (void)
{
if (foo (-2, 0) != -1)
abort ();
if (foo (-1, 0) != 0)
abort ();
if (foo (0, 0) != 1)
abort ();
if (foo (1, 0) != 2)
abort ();
if (foo (-2, 1) != -2)
abort ();
if (foo (-1, 1) != 0)
abort ();
if (foo (0, 1) != 2)
abort ();
if (foo (1, 1) != 3)
abort ();
return 0;
}
Roger
--
Roger Sayle, E-mail: roger@eyesopen.com
OpenEye Scientific Software, WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road, Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507. Fax: (+1) 505-473-0833