[Bug tree-optimization/18694] [4.0 regression] loop miscompilation at -O1 (-ftree-ch)
------- Additional Comments From steven at gcc dot gnu dot org 2004-12-04 23:26 -------
Looks like a jump threading problem. Given this test case:
void
divisors_bug(long *t, long e)
{
long int *d2;
long int *tmp;
long int *act_d;
long int *old_d;
long int *d;
long int j;
int t1, t2;
d = t;
++d;
*d = 1;
old_d = t;
j = e;
outer_loop_test:
if (j != 0) goto outer_loop_entry; else goto outer_loop_exit;
outer_loop_entry:
d2 = d;
tmp = old_d;
inner_loop_test:
if (d <= tmp) goto inner_loop_exit;
d2++;
tmp++;
t1 = *tmp;
t2 = t1 * 2;
*d2 = t2;
goto inner_loop_test;
inner_loop_exit:
j = j - 1;
old_d = d;
d = d2;
goto outer_loop_test;
outer_loop_exit:
return;
}
I have the following in one of the dominator passes:
divisors_bug (t, e)
{
void inner_loop_exit = <<< error >>>;
void inner_loop_test = <<< error >>>;
void outer_loop_exit = <<< error >>>;
void outer_loop_entry = <<< error >>>;
void outer_loop_test = <<< error >>>;
int t2;
int t1;
long int j;
long int * d;
long int * old_d;
long int * act_d;
long int * tmp;
long int * d2;
long int D.1484;
long int D.1483;
# BLOCK 0
# PRED: ENTRY
d_8 = t_6 + 8B;
# TMT.0_26 = V_MAY_DEF <TMT.0_25>;
*d_8 = 1;
if (e_10 != 0) goto <L14>; else goto <L6>;
# SUCC: 2 5
# BLOCK 1
# PRED: 4
outer_loop_test:;
if (j_14 != 0) goto <L14>; else goto <L6>;
# SUCC: 2 5
# BLOCK 2
# PRED: 0 1
# TMT.0_23 = PHI <TMT.0_26(0), TMT.0_9(1)>;
# j_3 = PHI <e_10(0), j_14(1)>;
# old_d_2 = PHI <t_6(0), d_1(1)>;
# d_1 = PHI <d_8(0), d2_7(1)>;
# TMT.0_16 = PHI <TMT.0_26(0), TMT.0_9(1)>;
# tmp_15 = PHI <t_6(0), d_1(1)>;
# d2_13 = PHI <d_8(0), d2_7(1)>;
<L14>:;
if (d_1 <= tmp_15) goto inner_loop_exit; else goto <L15>;
# SUCC: 4 3
# BLOCK 3
# PRED: 2 3
# TMT.0_12 = PHI <TMT.0_16(2), TMT.0_27(3)>;
# d2_11 = PHI <d2_13(2), d2_17(3)>;
# tmp_5 = PHI <tmp_15(2), tmp_18(3)>;
<L15>:;
d2_17 = d2_11 + 8B;
tmp_18 = tmp_5 + 8B;
# VUSE <TMT.0_12>;
D.1483_19 = *tmp_18;
t1_20 = (int) D.1483_19;
t2_21 = t1_20 * 2;
D.1484_22 = (long int) t2_21;
# TMT.0_27 = V_MAY_DEF <TMT.0_12>;
*d2_17 = D.1484_22;
if (d_1 <= tmp_18) goto inner_loop_exit; else goto <L15>;
# SUCC: 4 3
# BLOCK 4
# PRED: 3 2 6
# TMT.0_9 = PHI <TMT.0_27(3), TMT.0_16(2), TMT.0_16(6)>;
# d2_7 = PHI <d2_17(3), d2_13(2), d2_13(6)>;
inner_loop_exit:;
j_14 = j_3 - 1;
goto <bb 1> (outer_loop_test);
# SUCC: 1
# BLOCK 5
# PRED: 1 0
<L6>:;
return;
# SUCC: EXIT
# BLOCK 6
# PRED:
# TMT.0_23 = PHI <>;
# j_3 = PHI <>;
# old_d_2 = PHI <>;
# d_1 = PHI <>;
# TMT.0_16 = PHI <>;
# tmp_15 = PHI <>;
# d2_13 = PHI <>;
goto <bb 4> (inner_loop_exit);
# SUCC: 4
}
which we turn into this:
divisors_bug (t, e)
{
void inner_loop_exit = <<< error >>>;
void inner_loop_test = <<< error >>>;
void outer_loop_exit = <<< error >>>;
void outer_loop_entry = <<< error >>>;
void outer_loop_test = <<< error >>>;
int t2;
int t1;
long int j;
long int * d;
long int * old_d;
long int * act_d;
long int * tmp;
long int * d2;
long int D.1484;
long int D.1483;
# BLOCK 0
# PRED: ENTRY
d_8 = t_6 + 8B;
# TMT.0_26 = V_MAY_DEF <TMT.0_25>;
*d_8 = 1;
if (e_10 != 0) goto <L14>; else goto <L6>;
# SUCC: 2 5
# BLOCK 1
# PRED: 4
outer_loop_test:;
if (j_14 != 0) goto <L18>; else goto <L6>;
# SUCC: 6 5
# BLOCK 2
# PRED: 0
# TMT.0_23 = PHI <TMT.0_26(0)>;
# j_3 = PHI <e_10(0)>;
# old_d_2 = PHI <t_6(0)>;
# d_1 = PHI <d_8(0)>;
# TMT.0_16 = PHI <TMT.0_26(0)>;
# tmp_15 = PHI <t_6(0)>;
# d2_13 = PHI <d_8(0)>;
<L14>:;
if (d_1 <= tmp_15) goto inner_loop_exit; else goto <L15>;
# SUCC: 4 3
# BLOCK 3
# PRED: 2 3
# TMT.0_12 = PHI <TMT.0_16(2), TMT.0_27(3)>;
# d2_11 = PHI <d2_13(2), d2_17(3)>;
# tmp_5 = PHI <tmp_15(2), tmp_18(3)>;
<L15>:;
d2_17 = d2_11 + 8B;
tmp_18 = tmp_5 + 8B;
# VUSE <TMT.0_12>;
D.1483_19 = *tmp_18;
t1_20 = (int) D.1483_19;
t2_21 = t1_20 * 2;
D.1484_22 = (long int) t2_21;
# TMT.0_27 = V_MAY_DEF <TMT.0_12>;
*d2_17 = D.1484_22;
if (d_1 <= tmp_18) goto inner_loop_exit; else goto <L15>;
# SUCC: 4 3
# BLOCK 4
# PRED: 3 2 6
# TMT.0_9 = PHI <TMT.0_27(3), TMT.0_16(2), TMT.0_16(6)>;
# d2_7 = PHI <d2_17(3), d2_13(2), d2_13(6)>;
inner_loop_exit:;
j_14 = j_3 - 1;
goto <bb 1> (outer_loop_test);
# SUCC: 1
# BLOCK 5
# PRED: 1 0
<L6>:;
return;
# SUCC: EXIT
# BLOCK 6
# PRED: 1
# TMT.0_23 = PHI <TMT.0_9(1)>;
# j_3 = PHI <j_14(1)>;
# old_d_2 = PHI <d_1(1)>;
# d_1 = PHI <d2_7(1)>;
# TMT.0_16 = PHI <TMT.0_9(1)>;
# tmp_15 = PHI <d_1(1)>;
# d2_13 = PHI <d2_7(1)>;
<L18>:;
goto <bb 4> (inner_loop_exit);
# SUCC: 4
}
Note that when optimizing basic block 3, we do a jump thread:
Optimizing statement <L15>:;
Optimizing statement d2_17 = d2_11 + 8B;
Optimizing statement tmp_18 = tmp_5 + 8B;
Optimizing statement D.1483_19 = *tmp_18;
Optimizing statement t1_20 = (int) D.1483_19;
Optimizing statement t2_21 = t1_20 * 2;
Optimizing statement D.1484_22 = (long int) t2_21;
Optimizing statement *d2_17 = D.1484_22;
Optimizing statement if (d_1 <= tmp_18) goto inner_loop_exit; else goto <L15>;
Threaded jump 1 --> 2 to 6
This is the only transformation we do in DOM in this case, and apparently
it's not a correct one (but it's late so I'll leave it for Pinski to look
at it more closely :-)
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18694
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.
Reply to: