]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[optabs.c] Fix PR 67989: Handle const0_rtx target in expand_atomic_compare_and_swap
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Tue, 27 Oct 2015 14:07:04 +0000 (14:07 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Tue, 27 Oct 2015 14:07:04 +0000 (14:07 +0000)
Backport from mainline
2015-10-26  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

PR middle-end/67989
* optabs.c (expand_atomic_compare_and_swap): Handle case when
ptarget_oval or ptarget_bool are const0_rtx.

* g++.dg/pr67989.C: New test.

From-SVN: r229443

gcc/ChangeLog
gcc/optabs.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/pr67989.C [new file with mode: 0644]

index d64ff91a994b9ddd37fc4bc83ef1d9230a0d59ee..b96dfcd4c1cb8091a40bf74801e99f8fb0922664 100644 (file)
@@ -1,3 +1,12 @@
+2015-10-27  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       Backport from mainline
+       2015-10-26  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       PR middle-end/67989
+       * optabs.c (expand_atomic_compare_and_swap): Handle case when
+       ptarget_oval or ptarget_bool are const0_rtx.
+
 2015-10-27  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        PR target/67929
index aa4defcdd378838d1e4424d4b94d6ebca33bff16..6521485e36f346259167d128f1df406782c674a3 100644 (file)
@@ -7374,9 +7374,9 @@ expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
 
    *PTARGET_BOOL is an optional place to store the boolean success/failure.
    *PTARGET_OVAL is an optional place to store the old value from memory.
-   Both target parameters may be NULL to indicate that we do not care about
-   that return value.  Both target parameters are updated on success to
-   the actual location of the corresponding result.
+   Both target parameters may be NULL or const0_rtx to indicate that we do
+   not care about that return value.  Both target parameters are updated on
+   success to the actual location of the corresponding result.
 
    MEMMODEL is the memory model variant to use.
 
@@ -7401,6 +7401,9 @@ expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
   /* Make sure we always have some place to put the return oldval.
      Further, make sure that place is distinct from the input expected,
      just in case we need that path down below.  */
+  if (ptarget_oval && *ptarget_oval == const0_rtx)
+    ptarget_oval = NULL;
+
   if (ptarget_oval == NULL
       || (target_oval = *ptarget_oval) == NULL
       || reg_overlap_mentioned_p (expected, target_oval))
@@ -7411,6 +7414,9 @@ expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
     {
       enum machine_mode bool_mode = insn_data[icode].operand[0].mode;
 
+      if (ptarget_bool && *ptarget_bool == const0_rtx)
+       ptarget_bool = NULL;
+
       /* Make sure we always have a place for the bool operand.  */
       if (ptarget_bool == NULL
          || (target_bool = *ptarget_bool) == NULL
index 87d2c39b0d7e3a21e87a7f706433983bdf1beeaa..8e2f7312c79c860b7a19154f6ba6b726140bba64 100644 (file)
@@ -3,6 +3,14 @@
        PR fortran/58754
        * gfortran.dg/pr58754.f90: New test
 
+2015-10-27  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       Backport from mainline
+       2015-10-26  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       PR middle-end/67989
+       * g++.dg/pr67989.C: New test.
+
 2015-10-27  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        PR target/67929
diff --git a/gcc/testsuite/g++.dg/pr67989.C b/gcc/testsuite/g++.dg/pr67989.C
new file mode 100644 (file)
index 0000000..90261c4
--- /dev/null
@@ -0,0 +1,75 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c++11 -O2" } */
+/* { dg-additional-options "-marm -march=armv4t" { target arm*-*-* } } */
+
+__extension__ typedef unsigned long long int uint64_t;
+namespace std __attribute__ ((__visibility__ ("default")))
+{
+  typedef enum memory_order
+  {
+    memory_order_seq_cst
+  } memory_order;
+}
+
+namespace std __attribute__ ((__visibility__ ("default")))
+{
+  template < typename _Tp > struct atomic
+  {
+    static constexpr int _S_min_alignment
+      = (sizeof (_Tp) & (sizeof (_Tp) - 1)) || sizeof (_Tp) > 16
+      ? 0 : sizeof (_Tp);
+    static constexpr int _S_alignment
+      = _S_min_alignment > alignof (_Tp) ? _S_min_alignment : alignof (_Tp);
+      alignas (_S_alignment) _Tp _M_i;
+    operator  _Tp () const noexcept
+    {
+      return load ();
+    }
+    _Tp load (memory_order __m = memory_order_seq_cst) const noexcept
+    {
+      _Tp tmp;
+        __atomic_load (&_M_i, &tmp, __m);
+    }
+  };
+}
+
+namespace lldb_private
+{
+  namespace imp
+  {
+  }
+  class Address;
+}
+namespace lldb
+{
+  typedef uint64_t addr_t;
+  class SBSection
+  {
+  };
+  class SBAddress
+  {
+    void SetAddress (lldb::SBSection section, lldb::addr_t offset);
+      lldb_private::Address & ref ();
+  };
+}
+namespace lldb_private
+{
+  class Address
+  {
+  public:
+    const Address & SetOffset (lldb::addr_t offset)
+    {
+      bool changed = m_offset != offset;
+    }
+    std::atomic < lldb::addr_t > m_offset;
+  };
+}
+
+using namespace lldb;
+using namespace lldb_private;
+void
+SBAddress::SetAddress (lldb::SBSection section, lldb::addr_t offset)
+{
+  Address & addr = ref ();
+  addr.SetOffset (offset);
+}