-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Found by inspection while working on another threading patch. DOM tracks equivalences in a stack so that it can restore the state of the known equivalences as it completes processing a block in the dominator tree. The threading code also utilizes this stack so that it can temporarily record equivalences as it threads through the cfg successors of leafs in the dominator tree. The threading code removes the equivalences it records through the remove_temporary_equivalences call. However, in the case where we successfully thread through a block, we end up calling remove_temporary_equivalences twice from the threading code. This results in removing too many equivalences and ultimately missed optimizations. Ultimately it's a missing return statement. This has gone unnoticed since I introduced the problem in gcc-4.2; of course the only symptom of this problem is missed optimizations. Bootstrapped, regression tested on x86_64-unknown-linux-gnu. Installed as obvious. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/ iQEcBAEBAgAGBQJNu4Y3AAoJEBRtltQi2kC7XKQIAJrS/agWlbPkKaUoA6I9wZmA WSI/k8UrLhnm9QPgAGislM7j+Z3v8kURnIx1zvA/aCrO2eDAOGUhqi16q8x9n4O8 pExfhRoDRgaZhBPofC8cQ4ruW2PSGgKOUkVzsHHX8sA2Sr8lC8yVnHeBc0kxBPva m9ygcf5Cm/1egXoEhG1m1Egwvu1dv83XUP0JhZJs80GQkCdHO4dWQxowGnTwtJh1 /yP2nYOEwbUblPr/FvD9kAheOFeU4+qktGi7NAhXL39Q9wVb//ma3aW5g2tAfvsa +Yc6w3vRKmXH0NfVfiCPk9QPSNf4tcl7hEa5+4z9aQwgez1u6cqPZpavlDLP9Gc= =85sA -----END PGP SIGNATURE-----
* tree-ssa-threadedge.c (thread_across_edge): Add missing return. * gcc.dg/tree-ssa/ssa-dom-thread-4.c: New test. Index: testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c =================================================================== *** testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c (revision 0) --- testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c (revision 0) *************** *** 0 **** --- 1,63 ---- + /* { dg-do compile } */ + /* { dg-options "-O2 -fdump-tree-dom1-details" } */ + struct bitmap_head_def; + typedef struct bitmap_head_def *bitmap; + typedef const struct bitmap_head_def *const_bitmap; + typedef unsigned long BITMAP_WORD; + typedef struct bitmap_element_def + { + struct bitmap_element_def *next; + unsigned int indx; + } bitmap_element; + + + + + + + + + + unsigned char + bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b, + const_bitmap kill) + { + unsigned char changed = 0; + + bitmap_element *dst_elt; + const bitmap_element *a_elt, *b_elt, *kill_elt, *dst_prev; + + while (a_elt || b_elt) + { + unsigned char new_element = 0; + + if (b_elt) + while (kill_elt && kill_elt->indx < b_elt->indx) + kill_elt = kill_elt->next; + + if (b_elt && kill_elt && kill_elt->indx == b_elt->indx + && (!a_elt || a_elt->indx >= b_elt->indx)) + { + bitmap_element tmp_elt; + unsigned ix; + + BITMAP_WORD ior = 0; + + changed = bitmap_elt_ior (dst, dst_elt, dst_prev, + a_elt, &tmp_elt, changed); + + } + + } + + + return changed; + } + /* The block starting the second conditional has 3 incoming edges, + we should thread all three, but due to a bug in the threading + code we missed the edge when the first conditional is false + (b_elt is zero, which means the second conditional is always + zero. */ + /* { dg-final { scan-tree-dump-times "Threaded" 3 "dom1"} } */ + /* { dg-final { cleanup-tree-dump "dom1" } } */ + Index: tree-ssa-threadedge.c =================================================================== *** tree-ssa-threadedge.c (revision 173175) --- tree-ssa-threadedge.c (working copy) *************** thread_across_edge (gimple dummy_cond, *** 771,776 **** --- 771,777 ---- remove_temporary_equivalences (stack); register_jump_thread (e, taken_edge); + return; } }