https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102183
Bug ID: 102183 Summary: sccvn compare predicated result issue in vn_nary_op_insert_into Product: gcc Version: tree-ssa Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: dizhao at os dot amperecomputing.com Target Milestone: --- In tree-ssa-sccvn.c, function vn_nary_op_insert_into, the following code might lead to inserting entra vn_pval entry: vn_pval *nval = vno->u.values; vn_pval **next = &vno->u.values; bool found = false; for (vn_pval *val = (*slot)->u.values; val; val = val->next) { if (expressions_equal_p (val->result, vno->u.values->result)) // Here { ... /* Append value. */ *next = (vn_pval *) obstack_alloc (&vn_tables_obstack, sizeof (vn_pval) + val->n * sizeof (int)); (*next)->next = NULL; (*next)->result = val->result; ... next = &(*next)->next; if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Appending predicate to value.\n"); continue; } /* Copy other predicated values. */ *next = (vn_pval *) obstack_alloc (&vn_tables_obstack, sizeof (vn_pval) + (val->n-1) * sizeof (int)); memcpy (*next, val, sizeof (vn_pval) + (val->n-1) * sizeof (int)); (*next)->next = NULL; next = &(*next)->next; } I think 'expressions_equal_p' here should check if current val->result equals to the result in original vno? But vno->u.values will be changed if the "Copy other predicated values" branch is taken first (by setting *next). Here's an example test code: #include <stdio.h> unsigned int c = 1; void f (unsigned int a, unsigned int b) { if (a >= b) c = 2; else c = 9; for (unsigned i = 0; i < 100; i++) { if (a < b) { printf ("AAAA"); if (a >= b) printf ("XXXXX"); } else printf ("BBBB"); } } In detailed fre1 dump file, the new predicate value is not appended to old entry: Processing block 0: BB2 Value numbering stmt = if (a_5(D) >= b_6(D)) Recording on edge 2->3 a_5(D) ge_expr b_6(D) == true Recording on edge 2->4 a_5(D) ge_expr b_6(D) == false Recording on edge 2->3 a_5(D) lt_expr b_6(D) == false //===>old one Recording on edge 2->4 a_5(D) lt_expr b_6(D) == true //===>old one ... Processing block 5: BB6 Value numbering stmt = if (a_5(D) < b_6(D)) Recording on edge 6->7 a_5(D) lt_expr b_6(D) == true //===>new one Recording on edge 6->9 a_5(D) lt_expr b_6(D) == false Appending predicate to value. After changed to 'if (expressions_equal_p (val->result, nval->result))', the new predicate value can be appended to old one: Processing block 0: BB2 Value numbering stmt = if (a_5(D) >= b_6(D)) Recording on edge 2->3 a_5(D) ge_expr b_6(D) == true Recording on edge 2->4 a_5(D) ge_expr b_6(D) == false Recording on edge 2->3 a_5(D) lt_expr b_6(D) == false //===>old one Recording on edge 2->4 a_5(D) lt_expr b_6(D) == true //===>old one ... Processing block 5: BB6 Value numbering stmt = if (a_5(D) < b_6(D)) Recording on edge 6->7 a_5(D) lt_expr b_6(D) == true //===>new one Appending predicate to value. Recording on edge 6->9 a_5(D) lt_expr b_6(D) == false Appending predicate to value. (I think inserting extra vn_pval entries might cause losing optimize opportunities.)