http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383
H.J. Lu <hjl.tools at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- Component|target |middle-end Summary|[x32] Incorrect array |ivopts miscompiles Pmode != |access |ptr_mode --- Comment #3 from H.J. Lu <hjl.tools at gmail dot com> 2011-01-21 05:21:19 UTC --- The ivopts pass transforms foo (int elems) { unsigned int D.2715; unsigned int D.2716; int heap_len_lsm.11; int heap_max_lsm.10; int heap_len_lsm.9; int prephitmp.8; int pretmp.7; int n; int heap_max.4; int heap_len.2; int heap_len.1; <bb 2>: heap_len = 0; heap_max = 573; if (elems_3(D) > 0) goto <bb 4>; else goto <bb 3>; <bb 3>: pretmp.7_15 = heap[0]; goto <bb 8>; <bb 4>: <bb 5>: # n_19 = PHI <n_10(6), 0(4)> # prephitmp.8_44 = PHI <heap_len.1_7(6), 0(4)> heap_len.1_7 = prephitmp.8_44 + 1; heap[heap_len.1_7] = n_19; n_10 = n_19 + 1; if (elems_3(D) > n_10) goto <bb 6>; else goto <bb 7>; <bb 6>: goto <bb 5>; <bb 7>: heap_len.1_48 = elems_3(D); D.2715_43 = (unsigned int) elems_3(D); D.2716_42 = D.2715_43 + 4294967295; n_49 = (int) D.2716_42; heap_len_lsm.11_50 = elems_3(D); heap_len = elems_3(D); <bb 8>: # prephitmp.8_18 = PHI <elems_3(D)(7), 0(3)> # prephitmp.8_22 = PHI <n_49(7), pretmp.7_15(3)> <bb 9>: # prephitmp.8_37 = PHI <prephitmp.8_18(8), heap_len.2_14(10)> # prephitmp.8_39 = PHI <prephitmp.8_22(8), pretmp.7_38(10)> # prephitmp.8_41 = PHI <573(8), heap_max.4_20(10)> n_11 = heap[1]; heap[1] = prephitmp.8_39; heap_len.2_14 = prephitmp.8_37 + -1; heap_max.4_17 = prephitmp.8_41 + -1; heap[heap_max.4_17] = n_11; heap_max.4_20 = heap_max.4_17 + -1; heap[heap_max.4_20] = prephitmp.8_39; if (heap_len.2_14 > 1) goto <bb 10>; else goto <bb 11>; <bb 10>: pretmp.7_38 = heap[heap_len.2_14]; goto <bb 9>; <bb 11>: # heap_max_lsm.10_51 = PHI <heap_max.4_20(9)> # heap_len_lsm.9_52 = PHI <heap_len.2_14(9)> heap_len = heap_len_lsm.9_52; heap_max = heap_max_lsm.10_51; return; } to foo (int elems) { long unsigned int D.2757; long unsigned int D.2749; long unsigned int D.2750; unsigned int ivtmp.20; int D.2748; unsigned int ivtmp.17; unsigned int D.2715; unsigned int D.2716; int heap_len_lsm.11; int heap_max_lsm.10; int heap_len_lsm.9; int prephitmp.8; int pretmp.7; int n; int heap_max.4; int heap_len.2; int heap_len.1; <bb 2>: heap_len = 0; heap_max = 573; if (elems_3(D) > 0) goto <bb 4>; else goto <bb 3>; <bb 3>: pretmp.7_15 = heap[0]; goto <bb 8>; <bb 4>: <bb 5>: # prephitmp.8_44 = PHI <heap_len.1_7(6), 0(4)> n_19 = prephitmp.8_44; heap_len.1_7 = prephitmp.8_44 + 1; D.2757_41 = (long unsigned int) heap_len.1_7; MEM[symbol: heap, index: D.2757_41, step: 4, offset: 0B] = n_19; if (heap_len.1_7 != elems_3(D)) goto <bb 6>; else goto <bb 7>; <bb 6>: goto <bb 5>; <bb 7>: heap_len.1_48 = elems_3(D); D.2715_43 = (unsigned int) elems_3(D); D.2716_42 = D.2715_43 + 4294967295; n_49 = (int) D.2716_42; heap_len_lsm.11_50 = elems_3(D); heap_len = elems_3(D); <bb 8>: # prephitmp.8_18 = PHI <elems_3(D)(7), 0(3)> # prephitmp.8_22 = PHI <n_49(7), pretmp.7_15(3)> D.2748_13 = prephitmp.8_18 + -1; ivtmp.17_40 = (unsigned int) D.2748_13; <bb 9>: # prephitmp.8_39 = PHI <prephitmp.8_22(8), pretmp.7_38(10)> # ivtmp.17_28 = PHI <ivtmp.17_40(8), ivtmp.17_12(10)> # ivtmp.20_16 = PHI <571(8), ivtmp.20_36(10)> n_11 = heap[1]; heap[1] = prephitmp.8_39; heap_len.2_14 = (int) ivtmp.17_28; D.2749_6 = (long unsigned int) prephitmp.8_18; D.2750_34 = ivtmp.17_28 - D.2749_6; MEM[symbol: heap, index: D.2750_34, step: 8, offset: 2296B] = n_11; heap_max.4_20 = (int) ivtmp.20_16; MEM[symbol: heap, index: ivtmp.20_16, step: 4, offset: 0B] = prephitmp.8_39; ivtmp.20_36 = ivtmp.20_16 - 2; heap_len.2_46 = (int) ivtmp.17_28; if (heap_len.2_46 > 1) goto <bb 10>; else goto <bb 11>; <bb 10>: pretmp.7_38 = MEM[symbol: heap, index: ivtmp.17_28, step: 4, offset: 0B]; ivtmp.17_12 = ivtmp.17_28 - 1; goto <bb 9>; <bb 11>: # heap_max_lsm.10_51 = PHI <heap_max.4_20(9)> # heap_len_lsm.9_52 = PHI <heap_len.2_14(9)> heap_len = heap_len_lsm.9_52; heap_max = heap_max_lsm.10_51; return; } But unsigned int D.2715; unsigned int D.2716; ... D.2715_43 = (unsigned int) elems_3(D); D.2716_42 = D.2715_43 + 4294967295; n_49 = (int) D.2716_42; leads o the wrong result when Pmode != unsigned int. Adding -fno-ivopts fixes the bug. Technically, it is a 4.6 regression since ivopts in GCC 4.4 doesn't do such invalid transformation.