As mentioned in following sub-thread: https://gcc.gnu.org/ml/gcc-patches/2018-10/msg01885.html Using the sanitization patch I see: $ ./xgcc -B. /home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/torture/pr63941.c -O2 -c hash table checking failed: equal operator returns true for a pair of values with a different hash value during GIMPLE pass: lim /home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/torture/pr63941.c: In function ‘fn1’: /home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/torture/pr63941.c:6:1: internal compiler error: in hashtab_chk_error, at hash-table.h:1015 6 | fn1 () | ^~~ 0x1372cfd hashtab_chk_error /home/marxin/Programming/gcc/gcc/hash-table.h:1015 0x137e501 hash_table<mem_ref_hasher, false, xcallocator>::verify(ao_ref* const&, unsigned int) /home/marxin/Programming/gcc/gcc/hash-table.h:1036 0x137d5d5 hash_table<mem_ref_hasher, false, xcallocator>::find_slot_with_hash(ao_ref* const&, unsigned int, insert_option) /home/marxin/Programming/gcc/gcc/hash-table.h:953 0x137874a gather_mem_refs_stmt /home/marxin/Programming/gcc/gcc/tree-ssa-loop-im.c:1501 0x1378e4d analyze_memory_references /home/marxin/Programming/gcc/gcc/tree-ssa-loop-im.c:1625 0x137b334 tree_ssa_lim /home/marxin/Programming/gcc/gcc/tree-ssa-loop-im.c:2646 0x137b460 execute /home/marxin/Programming/gcc/gcc/tree-ssa-loop-im.c:2708
Not exactly sure what happens, need to investigate. The testcase looks innocous enough at least ...
(In reply to Richard Biener from comment #1) > Not exactly sure what happens, need to investigate. The testcase looks > innocous enough at least ... It's about 'd[f]' and 'd[0]' references. The former one is hashed in else branch and the later in true branch. These are then equal in mem_ref_hasher::equal as operand_equal_p can return true for these 2 array references. 1479 if (aor.max_size_known_p () 1480 && aor.offset.is_constant (&offset) 1481 && aor.size.is_constant (&size) 1482 && aor.max_size.is_constant (&max_size) 1483 && size == max_size 1484 && (size % BITS_PER_UNIT) == 0 1485 /* We're canonicalizing to a MEM where TYPE_SIZE specifies the 1486 size. Make sure this is consistent with the extraction. */ 1487 && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (*mem))) 1488 && known_eq (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (*mem))), 1489 aor.size) 1490 && (mem_base = get_addr_base_and_unit_offset (aor.ref, &mem_off))) 1491 { 1492 hash = iterative_hash_expr (ao_ref_base (&aor), 0); 1493 hash = iterative_hash_host_wide_int (offset, hash); 1494 hash = iterative_hash_host_wide_int (size, hash); 1495 } 1496 else 1497 { 1498 hash = iterative_hash_expr (aor.ref, 0); 1499 aor.max_size = -1; 1500 }
On Mon, 13 May 2019, marxin at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90450 > > --- Comment #2 from Martin Liška <marxin at gcc dot gnu.org> --- > (In reply to Richard Biener from comment #1) > > Not exactly sure what happens, need to investigate. The testcase looks > > innocous enough at least ... > > It's about 'd[f]' and 'd[0]' references. The former one is hashed in else > branch and the later > in true branch. These are then equal in mem_ref_hasher::equal as > operand_equal_p can return true > for these 2 array references. Huh? Would have to debug this. The equality function probably should start with if (mem1->mem.max_size_known_p () != obj2->max_size_known_p ()) return false; which may fix the issue. As said, need to reproduce locally.
OK, so it's not operand_equal_p of d[f.1_1] and d[0] returning true but the comparison involving the ao_ref pieces. And indeed the variable-offset one is fenced off by && (mem_base = get_addr_base_and_unit_offset (aor.ref, &mem_off))) but using max_size == -1 as tie-breaker doesn't work for the entities in the hash-table (we never compare!) because we only use max_size == -1 on the on-stack ref we use for the find_slot_with_hash call but actually insert the original value: ... else { hash = iterative_hash_expr (aor.ref, 0); aor.max_size = -1; } slot = memory_accesses.refs->find_slot_with_hash (&aor, hash, INSERT); aor.max_size = saved_maxsize; so the checking code is "flawed"... (I thought we didn't want to lose the extra disambiguation opportunity from having known max_size). So - not really a bug. Could be worked around by extra runtime overhead checking everything we check before the decision on the hashing scheme also in the equality routine. Or finding some spare bit in the non-loop-IM private ao_ref stucture. Or constructing a full im_mem_ref on the stack even if hash lookup only really needs the ao_ref and put this extra bit there. Bah :/ Guard the checking on entry type == comparable type?
Created attachment 46389 [details] patch The attached should fix the issue. Martin?
Author: rguenth Date: Wed May 22 07:44:24 2019 New Revision: 271503 URL: https://gcc.gnu.org/viewcvs?rev=271503&root=gcc&view=rev Log: 2019-05-22 Richard Biener <rguenther@suse.de> PR tree-optimization/90450 * tree-ssa-loop-im.c (struct im_mem_ref): Add ref_decomposed. (mem_ref_hasher::equal): Check it. (mem_ref_alloc): Initialize it. (gather_mem_refs_stmt): Set it. Modified: trunk/gcc/ChangeLog trunk/gcc/tree-ssa-loop-im.c
Fixed on trunk sofar.
Author: rguenth Date: Thu Jun 6 11:06:45 2019 New Revision: 271995 URL: https://gcc.gnu.org/viewcvs?rev=271995&root=gcc&view=rev Log: 2019-06-06 Richard Biener <rguenther@suse.de> Backport from mainline 2019-05-22 Richard Biener <rguenther@suse.de> PR tree-optimization/90450 * tree-ssa-loop-im.c (struct im_mem_ref): Add ref_decomposed. (mem_ref_hasher::equal): Check it. (mem_ref_alloc): Initialize it. (gather_mem_refs_stmt): Set it. 2019-05-15 Richard Biener <rguenther@suse.de> PR c/90474 * c-common.c (c_common_mark_addressable_vec): Also mark a COMPOUND_LITERAL_EXPR_DECL addressable similar to c_mark_addressable. 2019-05-13 Richard Biener <rguenther@suse.de> PR tree-optimization/90402 * tree-if-conv.c (tree_if_conversion): Value number only the loop body by making the latch an exit of the region as well. * tree-ssa-sccvn.c (process_bb): Add flag whether to skip processing PHIs. (do_rpo_vn): Deal with multiple edges into the entry block that are not backedges inside the region by skipping PHIs of the entry block. * gcc.dg/torture/pr90402-1.c: New testcase. 2019-05-06 Richard Biener <rguenther@suse.de> PR tree-optimization/90328 * tree-data-ref.h (dr_may_alias_p): Pass in the actual loop nest. * tree-data-ref.c (dr_may_alias_p): Check whether the clique is valid in the loop nest before using it. (initialize_data_dependence_relation): Adjust. * graphite-scop-detection.c (build_alias_set): Pass the SCOP enclosing loop as loop-nest to dr_may_alias_p. * gcc.dg/torture/pr90328.c: New testcase. Added: branches/gcc-9-branch/gcc/testsuite/gcc.dg/torture/pr90328.c branches/gcc-9-branch/gcc/testsuite/gcc.dg/torture/pr90402-1.c Modified: branches/gcc-9-branch/gcc/ChangeLog branches/gcc-9-branch/gcc/c-family/ChangeLog branches/gcc-9-branch/gcc/c-family/c-common.c branches/gcc-9-branch/gcc/graphite-scop-detection.c branches/gcc-9-branch/gcc/testsuite/ChangeLog branches/gcc-9-branch/gcc/tree-data-ref.c branches/gcc-9-branch/gcc/tree-data-ref.h branches/gcc-9-branch/gcc/tree-if-conv.c branches/gcc-9-branch/gcc/tree-ssa-loop-im.c branches/gcc-9-branch/gcc/tree-ssa-sccvn.c
Fixed.