I noticed we don't handle secondary effects of restrict in FRE when
looking at another testcase from PR48885:

int
f (int *__restrict__ &__restrict__ p, int *p2)
{
  *p = 1;
  *p2 = 2;
  return *p;
}

with the previously posted patch to improve the handling for p2
we should be able to optimize the return stmt to return 1
in FRE1.  Without the following patch we remove the redundant
load of 'p' but not the load from *p.  This is because the SCCVN
IL didn't record dependence info and did not reconstruct it for
the alias walks or final PRE insert.

The following fixes that - bootstrap and regtest running on
x86_64-unknown-linux-gnu.

Richard.

2015-09-23  Richard Biener  <rguent...@suse.de>

        * tree-ssa-sccvn.h (vn_reference_op_struct): Add clique and base
        members.
        * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Record clique
        and base for MEM_REF and TARGET_MEM_REF.  Handle BIT_FIELD_REF
        offset.
        (ao_ref_init_from_vn_reference): Record clique and base in the
        built base.
        * tree-ssa-pre.c (create_component_ref_by_pieces_1): Likewise

        * g++.dg/tree-ssa/restrict3.C: New testcase.

Index: gcc/tree-ssa-sccvn.h
===================================================================
*** gcc/tree-ssa-sccvn.h        (revision 228037)
--- gcc/tree-ssa-sccvn.h        (working copy)
*************** typedef struct vn_reference_op_struct
*** 83,88 ****
--- 83,91 ----
    ENUM_BITFIELD(tree_code) opcode : 16;
    /* 1 for instrumented calls.  */
    unsigned with_bounds : 1;
+   /* Dependence info, used for [TARGET_]MEM_REF only.  */
+   unsigned short clique;
+   unsigned short base;
    /* Constant offset this op adds or -1 if it is variable.  */
    HOST_WIDE_INT off;
    tree type;
Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c        (revision 228037)
--- gcc/tree-ssa-sccvn.c        (working copy)
*************** copy_reference_ops_from_ref (tree ref, v
*** 773,778 ****
--- 783,790 ----
        temp.op1 = TMR_STEP (ref);
        temp.op2 = TMR_OFFSET (ref);
        temp.off = -1;
+       temp.clique = MR_DEPENDENCE_CLIQUE (ref);
+       temp.base = MR_DEPENDENCE_BASE (ref);
        result->quick_push (temp);
  
        memset (&temp, 0, sizeof (temp));
*************** copy_reference_ops_from_ref (tree ref, v
*** 816,826 ****
--- 828,846 ----
          temp.op0 = TREE_OPERAND (ref, 1);
          if (tree_fits_shwi_p (TREE_OPERAND (ref, 1)))
            temp.off = tree_to_shwi (TREE_OPERAND (ref, 1));
+         temp.clique = MR_DEPENDENCE_CLIQUE (ref);
+         temp.base = MR_DEPENDENCE_BASE (ref);
          break;
        case BIT_FIELD_REF:
          /* Record bits and position.  */
          temp.op0 = TREE_OPERAND (ref, 1);
          temp.op1 = TREE_OPERAND (ref, 2);
+         if (tree_fits_shwi_p (TREE_OPERAND (ref, 2)))
+           {
+             HOST_WIDE_INT off = tree_to_shwi (TREE_OPERAND (ref, 2));
+             if (off % BITS_PER_UNIT == 0)
+               temp.off = off / 8;
+           }
          break;
        case COMPONENT_REF:
          /* The field decl is enough to unambiguously specify the field,
*************** ao_ref_init_from_vn_reference (ao_ref *r
*** 1017,1022 ****
--- 1037,1044 ----
          base_alias_set = get_deref_alias_set (op->op0);
          *op0_p = build2 (MEM_REF, op->type,
                           NULL_TREE, op->op0);
+         MR_DEPENDENCE_CLIQUE (*op0_p) = op->clique;
+         MR_DEPENDENCE_BASE (*op0_p) = op->base;
          op0_p = &TREE_OPERAND (*op0_p, 0);
          break;
  
Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c  (revision 228037)
--- gcc/tree-ssa-pre.c  (working copy)
*************** create_component_ref_by_pieces_1 (basic_
*** 2531,2537 ****
                                                     off));
            baseop = build_fold_addr_expr (base);
          }
!       return fold_build2 (MEM_REF, currop->type, baseop, offset);
        }
  
      case TARGET_MEM_REF:
--- 2531,2540 ----
                                                     off));
            baseop = build_fold_addr_expr (base);
          }
!       genop = build2 (MEM_REF, currop->type, baseop, offset);
!       MR_DEPENDENCE_CLIQUE (genop) = currop->clique;
!       MR_DEPENDENCE_BASE (genop) = currop->base;
!       return genop;
        }
  
      case TARGET_MEM_REF:
*************** create_component_ref_by_pieces_1 (basic_
*** 2554,2561 ****
            if (!genop1)
              return NULL_TREE;
          }
!       return build5 (TARGET_MEM_REF, currop->type,
!                      baseop, currop->op2, genop0, currop->op1, genop1);
        }
  
      case ADDR_EXPR:
--- 2557,2568 ----
            if (!genop1)
              return NULL_TREE;
          }
!       genop = build5 (TARGET_MEM_REF, currop->type,
!                       baseop, currop->op2, genop0, currop->op1, genop1);
! 
!       MR_DEPENDENCE_CLIQUE (genop) = currop->clique;
!       MR_DEPENDENCE_BASE (genop) = currop->base;
!       return genop;
        }
  
      case ADDR_EXPR:
Index: gcc/testsuite/g++.dg/tree-ssa/restrict3.C
===================================================================
*** gcc/testsuite/g++.dg/tree-ssa/restrict3.C   (revision 0)
--- gcc/testsuite/g++.dg/tree-ssa/restrict3.C   (working copy)
***************
*** 0 ****
--- 1,12 ----
+ // { dg-do compile }
+ // { dg-options "-O -fdump-tree-fre1" }
+ 
+ int
+ f (int *__restrict__ &__restrict__ p, int *p2)
+ {
+   *p = 1;
+   *p2 = 2;
+   return *p;
+ }
+ 
+ // { dg-final { scan-tree-dump "return 1;" "fre1" } }

Reply via email to