This fixes PR53144 - we were assigning a constant value-id to a non-constant value. That breaks bitmap set invariants and thus we end up endlessly inserting things. Oops.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk and branch. Richard. 2012-05-03 Richard Guenther <rguent...@suse.de> PR tree-optimization/53144 * tree-ssa-sccvn.c (vn_reference_lookup_or_insert_constant_for_pieces): Rename to ... (vn_reference_lookup_or_insert_for_pieces): ... this. Properly deal with SSA name values. (vn_reference_lookup_3): Adjust callers. * gcc.dg/torture/pr53144.c: New testcase. Index: gcc/tree-ssa-sccvn.c =================================================================== *** gcc/tree-ssa-sccvn.c (revision 187042) --- gcc/tree-ssa-sccvn.c (working copy) *************** vn_reference_lookup_2 (ao_ref *op ATTRIB *** 1348,1365 **** /* Lookup an existing or insert a new vn_reference entry into the value table for the VUSE, SET, TYPE, OPERANDS reference which ! has the constant value CST. */ static vn_reference_t ! vn_reference_lookup_or_insert_constant_for_pieces (tree vuse, ! alias_set_type set, ! tree type, ! VEC (vn_reference_op_s, ! heap) *operands, ! tree cst) { struct vn_reference_s vr1; vn_reference_t result; vr1.vuse = vuse; vr1.operands = operands; vr1.type = type; --- 1348,1366 ---- /* Lookup an existing or insert a new vn_reference entry into the value table for the VUSE, SET, TYPE, OPERANDS reference which ! has the value VALUE which is either a constant or an SSA name. */ static vn_reference_t ! vn_reference_lookup_or_insert_for_pieces (tree vuse, ! alias_set_type set, ! tree type, ! VEC (vn_reference_op_s, ! heap) *operands, ! tree value) { struct vn_reference_s vr1; vn_reference_t result; + unsigned value_id; vr1.vuse = vuse; vr1.operands = operands; vr1.type = type; *************** vn_reference_lookup_or_insert_constant_f *** 1367,1376 **** vr1.hashcode = vn_reference_compute_hash (&vr1); if (vn_reference_lookup_1 (&vr1, &result)) return result; return vn_reference_insert_pieces (vuse, set, type, VEC_copy (vn_reference_op_s, heap, ! operands), cst, ! get_or_alloc_constant_value_id (cst)); } /* Callback for walk_non_aliased_vuses. Tries to perform a lookup --- 1368,1380 ---- vr1.hashcode = vn_reference_compute_hash (&vr1); if (vn_reference_lookup_1 (&vr1, &result)) return result; + if (TREE_CODE (value) == SSA_NAME) + value_id = VN_INFO (value)->value_id; + else + value_id = get_or_alloc_constant_value_id (value); return vn_reference_insert_pieces (vuse, set, type, VEC_copy (vn_reference_op_s, heap, ! operands), value, value_id); } /* Callback for walk_non_aliased_vuses. Tries to perform a lookup *************** vn_reference_lookup_3 (ao_ref *ref, tree *** 1452,1458 **** && offset2 + size2 >= offset + maxsize) { tree val = build_zero_cst (vr->type); ! return vn_reference_lookup_or_insert_constant_for_pieces (vuse, vr->set, vr->type, vr->operands, val); } } --- 1456,1462 ---- && offset2 + size2 >= offset + maxsize) { tree val = build_zero_cst (vr->type); ! return vn_reference_lookup_or_insert_for_pieces (vuse, vr->set, vr->type, vr->operands, val); } } *************** vn_reference_lookup_3 (ao_ref *ref, tree *** 1473,1479 **** && offset2 + size2 >= offset + maxsize) { tree val = build_zero_cst (vr->type); ! return vn_reference_lookup_or_insert_constant_for_pieces (vuse, vr->set, vr->type, vr->operands, val); } } --- 1477,1483 ---- && offset2 + size2 >= offset + maxsize) { tree val = build_zero_cst (vr->type); ! return vn_reference_lookup_or_insert_for_pieces (vuse, vr->set, vr->type, vr->operands, val); } } *************** vn_reference_lookup_3 (ao_ref *ref, tree *** 1514,1520 **** / BITS_PER_UNIT), ref->size / BITS_PER_UNIT); if (val) ! return vn_reference_lookup_or_insert_constant_for_pieces (vuse, vr->set, vr->type, vr->operands, val); } } --- 1518,1524 ---- / BITS_PER_UNIT), ref->size / BITS_PER_UNIT); if (val) ! return vn_reference_lookup_or_insert_for_pieces (vuse, vr->set, vr->type, vr->operands, val); } } *************** vn_reference_lookup_3 (ao_ref *ref, tree *** 1568,1574 **** } } if (val) ! return vn_reference_lookup_or_insert_constant_for_pieces (vuse, vr->set, vr->type, vr->operands, val); } } --- 1572,1578 ---- } } if (val) ! return vn_reference_lookup_or_insert_for_pieces (vuse, vr->set, vr->type, vr->operands, val); } } Index: gcc/testsuite/gcc.dg/torture/pr53144.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr53144.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr53144.c (revision 0) *************** *** 0 **** --- 1,21 ---- + /* { dg-do compile } */ + + typedef unsigned char __attribute__((vector_size(4))) uvec; + + int main (int argc, char *argv[]) { + int i; + int x = 0; + uvec uc0 = (uvec) {argc, 1, 2, 10}; + unsigned char uc1[4] = {0, 3, 2, 200}; + signed char ucg[4] = {1, 0, 0, 0 }; + signed char ucl[4] = {0, 1, 0, 1 }; + + #define uc0_ ((unsigned char *)&uc0) + + for (i = 0; i < 4; i ++) { + x |= ucg[i] != (uc0_[i] > uc1[i]); + x |= ucl[i] != (uc0_[i] < uc1[i]); + } + return x; + } +