This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Reg-stack and cmove bug
- To: Zack Weinberg <zackw at Stanford dot EDU>
- Subject: Re: Reg-stack and cmove bug
- From: Jan Hubicka <jh at suse dot cz>
- Date: Fri, 16 Feb 2001 19:46:24 +0100
- Cc: Tim Prince <tprince at computer dot org>, tprinceusa at mindspring dot com, gcc-bugs at gcc dot gnu dot org, jh at suse dot cz, rth at cygnus dot com, gcc-patches at gcc dot gnu dot org
- References: <Springmail.105.982281121.0.18922500@www.springmail.com> <20010215161557.J814@wolery.stanford.edu> <015201c097df$a90d82b0$b50cd63f@amr.corp.intel.com> <20010216010413.C9664@wolery.stanford.edu>
> That should be enough analysis for someone to find the bug on.
Hi,
the bug was exactly on spot I expected. When reversing comparison, regstack
is happy with first conditional reversed assuming that the flags dies
there. W/o cc0 this is not the case.
I've also spot another potential problem of reg-stack getting after
function call assuming that register don't change. With -O0 this
may actually match in some cases.
It seems to fix the testcase and I am just running testsuite with
-march=pentiumpro to validate. Assuming that it passes, OK to install?
Zack: can you verify that the testcase is really happy now? My patch
changes the code in way I want, but I don't have f77 runtime to actually
run it.
Honza
Pá úno 16 19:43:03 CET 2001 Jan Hubicka <jh@suse.cz>
* reg-stack.c (next_flags_user): Use current_block->end
(swap_rtx_condition): Look for next user if flags don't die;
give up on CALL_INSNs; use current_block->end.
*** /p1/x86-64/x86-64/gcc/gcc/reg-stack.c.old Fri Feb 16 17:41:33 2001
--- reg-stack.c Fri Feb 16 19:42:29 2001
*************** next_flags_user (insn)
*** 334,355 ****
{
/* Search forward looking for the first use of this value.
Stop at block boundaries. */
- /* ??? This really cries for BLOCK_END! */
! while (1)
{
insn = NEXT_INSN (insn);
- if (!insn)
- return NULL_RTX;
if (INSN_P (insn) && reg_mentioned_p (ix86_flags_rtx, PATTERN (insn)))
return insn;
! if (GET_CODE (insn) == JUMP_INSN
! || GET_CODE (insn) == CODE_LABEL
! || GET_CODE (insn) == CALL_INSN)
return NULL_RTX;
}
}
/* Reorganise the stack into ascending numbers,
--- 335,352 ----
{
/* Search forward looking for the first use of this value.
Stop at block boundaries. */
! while (insn != current_block->end)
{
insn = NEXT_INSN (insn);
if (INSN_P (insn) && reg_mentioned_p (ix86_flags_rtx, PATTERN (insn)))
return insn;
! if (GET_CODE (insn) == CALL_INSN)
return NULL_RTX;
}
+ return NULL_RTX;
}
/* Reorganise the stack into ascending numbers,
*************** swap_rtx_condition (insn)
*** 1230,1246 ****
/* Search forward looking for the first use of this value.
Stop at block boundaries. */
! /* ??? This really cries for BLOCK_END! */
! while (1)
{
insn = NEXT_INSN (insn);
- if (insn == NULL_RTX)
- return 0;
if (INSN_P (insn) && reg_mentioned_p (dest, insn))
break;
! if (GET_CODE (insn) == JUMP_INSN)
! return 0;
! if (GET_CODE (insn) == CODE_LABEL)
return 0;
}
--- 1227,1238 ----
/* Search forward looking for the first use of this value.
Stop at block boundaries. */
! while (insn != current_block->end)
{
insn = NEXT_INSN (insn);
if (INSN_P (insn) && reg_mentioned_p (dest, insn))
break;
! if (GET_CODE (insn) == CALL_INSN)
return 0;
}
*************** swap_rtx_condition (insn)
*** 1263,1270 ****
--- 1255,1273 ----
if (swap_rtx_condition_1 (pat))
{
+ int fail = 0;
INSN_CODE (insn) = -1;
if (recog_memoized (insn) == -1)
+ fail = 1;
+ /* In case the flags don't die here, recurse to try fix
+ following user too. */
+ else if (! dead_or_set_p (insn, ix86_flags_rtx))
+ {
+ insn = next_flags_user (insn);
+ if (!insn || !swap_rtx_condition (insn))
+ fail = 1;
+ }
+ if (fail)
{
swap_rtx_condition_1 (pat);
return 0;