PR optimization/12965
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 7 Dec 2003 13:05:43 +0000 (13:05 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 7 Dec 2003 13:05:43 +0000 (13:05 +0000)
* caller-save.c (save_call_clobbered_regs): Do not save/restore
registers around no-return calls.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@74389 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/caller-save.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/noreturn-1.C [new file with mode: 0644]

index 3b7ed52..d95d628 100644 (file)
@@ -1,3 +1,9 @@
+2003-12-07  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       PR optimization/12965
+       * caller-save.c (save_call_clobbered_regs): Do not save/restore
+       registers around no-return calls.
+
 2003-12-07  Nathanael Nerode  <neroden@gcc.gnu.org>
 
        * configure.in: Make minimum necessary changes for autoconf 2.5x.
index d40c8d9..7467385 100644 (file)
@@ -408,7 +408,7 @@ save_call_clobbered_regs (void)
                  regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS, save_mode);
            }
 
-         if (code == CALL_INSN)
+         if (code == CALL_INSN && ! find_reg_note (insn, REG_NORETURN, NULL))
            {
              int regno;
              HARD_REG_SET hard_regs_to_save;
index b075f0e..558f7a4 100644 (file)
@@ -1,3 +1,7 @@
+2003-12-07  Falk Hueffner  <falk@debian.org>
+
+       * g++.dg/opt/noreturn-1.C: New test.
+
 2003-12-07  Wolfgang Bangerth  <bangerth@dealii.org>
 
        * gcc.dg/overflow-1.c: New test.
diff --git a/gcc/testsuite/g++.dg/opt/noreturn-1.C b/gcc/testsuite/g++.dg/opt/noreturn-1.C
new file mode 100644 (file)
index 0000000..9b2fc0c
--- /dev/null
@@ -0,0 +1,87 @@
+// PR optimization/12965
+// Origin: <qboosh@pld-linux.org>
+// Reduced testcase: Falk Hueffner <falk@debian.org>
+
+// This ICEd on Alpha because the reload pass emitted save/restore
+// insns around a no-return call.
+
+// { dg-do compile }
+// { dg-options "-O2" }
+
+template <typename _Alloc> class allocator;
+template <class _CharT> struct char_traits;
+template <typename _CharT,
+         typename _Traits = char_traits<_CharT>,
+         typename _Alloc = allocator<_CharT> >
+class basic_string;
+typedef basic_string<char> string;
+
+static inline int __exchange_and_add(volatile int * __mem, int __val) {
+    int __result;
+    asm("" : "=&r"(__result));
+    return __result;
+}
+
+template<typename _Tp> struct allocator {
+    allocator() throw() { }
+    allocator(const allocator &) throw() {}
+};
+
+template<typename _CharT, typename _Traits, typename _Alloc>
+struct basic_string {
+    typedef _Alloc allocator_type;
+    struct _Rep {
+       int _M_references;
+       void _M_dispose(const _Alloc & __a) {
+           if (__exchange_and_add(&_M_references, -1) <= 0)
+               _M_destroy(__a);
+       } void _M_destroy(const _Alloc &) throw();
+    };
+    struct _Alloc_hider : _Alloc {
+       _CharT *_M_p;
+    };
+    mutable _Alloc_hider _M_dataplus;
+    _CharT *_M_data() const { return _M_dataplus._M_p; }
+    _Rep *_M_rep() const {
+       return &((reinterpret_cast<_Rep *>(_M_data()))[-1]);
+    }
+    basic_string();
+    basic_string(const _CharT * __s, const _Alloc & __a = _Alloc());
+    ~basic_string() {
+       _M_rep()->_M_dispose(this->get_allocator());
+    }
+    allocator_type get_allocator() const { return _M_dataplus; }
+};
+
+struct Egeneric {
+    void stack(const string & passage, const string & message = "") { }
+};
+
+struct infinint {
+    void detruit() throw(Egeneric);
+    template<class T> void infinint_from(T a) throw(Egeneric);
+    infinint(long a = 0) throw(Egeneric) {
+       try {
+           infinint_from(a);
+       } catch(Egeneric& e) {
+           e.stack("infinint::infinint", "long");
+       }
+    }
+    ~infinint() throw(Egeneric) {
+       try {
+           detruit();
+       } catch(Egeneric& e) { }
+    }
+};
+
+struct inode {
+    string x;
+    infinint a, c;
+    infinint ea_offset;
+    inode();
+};
+
+inode::inode()
+{
+    ea_offset = 0;
+}