mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-03 05:10:26 +08:00
re PR rtl-optimization/63659 (wrong code at -O2 and -O3 on x86_64-linux-gnu)
PR rtl-optimization/63659 * ree.c (update_reg_equal_equiv_notes): New function. (combine_set_extension, transform_ifelse): Use it. * gcc.c-torture/execute/pr63659.c: New test. From-SVN: r216985
This commit is contained in:
parent
62871ba282
commit
73c49bf53a
@ -1,3 +1,9 @@
|
||||
2014-10-31 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/63659
|
||||
* ree.c (update_reg_equal_equiv_notes): New function.
|
||||
(combine_set_extension, transform_ifelse): Use it.
|
||||
|
||||
2014-10-31 Jeff Law <law@redhat.com>
|
||||
|
||||
* doc/contrib.texi: Add contribution notes for Balaji Iyer (Cilk+)
|
||||
|
56
gcc/ree.c
56
gcc/ree.c
@ -274,6 +274,50 @@ typedef struct ext_cand
|
||||
|
||||
static int max_insn_uid;
|
||||
|
||||
/* Update or remove REG_EQUAL or REG_EQUIV notes for INSN. */
|
||||
|
||||
static bool
|
||||
update_reg_equal_equiv_notes (rtx_insn *insn, machine_mode new_mode,
|
||||
machine_mode old_mode, enum rtx_code code)
|
||||
{
|
||||
rtx *loc = ®_NOTES (insn);
|
||||
while (*loc)
|
||||
{
|
||||
enum reg_note kind = REG_NOTE_KIND (*loc);
|
||||
if (kind == REG_EQUAL || kind == REG_EQUIV)
|
||||
{
|
||||
rtx orig_src = XEXP (*loc, 0);
|
||||
/* Update equivalency constants. Recall that RTL constants are
|
||||
sign-extended. */
|
||||
if (GET_CODE (orig_src) == CONST_INT
|
||||
&& HOST_BITS_PER_WIDE_INT >= GET_MODE_BITSIZE (new_mode))
|
||||
{
|
||||
if (INTVAL (orig_src) >= 0 || code == SIGN_EXTEND)
|
||||
/* Nothing needed. */;
|
||||
else
|
||||
{
|
||||
/* Zero-extend the negative constant by masking out the
|
||||
bits outside the source mode. */
|
||||
rtx new_const_int
|
||||
= gen_int_mode (INTVAL (orig_src)
|
||||
& GET_MODE_MASK (old_mode),
|
||||
new_mode);
|
||||
if (!validate_change (insn, &XEXP (*loc, 0),
|
||||
new_const_int, true))
|
||||
return false;
|
||||
}
|
||||
loc = &XEXP (*loc, 1);
|
||||
}
|
||||
/* Drop all other notes, they assume a wrong mode. */
|
||||
else if (!validate_change (insn, loc, XEXP (*loc, 1), true))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
loc = &XEXP (*loc, 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Given a insn (CURR_INSN), an extension candidate for removal (CAND)
|
||||
and a pointer to the SET rtx (ORIG_SET) that needs to be modified,
|
||||
this code modifies the SET rtx to a new SET rtx that extends the
|
||||
@ -295,6 +339,7 @@ static bool
|
||||
combine_set_extension (ext_cand *cand, rtx_insn *curr_insn, rtx *orig_set)
|
||||
{
|
||||
rtx orig_src = SET_SRC (*orig_set);
|
||||
machine_mode orig_mode = GET_MODE (SET_DEST (*orig_set));
|
||||
rtx new_set;
|
||||
rtx cand_pat = PATTERN (cand->insn);
|
||||
|
||||
@ -331,9 +376,8 @@ combine_set_extension (ext_cand *cand, rtx_insn *curr_insn, rtx *orig_set)
|
||||
{
|
||||
/* Zero-extend the negative constant by masking out the bits outside
|
||||
the source mode. */
|
||||
machine_mode src_mode = GET_MODE (SET_DEST (*orig_set));
|
||||
rtx new_const_int
|
||||
= gen_int_mode (INTVAL (orig_src) & GET_MODE_MASK (src_mode),
|
||||
= gen_int_mode (INTVAL (orig_src) & GET_MODE_MASK (orig_mode),
|
||||
GET_MODE (new_reg));
|
||||
new_set = gen_rtx_SET (VOIDmode, new_reg, new_const_int);
|
||||
}
|
||||
@ -372,7 +416,9 @@ combine_set_extension (ext_cand *cand, rtx_insn *curr_insn, rtx *orig_set)
|
||||
|
||||
/* This change is a part of a group of changes. Hence,
|
||||
validate_change will not try to commit the change. */
|
||||
if (validate_change (curr_insn, orig_set, new_set, true))
|
||||
if (validate_change (curr_insn, orig_set, new_set, true)
|
||||
&& update_reg_equal_equiv_notes (curr_insn, cand->mode, orig_mode,
|
||||
cand->code))
|
||||
{
|
||||
if (dump_file)
|
||||
{
|
||||
@ -422,7 +468,9 @@ transform_ifelse (ext_cand *cand, rtx_insn *def_insn)
|
||||
ifexpr = gen_rtx_IF_THEN_ELSE (cand->mode, cond, map_srcreg, map_srcreg2);
|
||||
new_set = gen_rtx_SET (VOIDmode, map_dstreg, ifexpr);
|
||||
|
||||
if (validate_change (def_insn, &PATTERN (def_insn), new_set, true))
|
||||
if (validate_change (def_insn, &PATTERN (def_insn), new_set, true)
|
||||
&& update_reg_equal_equiv_notes (def_insn, cand->mode, GET_MODE (dstreg),
|
||||
cand->code))
|
||||
{
|
||||
if (dump_file)
|
||||
{
|
||||
|
@ -1,3 +1,8 @@
|
||||
2014-10-31 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/63659
|
||||
* gcc.c-torture/execute/pr63659.c: New test.
|
||||
|
||||
2014-10-31 Evgeny Stupachenko <evstupac@gmail.com>
|
||||
|
||||
PR target/63534
|
||||
|
29
gcc/testsuite/gcc.c-torture/execute/pr63659.c
Normal file
29
gcc/testsuite/gcc.c-torture/execute/pr63659.c
Normal file
@ -0,0 +1,29 @@
|
||||
/* PR rtl-optimization/63659 */
|
||||
|
||||
int a, b, c, *d = &b, g, h, i;
|
||||
unsigned char e;
|
||||
char f;
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
while (a)
|
||||
{
|
||||
for (a = 0; a; a++)
|
||||
for (; c; c++)
|
||||
;
|
||||
if (i)
|
||||
break;
|
||||
}
|
||||
|
||||
char j = c, k = -1, l;
|
||||
l = g = j >> h;
|
||||
f = l == 0 ? k : k % l;
|
||||
e = 0 ? 0 : f;
|
||||
*d = e;
|
||||
|
||||
if (b != 255)
|
||||
__builtin_abort ();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user