------- 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