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.)

Reply via email to