This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Don't mark set of vDRAP from DRAP as frame related (PR debug/43290)


Hi!

Unfortunately I have only testcase for 4.4-RH for this issue, but I believe
it is latent in 4.4/4.5.
As discussed in the PR, the problem is that we have two saves of
%ecx (DRAP) to stack, once using %esp based address, generated by
ix86_expand_prologue and once when the vDRAP pseudo is allocated on the
stack and spilled there (vDRAP = DRAP insn generated by ix86_get_drap_rtx)
using %ebp based address.
Both of these are marked RTX_FRAME_RELATED_P.  Normally the prologue
generated one is scheduled first and the dwarf2out.c unwind info code is
happy about it (cfa_store is %esp based, cfa_temp is %ecx based), as
on the first store Rule 19 was processed.  But, in 4.4-RH scheduler happens
to reorder these two stores, which IMHO can happen with 4.4 or 4.5 too,
and then we hit the ICE that regno used as base of address (%ebp) is neither
cfa_store nor cfa_temp.  I think it is a bug to mark this vDRAP = DRAP
assignment as RTX_FRAME_RELATED_P, as the canonical store is really the one
done in the prologue - from that spot it is restored again.

The following patch fixes it.

Bootstrapped/regtested on x86_64-linux and i686-linux (both trunk and
4.4-RH).  Ok for trunk?

2010-03-08  Jakub Jelinek  <jakub@redhat.com>

	PR debug/43290
	* config/i386/i386.c (ix86_get_drap_rtx): Don't set
	RTX_FRAME_RELATED_P.

	* g++.dg/eh/unwind2.C: New test.

--- gcc/config/i386/i386.c.jj	2010-02-26 17:32:22.000000000 +0100
+++ gcc/config/i386/i386.c	2010-03-08 17:31:23.000000000 +0100
@@ -8323,7 +8323,7 @@ ix86_get_drap_rtx (void)
       unsigned int regno = find_drap_reg ();
       rtx drap_vreg;
       rtx arg_ptr;
-      rtx seq, insn;
+      rtx seq;
 
       arg_ptr = gen_rtx_REG (Pmode, regno);
       crtl->drap_reg = arg_ptr;
@@ -8332,9 +8332,8 @@ ix86_get_drap_rtx (void)
       drap_vreg = copy_to_reg (arg_ptr);
       seq = get_insns ();
       end_sequence ();
-      
-      insn = emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
-      RTX_FRAME_RELATED_P (insn) = 1;
+
+      emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
       return drap_vreg;
     }
   else
--- gcc/testsuite/g++.dg/eh/unwind2.C.jj	2010-03-08 18:05:41.000000000 +0100
+++ gcc/testsuite/g++.dg/eh/unwind2.C	2010-03-08 18:07:59.000000000 +0100
@@ -0,0 +1,94 @@
+// PR debug/43290
+// { dg-do compile }
+// { dg-options "-O2" }
+// { dg-options "-O3 -mavx -fPIC -mtune=core2" { target { { i?86-*-* x86_64-*-* } && { ilp32 && fpic } } } }
+
+namespace std
+{
+  template <class> struct char_traits;
+}
+typedef struct { union { char __wchb[4]; }; } mbstate_t;
+namespace std
+{
+  template <typename _StateT> struct fpos
+  {
+    long long _M_off;
+    _StateT _M_state;
+    fpos (long long):_M_off (), _M_state () { }
+    _StateT state () { return _M_state; }
+  };
+  typedef fpos <mbstate_t> streampos;
+}
+namespace std
+{
+  template <> struct char_traits <char>
+  {
+    typedef streampos pos_type;
+    typedef long long off_type;
+    typedef mbstate_t state_type;
+  };
+}
+struct pthread_mutex_t;
+namespace
+{
+  enum _Ios_Openmode { _S_in = 3, _S_out };
+  enum _Ios_Seekdir { _S_beg };
+  struct ios_base
+  {
+    typedef _Ios_Openmode openmode;
+    static const openmode in = _S_in;
+    static const openmode out = _S_out;
+    typedef _Ios_Seekdir seekdir;
+    static const seekdir beg = _S_beg;
+  };
+  template < typename _CharT, typename > struct basic_streambuf
+  {
+    typedef _CharT char_type;
+    char_type * _M_in_beg;
+    char_type *eback () { return _M_in_beg; }
+    char_type *gptr () {}
+  };
+}
+namespace std
+{
+  typedef struct pthread_mutex_t __c_lock;
+  template <typename> class __basic_file;
+  template <> struct __basic_file <char>
+  {
+    __basic_file (__c_lock * = 0);
+    bool is_open ();
+  };
+  template <typename _CharT, typename _Traits> struct basic_filebuf : public basic_streambuf <_CharT, _Traits>
+  {
+    typedef _CharT char_type;
+    typedef _Traits traits_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+    typedef __basic_file < char >__file_type;
+    typedef typename traits_type::state_type __state_type;
+    __file_type _M_file;
+    char_type *_M_pback_cur_save;
+    bool _M_pback_init;
+    void _M_destroy_pback () throw ()
+    {
+	_M_pback_cur_save += this->gptr () != this->eback ();
+	_M_pback_init = false;
+    }
+    bool is_open () throw () { return _M_file.is_open (); }
+    pos_type seekpos (pos_type, ios_base::openmode = ios_base::in | ios_base::out);
+    pos_type _M_seek (off_type, ios_base::seekdir, __state_type);
+  };
+  template <typename _CharT, typename _Traits>
+  typename basic_filebuf <_CharT, _Traits>::pos_type
+  basic_filebuf <_CharT, _Traits>::seekpos (pos_type __pos, ios_base::openmode)
+  {
+    pos_type __ret = (off_type ());
+    if (this->is_open ())
+      {
+	_M_destroy_pback ();
+	__ret = _M_seek (off_type (), ios_base::beg, __pos.state ());
+      }
+    return __ret;
+  }
+  template class basic_filebuf <char, char_traits <char> >;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]