During stagefeedback (PGO bootstrap) gcc gets miscompiled. It segfaults when building libgcc, e.g.: trippels@gcc2-power8 libgcc % gdb --args /home/trippels/gcc_build_dir_/./gcc/xgcc -B/home/trippels/gcc_build_dir_/./gcc/ -B/usr/local/powerpc64le-unknown-linux-gnu/bin/ -B/usr/local/powerpc64le-unknown-linux-gnu/lib/ -isystem /usr/local/powerpc64le-unknown-linux-gnu/include -isystem /usr/local/powerpc64le-unknown-linux-gnu/sys-include -mcpu=power8 -Wno-error=coverage-mismatch -O3 -pipe -O2 -mcpu=power8 -Wno-error=coverage-mismatch -O3 -pipe -DIN_GCC -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -fPIC -mlong-double-128 -mno-minimal-toc -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -fPIC -mlong-double-128 -mno-minimal-toc -I. -I. -I../.././gcc -I../../../gcc/libgcc -I../../../gcc/libgcc/. -I../../../gcc/libgcc/../gcc -I../../../gcc/libgcc/../include -I../../../gcc/libgcc/../libdecnumber/dpd -I../../../gcc/libgcc/../libdecnumber -DHAVE_CC_TLS -o _gcov_merge_add.o -MT _gcov_merge_add.o -MD -MP -MF _gcov_merge_add.dep -DL_gcov_merge_add -c ../../../gcc/libgcc/libgcov-merge.c Thread 2.1 "cc1" received signal SIGSEGV, Segmentation fault. [Switching to process 9861] 0x0000000010317914 in nearest_common_dominator_for_set(cdi_direction, bitmap_head*) () (gdb) bt #0 0x0000000010317914 in nearest_common_dominator_for_set(cdi_direction, bitmap_head*) () #1 0x0000000010610f70 in update_ssa(unsigned int) () #2 0x00000000107a36ac in (anonymous namespace)::pass_vrp::execute(function*) () #3 0x000000001051b39c in execute_one_pass(opt_pass*) () #4 0x000000001051ec40 in execute_pass_list(function*, opt_pass*) () #5 0x00000000102c1f84 in cgraph_node::expand() () #6 0x0000000010af4620 in symbol_table::compile() () #7 0x00000000102be550 in symbol_table::finalize_compilation_unit() () #8 0x0000000010d220dc in compile_file() () #9 0x00000000101b36ec in toplev::main(int, char**) () #10 0x00000000101b5928 in main ()
Also happens on X86_64, so I guess the issue is target independent.
Started with r254536.
../gcc/configure --disable-libstdcxx-pch --disable-libvtv --disable-libitm --disable-libcilkrts --disable-libssp --disable-libgomp --disable-werror --disable-multilib --enable-languages=c,c++,fortran --enable-checking=release make -j8 BOOT_CFLAGS="-Wno-error=coverage-mismatch -march=native -O3 -pipe" STAGE1_CFLAGS="-Wno-error=coverage-mismatch -march=native -O3 -pipe" CFLAGS_FOR_TARGET="-Wno-error=coverage-mismatch -march=native -O3 -pipe" CXXFLAGS_FOR_TARGET="-Wno-error=coverage-mismatch -march=native -O3 -pipe" profiledbootstrap
Seems it is et-forest.o that matters, and compiling it with -fno-store-merging makes the ICE go away.
So, reduced testcase for -O2 -fno-tree-dse is like: struct allocation_pool_list { struct allocation_pool_list *next; }; struct et_node; struct et_occ { struct et_node *of; struct et_occ *parent, *prev, *next; int depth; int min; struct et_occ *min_occ; }; struct et_occ * et_new_occ (struct et_node *node) { struct allocation_pool_list *p = __builtin_malloc (sizeof (struct et_occ)); p->next = 0; struct et_occ *nw = (struct et_occ *)(void *)p; nw->of = node; nw->parent = 0; nw->prev = 0; nw->next = 0; nw->depth = 0; nw->min_occ = nw; nw->min = 0; return nw; } (the original has some inlined functions and operator new). And the problem is that r254536 aliasing changes for some reason allow this to be optimized as: p_3 = __builtin_malloc (48); - p_3->next = 0B; MEM[(struct et_occ *)p_3].of = node_5(D); + MEM[(struct et_occ *)p_3].min_occ = p_3; + p_3->next = 0B; MEM[(struct et_occ *)p_3].parent = 0B; MEM[(struct et_occ *)p_3].prev = 0B; MEM[(struct et_occ *)p_3].next = 0B; - MEM[(struct et_occ *)p_3].depth = 0; - MEM[(struct et_occ *)p_3].min_occ = p_3; - MEM[(struct et_occ *)p_3].min = 0; + MEM[(int *)p_3 + 32B] = 0; which is wrong, because the p_3->next store is at the same offset/size (i.e. must alias) as MEM[(struct et_occ *)p_3].of and by moving p_3->next = 0B; after it the of field will not be whatever has been passed, but NULL instead.
What the code does is when seeing the MEM[(struct et_occ *)p_3].of = node_5(D); store, we go through all current chains (there is exactly one at that point) and for each chain through all their stmts and do: 961 if (ref_maybe_used_by_stmt_p (stmt, gimple_assign_lhs (info->stmt)) 962 || stmt_may_clobber_ref_p (stmt, gimple_assign_lhs (info->stmt))) stmt here is MEM[(struct et_occ *)p_3].of = node_5(D); and info->stmt is p_3->next = 0B; And because both of these functions return false, we think there can't be any aliasing. We want to make sure that if there are any (valid) uses of the memory set by the info->stmt store, or if we are overwriting any part of the info->stmt lhs memory in stmt that we terminate the chain. Are these functions not the right alias functions to call?
Created attachment 42567 [details] gcc8-pr82916.patch Untested fix.
(In reply to Jakub Jelinek from comment #7) > Created attachment 42567 [details] > gcc8-pr82916.patch > > Untested fix. As you figured ref_maybe_used_by_stmt and stmt_clobbers_ref_p are supposed to be read-write dependence checks. Note you may not use stmt_clobbers_ref_p to ask whether to re-order ... = read; write = ...; you'd have to use refs_anti_dependent_p. The fix looks correct but as noted above you might want to audit the checks for the possibility of the case anti-dependence checks lurking (which wouldn't be handled correctly either).
Author: jakub Date: Fri Nov 10 10:31:34 2017 New Revision: 254623 URL: https://gcc.gnu.org/viewcvs?rev=254623&root=gcc&view=rev Log: PR bootstrap/82916 * gimple-ssa-store-merging.c (pass_store_merging::terminate_all_aliasing_chains): For gimple_store_p stmts also call refs_output_dependent_p. * gcc.dg/store_merging_2.c: Only expect 2 successful mergings instead of 3. * gcc.dg/pr82916.c: New test. Added: trunk/gcc/testsuite/gcc.dg/pr82916.c Modified: trunk/gcc/ChangeLog trunk/gcc/gimple-ssa-store-merging.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.dg/store_merging_2.c
Fixed.
Author: jakub Date: Sat Mar 3 13:38:48 2018 New Revision: 258201 URL: https://gcc.gnu.org/viewcvs?rev=258201&root=gcc&view=rev Log: Backported from mainline 2018-02-22 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/84503 * gcc.dg/pr84503-1.c: New test. * gcc.dg/pr84503-2.c: New test. 2017-11-10 Jakub Jelinek <jakub@redhat.com> PR bootstrap/82916 * gimple-ssa-store-merging.c (pass_store_merging::terminate_all_aliasing_chains): For gimple_store_p stmts also call refs_output_dependent_p. * gcc.dg/pr82916.c: New test. Added: branches/gcc-7-branch/gcc/testsuite/gcc.dg/pr82916.c branches/gcc-7-branch/gcc/testsuite/gcc.dg/pr84503-1.c branches/gcc-7-branch/gcc/testsuite/gcc.dg/pr84503-2.c Modified: branches/gcc-7-branch/gcc/ChangeLog branches/gcc-7-branch/gcc/gimple-ssa-store-merging.c branches/gcc-7-branch/gcc/testsuite/ChangeLog