[Bug middle-end/47383] ivopts miscompiles Pmode != ptr_mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383 --- Comment #14 from hjl at gcc dot gnu.org hjl at gcc dot gnu.org 2011-07-06 13:19:08 UTC --- Author: hjl Date: Wed Jul 6 13:19:04 2011 New Revision: 175912 URL: http://gcc.gnu.org/viewcvs?root=gccview=revrev=175912 Log: Use pointer_mode for address computation. gcc/ 2011-07-06 H.J. Lu hongjiu...@intel.com PR middle-end/47383 * tree-ssa-address.c (addr_for_mem_ref): Use pointer_mode for address computation and convert to address_mode if needed. gcc/testsuite/ 2011-07-06 H.J. Lu hongjiu...@intel.com PR middle-end/47383 * gcc.dg/pr47383.c: New. Added: trunk/gcc/testsuite/gcc.dg/pr47383.c Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-ssa-address.c
[Bug middle-end/47383] ivopts miscompiles Pmode != ptr_mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383 H.J. Lu hjl.tools at gmail dot com changed: What|Removed |Added Status|NEW |RESOLVED Resolution||FIXED Target Milestone|--- |4.7.0 --- Comment #15 from H.J. Lu hjl.tools at gmail dot com 2011-07-06 18:22:46 UTC --- Fixed.
[Bug middle-end/47383] ivopts miscompiles Pmode != ptr_mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383 --- Comment #16 from hjl at gcc dot gnu.org hjl at gcc dot gnu.org 2011-07-06 20:30:13 UTC --- Author: hjl Date: Wed Jul 6 20:30:06 2011 New Revision: 175933 URL: http://gcc.gnu.org/viewcvs?root=gccview=revrev=175933 Log: Use pointer_mode for address computation. gcc/ 2011-07-05 H.J. Lu hongjiu...@intel.com PR middle-end/47383 * tree-ssa-address.c (addr_for_mem_ref): Use pointer_mode for address computation and convert to address_mode if needed. gcc/testsuite/ 2011-07-05 H.J. Lu hongjiu...@intel.com PR middle-end/47383 * gcc.dg/pr47383.c: New. Added: branches/x32/gcc/testsuite/gcc.dg/pr47383.c Modified: branches/x32/gcc/ChangeLog.x32 branches/x32/gcc/testsuite/ChangeLog.x32 branches/x32/gcc/tree-ssa-address.c
[Bug middle-end/47383] ivopts miscompiles Pmode != ptr_mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383 --- Comment #12 from hjl at gcc dot gnu.org hjl at gcc dot gnu.org 2011-02-12 17:36:47 UTC --- Author: hjl Date: Sat Feb 12 17:36:45 2011 New Revision: 170080 URL: http://gcc.gnu.org/viewcvs?root=gccview=revrev=170080 Log: Support 32bit address in x32 mode. 2011-02-11 H.J. Lu hongjiu...@intel.com PR middle-end/47383 * config/i386/i386.c (ix86_decompose_address): Support 32bit address in x32 mode. (ix86_legitimate_address_p): Likewise. (ix86_fixup_binary_operands): Likewise. * config/i386/i386.md (*lea_1_x32): New. Modified: branches/x32/gcc/ChangeLog.x32 branches/x32/gcc/config/i386/i386.c branches/x32/gcc/config/i386/i386.md
[Bug middle-end/47383] ivopts miscompiles Pmode != ptr_mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383 --- Comment #13 from hjl at gcc dot gnu.org hjl at gcc dot gnu.org 2011-02-12 17:37:49 UTC --- Author: hjl Date: Sat Feb 12 17:37:46 2011 New Revision: 170081 URL: http://gcc.gnu.org/viewcvs?root=gccview=revrev=170081 Log: Use ptr_mode instead of targetm.addr_space.address_mode. 2011-02-12 H.J. Lu hongjiu...@intel.com PR middle-end/47383 * tree-ssa-address.c (addr_for_mem_ref): Use ptr_mode instead of targetm.addr_space.address_mode. Modified: branches/x32/gcc/ChangeLog.x32 branches/x32/gcc/tree-ssa-address.c
[Bug middle-end/47383] ivopts miscompiles Pmode != ptr_mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383 --- Comment #11 from hjl at gcc dot gnu.org hjl at gcc dot gnu.org 2011-02-09 17:20:07 UTC --- Author: hjl Date: Wed Feb 9 17:20:00 2011 New Revision: 169979 URL: http://gcc.gnu.org/viewcvs?root=gccview=revrev=169979 Log: Disable ivopts for non-constant base with negative step and Pmode !== ptr_mode. gcc/ 2011-02-09 H.J. Lu hongjiu...@intel.com PR middle-end/47383 * tree-ssa-loop-ivopts.c (find_bivs): Disabled for non-constant base with negative step and Pmode !== ptr_mode. (find_givs_in_stmt): Return for non-constant base with negative step and Pmode !== ptr_mode. (generic_type_for): Change arguments to base and step. Check non-constant base with negative step and Pmode !== ptr_mode. gcc/testsuite/ 2011-02-08 H.J. Lu hongjiu...@intel.com PR middle-end/47383 * gcc.dg/torture/pr47383.c: New. Added: branches/x32/gcc/testsuite/gcc.dg/torture/pr47383.c Modified: branches/x32/gcc/ChangeLog.x32 branches/x32/gcc/testsuite/ChangeLog.x32 branches/x32/gcc/tree-ssa-loop-ivopts.c
[Bug middle-end/47383] ivopts miscompiles Pmode != ptr_mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383 H.J. Lu hjl.tools at gmail dot com changed: What|Removed |Added URL||http://gcc.gnu.org/ml/gcc-p ||atches/2011-02/msg00570.htm ||l --- Comment #10 from H.J. Lu hjl.tools at gmail dot com 2011-02-08 23:09:28 UTC --- A patch is posted at http://gcc.gnu.org/ml/gcc-patches/2011-02/msg00570.html
[Bug middle-end/47383] ivopts miscompiles Pmode != ptr_mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383 Richard Guenther rguenth at gcc dot gnu.org changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2011.02.07 12:25:25 Ever Confirmed|0 |1 --- Comment #9 from Richard Guenther rguenth at gcc dot gnu.org 2011-02-07 12:25:25 UTC --- (In reply to comment #8) (In reply to comment #7) looks wrong since it assumes D.2750_34 can be negative. But sizetype values are sign-extended. ivopts uses unsigned on purpose and create_mem_ref isn't prepared to deal with. This isn't the right fix. It just shows we need to properly sign-extended index when Pmode != ptr_mode: diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c index a9ca835..4926a6d 100644 --- a/gcc/tree-ssa-address.c +++ b/gcc/tree-ssa-address.c @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #include expr.h #include ggc.h #include target.h +#include langhooks.h /* TODO -- handling of symbols (according to Richard Hendersons comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html): @@ -658,6 +659,13 @@ addr_to_parts (tree type, aff_tree *addr, tree iv_cand, } if (addr-rest) add_to_parts (parts, fold_convert (sizetype, addr-rest)); + + if (Pmode != ptr_mode parts-index) +{ + parts-index = fold_convert (ssizetype, parts-index); + parts-index = fold_convert (lang_hooks.types.type_for_mode (Pmode, 0), + parts-index); +} } /* Force the PARTS to register. */ I think the issue is more involved. First we loose any information of the signedness of the offset that was present in the C source because of our stupid idea to convert all pointer offsets to sizetype (which, in its other stupid way is a TYPE_UNSIGNED type that is supposed to be sign-extended). Second, there is no way for the target to specify whether offsets to ptr_mode should be sign- or zero-extended to an integer type of the with of Pmode. We'd need a OFFSETS_EXTEND_UNSIGNED macro for this (if it should be a consistent extension). OTOH on my TODO list there is preserve signedness of pointer offsets, thus, drop the sizetype conversion requirement and just extend offsets based on their actual sign. The above said, a IVOPTs-local solution isn't a solution. We have the same issue with all POINTER_PLUS_EXPRs (how does it happen that they work for you (in all werid cases)?). You can maybe work around the issue by computing the resulting address in ptr_mode (including all offsets) and only then extending to Pmode according to POINTERS_EXTEND_UNSIGNED. That works unless sizetype != ptr_mode size.
[Bug middle-end/47383] ivopts miscompiles Pmode != ptr_mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383 --- Comment #8 from H.J. Lu hjl.tools at gmail dot com 2011-02-04 04:12:59 UTC --- (In reply to comment #7) looks wrong since it assumes D.2750_34 can be negative. But sizetype values are sign-extended. ivopts uses unsigned on purpose and create_mem_ref isn't prepared to deal with. This isn't the right fix. It just shows we need to properly sign-extended index when Pmode != ptr_mode: diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c index a9ca835..4926a6d 100644 --- a/gcc/tree-ssa-address.c +++ b/gcc/tree-ssa-address.c @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #include expr.h #include ggc.h #include target.h +#include langhooks.h /* TODO -- handling of symbols (according to Richard Hendersons comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html): @@ -658,6 +659,13 @@ addr_to_parts (tree type, aff_tree *addr, tree iv_cand, } if (addr-rest) add_to_parts (parts, fold_convert (sizetype, addr-rest)); + + if (Pmode != ptr_mode parts-index) +{ + parts-index = fold_convert (ssizetype, parts-index); + parts-index = fold_convert (lang_hooks.types.type_for_mode (Pmode, 0), + parts-index); +} } /* Force the PARTS to register. */
[Bug middle-end/47383] ivopts miscompiles Pmode != ptr_mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383 --- Comment #6 from pinskia at gmail dot com pinskia at gmail dot com 2011-01-21 11:43:45 UTC --- Sent from my Palm Pre on ATamp;T On Jan 20, 2011 21:34, hjl.tools at gmail dot com lt;gcc-bugzi...@gcc.gnu.orggt; wrote: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383 --- Comment #4 from H.J. Lu lt;hjl.tools at gmail dot comgt; 2011-01-21 05:33:53 UTC --- (In reply to comment #3) gt; The ivopts pass transforms gt; gt; gt; unsigned int D.2715; gt; unsigned int D.2716; gt; ... gt; D.2715_43 = (unsigned int) elems_3(D); gt; D.2716_42 = D.2715_43 + 4294967295; gt; n_49 = (int) D.2716_42; gt; gt; leads o the wrong result when Pmode != unsigned int. Adding gt; -fno-ivopts fixes the bug. gt; This is OK due to cast to int. But 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; ... 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; Mem here should have been rejected. looks wrong since it assumes D.2750_34 can be negative. But D.2750_34 is unsigned. It won't work when ptr_mode == unsigned and Pmode is unsigned long long.
[Bug middle-end/47383] ivopts miscompiles Pmode != ptr_mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383 --- Comment #7 from Richard Guenther rguenth at gcc dot gnu.org 2011-01-21 12:38:22 UTC --- (In reply to comment #6) Sent from my Palm Pre on ATamp;T On Jan 20, 2011 21:34, hjl.tools at gmail dot com lt;gcc-bugzi...@gcc.gnu.orggt; wrote: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383 --- Comment #4 from H.J. Lu lt;hjl.tools at gmail dot comgt; 2011-01-21 05:33:53 UTC --- (In reply to comment #3) gt; The ivopts pass transforms gt; gt; gt; unsigned int D.2715; gt; unsigned int D.2716; gt; ... gt; D.2715_43 = (unsigned int) elems_3(D); gt; D.2716_42 = D.2715_43 + 4294967295; gt; n_49 = (int) D.2716_42; gt; gt; leads o the wrong result when Pmode != unsigned int. Adding gt; -fno-ivopts fixes the bug. gt; This is OK due to cast to int. But 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; ... 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; Mem here should have been rejected. looks wrong since it assumes D.2750_34 can be negative. But sizetype values are sign-extended. D.2750_34 is unsigned. It won't work when ptr_mode == unsigned and Pmode is unsigned long long.
[Bug middle-end/47383] ivopts miscompiles Pmode != ptr_mode
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.
[Bug middle-end/47383] ivopts miscompiles Pmode != ptr_mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383 --- Comment #4 from H.J. Lu hjl.tools at gmail dot com 2011-01-21 05:33:53 UTC --- (In reply to comment #3) The ivopts pass transforms 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. This is OK due to cast to int. But 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; ... 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; looks wrong since it assumes D.2750_34 can be negative. But D.2750_34 is unsigned. It won't work when ptr_mode == unsigned and Pmode is unsigned long long.
[Bug middle-end/47383] ivopts miscompiles Pmode != ptr_mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383 --- Comment #5 from H.J. Lu hjl.tools at gmail dot com 2011-01-21 05:52:47 UTC --- Should ivopts use signed integer instead of unsigned integer for index type if it is known to be negative?