re PR rtl-optimization/17581 (Long long arithmetic fails inside a switch/case statement when compiled with -O2)

PR rtl-optimization/17581
	* cselib.c (cselib_process_insn): The last instruction of a libcall
	block, with the REG_RETVAL note, should be considered in the libcall.
	* gcse.c (do_local_cprop): Allow constants to be propagated outside
	of libcall blocks.
	(adjust_libcall_notes): Use simplify_replace_rtx instead of
	replace_rtx to avoid creating invalid RTL in REG_RETVAL notes.

	* gcc.dg/pr17581-1.c: New test case.

From-SVN: r89873
This commit is contained in:
Roger Sayle 2004-10-30 00:56:59 +00:00 committed by Roger Sayle
parent 8b5a12daa0
commit 5976e643ed
5 changed files with 52 additions and 4 deletions

View file

@ -1,3 +1,13 @@
2004-10-29 Roger Sayle <roger@eyesopen.com>
PR rtl-optimization/17581
* cselib.c (cselib_process_insn): The last instruction of a libcall
block, with the REG_RETVAL note, should be considered in the libcall.
* gcse.c (do_local_cprop): Allow constants to be propagated outside
of libcall blocks.
(adjust_libcall_notes): Use simplify_replace_rtx instead of
replace_rtx to avoid creating invalid RTL in REG_RETVAL notes.
2004-10-30 Kazu Hirata <kazu@cs.umass.edu>
* tree-phinodes.c (create_phi_node): Don't zero PHI_REWRITTEN.

View file

@ -1346,8 +1346,6 @@ cselib_process_insn (rtx insn)
if (find_reg_note (insn, REG_LIBCALL, NULL))
cselib_current_insn_in_libcall = true;
if (find_reg_note (insn, REG_RETVAL, NULL))
cselib_current_insn_in_libcall = false;
cselib_current_insn = insn;
/* Forget everything at a CODE_LABEL, a volatile asm, or a setjmp. */
@ -1358,12 +1356,16 @@ cselib_process_insn (rtx insn)
&& GET_CODE (PATTERN (insn)) == ASM_OPERANDS
&& MEM_VOLATILE_P (PATTERN (insn))))
{
if (find_reg_note (insn, REG_RETVAL, NULL))
cselib_current_insn_in_libcall = false;
clear_table ();
return;
}
if (! INSN_P (insn))
{
if (find_reg_note (insn, REG_RETVAL, NULL))
cselib_current_insn_in_libcall = false;
cselib_current_insn = 0;
return;
}
@ -1399,6 +1401,8 @@ cselib_process_insn (rtx insn)
if (GET_CODE (XEXP (x, 0)) == CLOBBER)
cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0));
if (find_reg_note (insn, REG_RETVAL, NULL))
cselib_current_insn_in_libcall = false;
cselib_current_insn = 0;
if (n_useless_values > MAX_USELESS_VALUES)

View file

@ -3134,7 +3134,8 @@ do_local_cprop (rtx x, rtx insn, int alter_jumps, rtx *libcall_sp)
rtx this_rtx = l->loc;
rtx note;
if (l->in_libcall)
/* Don't CSE non-constant values out of libcall blocks. */
if (l->in_libcall && ! CONSTANT_P (this_rtx))
continue;
if (gcse_constant_p (this_rtx))
@ -3222,7 +3223,7 @@ adjust_libcall_notes (rtx oldreg, rtx newval, rtx insn, rtx *libcall_sp)
return true;
}
}
XEXP (note, 0) = replace_rtx (XEXP (note, 0), oldreg, newval);
XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0), oldreg, newval);
insn = end;
}
return true;

View file

@ -1,3 +1,8 @@
2004-10-29 Roger Sayle <roger@eyesopen.com>
PR rtl-optimization/17581
* gcc.dg/pr17581-1.c: New test case.
2004-10-28 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/conversion/dr195.C: Adjust expected errors for DR195 not

View file

@ -0,0 +1,28 @@
/* PR rtl-optimization/17581 */
/* { dg-do run } */
/* { dg-options "-O2" } */
int foo(int x)
{
unsigned long long tmp = 0;
switch(x) {
case 21:
tmp |= 1;
tmp |= 2;
tmp |= 8;
break;
default:
break;
}
return (int)tmp;
}
int main()
{
if (foo(21) != 11)
abort ();
return 0;
}