SRA uses bogus alias sets for access replacements if a alias-punning
MEM_REF is based on a decl.  The following patch fixes this.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

The testcase is a GCC 6 regression but the issue is older.

Richard.

2016-04-05  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/70526
        * tree-sra.c (build_ref_for_offset): Use prev_base to
        extract the alias pointer type.

        * g++.dg/torture/pr70526.C: New testcase.

Index: gcc/tree-sra.c
===================================================================
*** gcc/tree-sra.c      (revision 234736)
--- gcc/tree-sra.c      (working copy)
*************** build_ref_for_offset (location_t loc, tr
*** 1673,1679 ****
      }
    else
      {
!       off = build_int_cst (reference_alias_ptr_type (base),
                           base_offset + offset / BITS_PER_UNIT);
        base = build_fold_addr_expr (unshare_expr (base));
      }
--- 1673,1679 ----
      }
    else
      {
!       off = build_int_cst (reference_alias_ptr_type (prev_base),
                           base_offset + offset / BITS_PER_UNIT);
        base = build_fold_addr_expr (unshare_expr (base));
      }
Index: gcc/testsuite/g++.dg/torture/pr70526.C
===================================================================
*** gcc/testsuite/g++.dg/torture/pr70526.C      (revision 0)
--- gcc/testsuite/g++.dg/torture/pr70526.C      (working copy)
***************
*** 0 ****
--- 1,35 ----
+ // { dg-do run }
+ 
+ typedef unsigned uint32_t;
+ 
+ template<typename T>
+ struct AlignedStorage2
+ {
+   char mBytes[sizeof(T)];
+ 
+   const T* addr() const { return reinterpret_cast<const T*>(mBytes); }
+   T* addr() { return reinterpret_cast<T*>(mBytes); }
+ };
+ 
+ struct Register {
+     uint32_t reg_;
+ };
+ 
+ class TypedOrValueRegister
+ {
+   AlignedStorage2<Register> typed;
+   __attribute__((noinline)) Register& dataTyped() { return *typed.addr(); }
+ public:
+   TypedOrValueRegister(Register reg)
+     {
+       dataTyped() = reg;
+     }
+   Register typedReg() const { return *typed.addr(); }
+ };
+ 
+ int main() {
+     Register reg = { 10u };
+     if (TypedOrValueRegister(reg).typedReg().reg_ != 10)
+       __builtin_abort();
+     return 0;
+ }

Reply via email to