re PR tree-optimization/49516 (SRA generates memory references into its replacements)
authorMartin Jambor <mjambor@suse.cz>
Fri, 24 Jun 2011 13:27:44 +0000 (15:27 +0200)
committerMartin Jambor <jamborm@gcc.gnu.org>
Fri, 24 Jun 2011 13:27:44 +0000 (15:27 +0200)
2011-06-24  Martin Jambor  <mjambor@suse.cz>

PR tree-optimizations/49516
* tree-sra.c (sra_modify_assign): Choose the safe path for
aggregate copies if we also did scalar replacements.

* testsuite/g++.dg/tree-ssa/pr49516.C: New test.

From-SVN: r175376

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/pr49516.C [new file with mode: 0644]
gcc/tree-sra.c

index 7eb822533330a252cd7a4c687d6e1ca27ff67407..fa88db30b284047a7f68711105d8426a30bfb597 100644 (file)
@@ -1,3 +1,9 @@
+2011-06-24  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimizations/49516
+       * tree-sra.c (sra_modify_assign): Choose the safe path for
+       aggregate copies if we also did scalar replacements.
+
 2011-06-24  Ramana Radhakrishnan  <ramana.radhakrishnan@linaro.org>
 
        PR target/49335
index bab71b3f32ad6d9ff997704b517bc3254e1c49a2..c0f297671dafb7add170ab6b930298af0aa09b87 100644 (file)
@@ -1,3 +1,8 @@
+2011-06-24  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimizations/49516
+       * g++.dg/tree-ssa/pr49516.C: New test.
+
 2011-06-23  Jason Merrill  <jason@redhat.com>
 
        PR c++/35255
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr49516.C b/gcc/testsuite/g++.dg/tree-ssa/pr49516.C
new file mode 100644 (file)
index 0000000..2c6fd04
--- /dev/null
@@ -0,0 +1,86 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern "C" void abort (void);
+
+typedef int int32;
+typedef unsigned int uint32;
+typedef unsigned long long uint64;
+typedef short int16;
+
+class Tp {
+ public:
+  Tp(int, const int segment, const int index) __attribute__((noinline));
+
+  inline bool operator==(const Tp& other) const;
+  inline bool operator!=(const Tp& other) const;
+  int GetType() const { return type_; }
+  int GetSegment() const { return segment_; }
+  int GetIndex() const { return index_; }
+ private:
+  inline static bool IsValidSegment(const int segment);
+  static const int kSegmentBits = 28;
+  static const int kTypeBits = 4;
+  static const int kMaxSegment = (1 << kSegmentBits) - 1;
+
+  union {
+
+    struct {
+      int32 index_;
+      uint32 segment_ : kSegmentBits;
+      uint32 type_ : kTypeBits;
+    };
+    struct {
+      int32 dummy_;
+      uint32 type_and_segment_;
+    };
+    uint64 value_;
+  };
+};
+
+Tp::Tp(int t, const int segment, const int index)
+ : index_(index), segment_(segment), type_(t) {}
+
+inline bool Tp::operator==(const Tp& other) const {
+  return value_ == other.value_;
+}
+inline bool Tp::operator!=(const Tp& other) const {
+  return value_ != other.value_;
+}
+
+class Range {
+ public:
+  inline Range(const Tp& position, const int count) __attribute__((always_inline));
+  inline Tp GetBeginTokenPosition() const;
+  inline Tp GetEndTokenPosition() const;
+ private:
+  Tp position_;
+  int count_;
+  int16 begin_index_;
+  int16 end_index_;
+};
+
+inline Range::Range(const Tp& position,
+                    const int count)
+    : position_(position), count_(count), begin_index_(0), end_index_(0)
+    { }
+
+inline Tp Range::GetBeginTokenPosition() const {
+  return position_;
+}
+inline Tp Range::GetEndTokenPosition() const {
+  return Tp(position_.GetType(), position_.GetSegment(),
+            position_.GetIndex() + count_);
+}
+
+int main ()
+{
+  Range range(Tp(0, 0, 3), 0);
+  if (!(range.GetBeginTokenPosition() == Tp(0, 0, 3)))
+    abort ();
+
+  if (!(range.GetEndTokenPosition() == Tp(0, 0, 3)))
+    abort();
+
+  return 0;
+}
index df19dd1cc51fa81c52f6afbb8ad9100197110744..45ebd93698d37c15420bc1f9ea943818a54840a4 100644 (file)
@@ -2876,7 +2876,8 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
      there to do the copying and then load the scalar replacements of the LHS.
      This is what the first branch does.  */
 
-  if (gimple_has_volatile_ops (*stmt)
+  if (modify_this_stmt
+      || gimple_has_volatile_ops (*stmt)
       || contains_vce_or_bfcref_p (rhs)
       || contains_vce_or_bfcref_p (lhs))
     {