Commit 7a98fb6e by Kyrylo Tkachov Committed by Kyrylo Tkachov

[RTL ifcvt] PR rtl-optimization/71594: ICE in noce_emit_cmove due to mismatched source modes

	PR rtl-optimization/71594
	* ifcvt.c (noce_convert_multiple_sets): Wrap new_val or old_val
	into subregs of appropriate mode before trying to emit a conditional
	move.

	* gcc.dg/torture/pr71594.c: New test.

From-SVN: r238013
parent 1e3d54b4
2016-07-05 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR rtl-optimization/71594
* ifcvt.c (noce_convert_multiple_sets): Wrap new_val or old_val
into subregs of appropriate mode before trying to emit a conditional
move.
2016-07-05 Jan Hubicka <jh@suse.cz>
* tree-scalar-evolution.c (iv_can_overflow_p): New function.
......
......@@ -3228,6 +3228,41 @@ noce_convert_multiple_sets (struct noce_if_info *if_info)
if (if_info->then_else_reversed)
std::swap (old_val, new_val);
/* We allow simple lowpart register subreg SET sources in
bb_ok_for_noce_convert_multiple_sets. Be careful when processing
sequences like:
(set (reg:SI r1) (reg:SI r2))
(set (reg:HI r3) (subreg:HI (r1)))
For the second insn new_val or old_val (r1 in this example) will be
taken from the temporaries and have the wider mode which will not
match with the mode of the other source of the conditional move, so
we'll end up trying to emit r4:HI = cond ? (r1:SI) : (r3:HI).
Wrap the two cmove operands into subregs if appropriate to prevent
that. */
if (GET_MODE (new_val) != GET_MODE (temp))
{
machine_mode src_mode = GET_MODE (new_val);
machine_mode dst_mode = GET_MODE (temp);
if (GET_MODE_SIZE (src_mode) <= GET_MODE_SIZE (dst_mode))
{
end_sequence ();
return FALSE;
}
new_val = lowpart_subreg (dst_mode, new_val, src_mode);
}
if (GET_MODE (old_val) != GET_MODE (temp))
{
machine_mode src_mode = GET_MODE (old_val);
machine_mode dst_mode = GET_MODE (temp);
if (GET_MODE_SIZE (src_mode) <= GET_MODE_SIZE (dst_mode))
{
end_sequence ();
return FALSE;
}
old_val = lowpart_subreg (dst_mode, old_val, src_mode);
}
/* Actually emit the conditional move. */
rtx temp_dest = noce_emit_cmove (if_info, temp, cond_code,
x, y, new_val, old_val);
......
2016-07-05 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR rtl-optimization/71594
* gcc.dg/torture/pr71594.c: New test.
2016-07-05 Jan Hubicka <jh@suse.cz>
* gcc.dg/tree-ssa/scev-14.c: new testcase.
......
/* { dg-do compile } */
/* { dg-options "--param max-rtl-if-conversion-insns=2" } */
unsigned short a;
int b, c;
int *d;
void fn1() {
*d = 24;
for (; *d <= 65;) {
unsigned short *e = &a;
b = (a &= 0 <= 0) < (c ?: (*e %= *d));
for (; *d <= 83;)
;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment