Compare commits

..

No commits in common. "imports/c8-beta/gcc-8.5.0-18.el8" and "c8" have entirely different histories.

16 changed files with 6021 additions and 9 deletions

View File

@ -0,0 +1,59 @@
2024-04-18 Jakub Jelinek <jakub@redhat.com>
* tree-vect-stmts.c (vectorizable_call): For j == 0 use
vargs.safe_grow (nargs) rather than vargs.create (nargs), for j != 0
remove vargs.truncate (0). Instead of vargs.quick_push store into
vargs[i]. Use vargs[i] instead of gimple_call_arg (new_stmt, i)
if j != 0.
* gcc.c-torture/compile/20240418.c: New test.
--- gcc/tree-vect-stmts.c.jj 2021-04-22 15:48:48.228178359 +0200
+++ gcc/tree-vect-stmts.c 2024-04-18 13:21:46.104061529 +0200
@@ -3242,9 +3242,7 @@ vectorizable_call (gimple *gs, gimple_st
{
/* Build argument list for the vectorized call. */
if (j == 0)
- vargs.create (nargs);
- else
- vargs.truncate (0);
+ vargs.safe_grow (nargs);
if (slp_node)
{
@@ -3252,7 +3250,7 @@ vectorizable_call (gimple *gs, gimple_st
vec<tree> vec_oprnds0;
for (i = 0; i < nargs; i++)
- vargs.quick_push (gimple_call_arg (stmt, i));
+ vargs[i] = gimple_call_arg (stmt, i);
vect_get_slp_defs (vargs, slp_node, &vec_defs);
vec_oprnds0 = vec_defs[0];
@@ -3314,13 +3312,10 @@ vectorizable_call (gimple *gs, gimple_st
vec_oprnd0
= vect_get_vec_def_for_operand (op, stmt);
else
- {
- vec_oprnd0 = gimple_call_arg (new_stmt, i);
- vec_oprnd0
- = vect_get_vec_def_for_stmt_copy (dt[i], vec_oprnd0);
- }
+ vec_oprnd0
+ = vect_get_vec_def_for_stmt_copy (dt[i], vargs[i]);
- vargs.quick_push (vec_oprnd0);
+ vargs[i] = vec_oprnd0;
}
if (gimple_call_internal_p (stmt)
--- gcc/testsuite/gcc.c-torture/compile/20240418.c.jj 2024-04-18 13:24:10.180065661 +0200
+++ gcc/testsuite/gcc.c-torture/compile/20240418.c 2024-04-18 13:19:12.166194018 +0200
@@ -0,0 +1,7 @@
+void
+foo (signed char *p, unsigned long long *q)
+{
+ int i;
+ for (i = 0; i <= 64; i++)
+ *p++ = __builtin_popcountll (*q++);
+}

View File

@ -0,0 +1,30 @@
The change is based on:
commit 190c644c06369766aa2537851ddbf83b1231b65b
Author: Philipp Fent <fent@in.tum.de>
Date: Sun Sep 4 20:47:34 2022 +0200
libstdc++: Fix pretty printer tests of tuple indexes
but it is adapted to GCC8 since it does not have the tuple inheritance change,
which is:
commit 91e6226f880b048275a7ceedef716e159c7cefd9
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Fri Aug 7 17:13:56 2020 +0100
libstdc++: Remove inheritance from elements in std::tuple
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc
index cc91803e247..af335d0d3c7 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc
@@ -29,7 +29,7 @@ main()
// { dg-final { note-test t1 {empty std::tuple} } }
std::tuple<std::string, int, std::tuple<>> t2{ "Johnny", 5, {} };
-// { dg-final { regexp-test t2 {std::tuple containing = {\[1\] = "Johnny", \[2\] = 5, \[3\] = {<std::(__8::)?tuple<>> = empty std::tuple, <No data fields>}}} } }
+// { dg-final { regexp-test t2 {std::tuple containing = {\[0\] = "Johnny", \[1\] = 5, \[2\] = {<std::(__8::)?tuple<>> = empty std::tuple, <No data fields>}}} } }
std::cout << "\n";
return 0; // Mark SPOT

View File

@ -0,0 +1,27 @@
NullablePointer support not available, so drop these tests.
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc.new
index 2f75d12..6fb19c3 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
@@ -145,20 +145,6 @@ main()
std::unique_ptr<data>& rarrptr = arrptr;
// { dg-final { regexp-test rarrptr {std::unique_ptr.datum \[\]. = {get\(\) = 0x.*}} } }
- struct Deleter
- {
- int deleter_member = -1;
- using pointer = __gnu_test::NullablePointer<void>;
- void operator()(pointer) const noexcept { }
- };
- static_assert( !std::is_empty<Deleter>(), "Deleter is not empty" );
- static_assert( std::is_empty<Deleter::pointer>(), "but pointer is empty" );
-
- std::unique_ptr<int, Deleter> empty_ptr;
-// { dg-final { note-test empty_ptr {std::unique_ptr<int> = {get() = {<No data fields>}}} } }
- std::unique_ptr<int, Deleter>& rempty_ptr = empty_ptr;
-// { dg-final { note-test rempty_ptr {std::unique_ptr<int> = {get() = {<No data fields>}}} } }
-
struct Deleter_pr103086
{
int deleter_member = -1;

View File

@ -0,0 +1,44 @@
Revert this commit for libstdc++-prettyprinters (only cxx17, 91997
doesn't exist in this tree) since gcc8 does not default to c++17. The
context has been adapted but the change should be exact:
commit 0498d2d09a2364aae1e6b5e085c8ebb8fc517684
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Mon May 10 16:22:54 2021 +0100
libstdc++: Remove redundant -std=gnu++17 option from remaining tests
Also remove the filesystem tests since it's not supported by RHEL8 gcc.
diff --git b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
index 72c66d3b785..98e21e963fe 100644
--- b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
+++ a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
@@ -1,4 +1,4 @@
-// { dg-options "-g -O0" }
+// { dg-options "-g -O0 -std=gnu++17" }
// { dg-do run { target c++17 } }
// Copyright (C) 2014-2024 Free Software Foundation, Inc.
@@ -18,7 +18,6 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-#include <filesystem>
#include <any>
#include <optional>
#include <variant>
@@ -120,13 +119,6 @@ main()
// { dg-final { regexp-test q {std::shared_ptr.int \[2\]. \(use count 2, weak count 1\) = {get\(\) = 0x.*}} } }
// { dg-final { regexp-test wq {std::weak_ptr.int \[2\]. \(use count 2, weak count 1\) = {get\(\) = 0x.*}} } }
- std::filesystem::path path0;
-// { dg-final { note-test path0 {filesystem::path ""} } }
- std::filesystem::path path1("filename");
-// { dg-final { note-test path1 {filesystem::path "filename"} } }
- std::filesystem::path path2("/dir/.");
-// { dg-final { note-test path2 {filesystem::path "/dir/." = {[root-directory] = "/", [1] = "dir", [2] = "."}} } }
-
std::cout << "\n";
return 0; // Mark SPOT
}

View File

@ -0,0 +1,458 @@
.../testsuite/libstdc++-prettyprinters/compat.cc | 11 +-
.../testsuite/libstdc++-prettyprinters/cxx11.cc | 129 +++++++++++++++------
.../testsuite/libstdc++-prettyprinters/cxx17.cc | 50 +++++---
.../libstdc++-prettyprinters/filesystem-ts.cc | 8 +-
.../libstdc++-prettyprinters/libfundts.cc | 26 +++--
5 files changed, 146 insertions(+), 78 deletions(-)
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc
index 81e0ce7213f..604a6f6415b 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc
@@ -1,8 +1,7 @@
// { dg-options "-g -O0" }
// { dg-do run { target c++11 } }
-// { dg-skip-if "" { *-*-* } { "-D_GLIBCXX_PROFILE" } }
-// Copyright (C) 2014-2019 Free Software Foundation, Inc.
+// Copyright (C) 2014-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -103,13 +102,13 @@ main()
using std::optional;
optional<int> o;
-// { dg-final { note-test o {std::optional<int> [no contained value]} } }
+// { dg-final { note-test o {std::optional [no contained value]} } }
optional<bool> ob{false};
-// { dg-final { note-test ob {std::optional<bool> = {[contained value] = false}} } }
+// { dg-final { note-test ob {std::optional = {[contained value] = false}} } }
optional<int> oi{5};
-// { dg-final { note-test oi {std::optional<int> = {[contained value] = 5}} } }
+// { dg-final { note-test oi {std::optional = {[contained value] = 5}} } }
optional<void*> op{nullptr};
-// { dg-final { note-test op {std::optional<void *> = {[contained value] = 0x0}} } }
+// { dg-final { note-test op {std::optional = {[contained value] = 0x0}} } }
__builtin_puts("");
return 0; // Mark SPOT
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
index 9a90d8d91db..2f75d12703c 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
@@ -1,8 +1,7 @@
// { dg-do run { target c++11 } }
// { dg-options "-g -O0" }
-// { dg-skip-if "" { *-*-* } { "-D_GLIBCXX_PROFILE" } }
-// Copyright (C) 2011-2018 Free Software Foundation, Inc.
+// Copyright (C) 2011-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -25,6 +24,10 @@
#include <string>
#include <memory>
#include <iostream>
+#include <future>
+#include <initializer_list>
+#include <atomic>
+#include "../util/testsuite_allocator.h" // NullablePointer
typedef std::tuple<int, int> ExTuple;
@@ -60,84 +63,74 @@ struct datum
std::unique_ptr<datum> global;
-struct Deleter
-{
- // Deleter is not an empty class:
- int deleter_member = -1;
- // But pointer is an empty class:
- struct pointer
- {
- pointer(const void* = nullptr) { }
- explicit operator bool() const noexcept { return false; }
- friend bool operator==(pointer, pointer) noexcept { return true; }
- friend bool operator!=(pointer, pointer) noexcept { return false; }
- };
- void operator()(pointer) const noexcept { }
+struct custom_cat : std::error_category {
+ const char* name() const noexcept { return "miaow"; }
+ std::string message(int) const { return ""; }
};
int
main()
{
std::forward_list<int> efl;
-// { dg-final { note-test efl "empty std::forward_list" } }
+// { dg-final { regexp-test efl "empty std::(__debug::)?forward_list" } }
std::forward_list<int> &refl = efl;
-// { dg-final { note-test refl "empty std::forward_list" } }
+// { dg-final { regexp-test refl "empty std::(__debug::)?forward_list" } }
std::forward_list<int> fl;
fl.push_front(2);
fl.push_front(1);
-// { dg-final { note-test fl {std::forward_list = {[0] = 1, [1] = 2}} } }
+// { dg-final { regexp-test fl {std::(__debug::)?forward_list = {\[0\] = 1, \[1\] = 2}} } }
std::forward_list<int> &rfl = fl;
-// { dg-final { note-test rfl {std::forward_list = {[0] = 1, [1] = 2}} } }
+// { dg-final { regexp-test rfl {std::(__debug::)?forward_list = {\[0\] = 1, \[1\] = 2}} } }
std::unordered_map<int, std::string> eum;
-// { dg-final { note-test eum "std::unordered_map with 0 elements" } }
+// { dg-final { regexp-test eum "std::(__debug::)?unordered_map with 0 elements" } }
std::unordered_map<int, std::string> &reum = eum;
-// { dg-final { note-test reum "std::unordered_map with 0 elements" } }
+// { dg-final { regexp-test reum "std::(__debug::)?unordered_map with 0 elements" } }
std::unordered_multimap<int, std::string> eumm;
-// { dg-final { note-test eumm "std::unordered_multimap with 0 elements" } }
+// { dg-final { regexp-test eumm "std::(__debug::)?unordered_multimap with 0 elements" } }
std::unordered_multimap<int, std::string> &reumm = eumm;
-// { dg-final { note-test reumm "std::unordered_multimap with 0 elements" } }
+// { dg-final { regexp-test reumm "std::(__debug::)?unordered_multimap with 0 elements" } }
std::unordered_set<int> eus;
-// { dg-final { note-test eus "std::unordered_set with 0 elements" } }
+// { dg-final { regexp-test eus "std::(__debug::)?unordered_set with 0 elements" } }
std::unordered_set<int> &reus = eus;
-// { dg-final { note-test reus "std::unordered_set with 0 elements" } }
+// { dg-final { regexp-test reus "std::(__debug::)?unordered_set with 0 elements" } }
std::unordered_multiset<int> eums;
-// { dg-final { note-test eums "std::unordered_multiset with 0 elements" } }
+// { dg-final { regexp-test eums "std::(__debug::)?unordered_multiset with 0 elements" } }
std::unordered_multiset<int> &reums = eums;
-// { dg-final { note-test reums "std::unordered_multiset with 0 elements" } }
+// { dg-final { regexp-test reums "std::(__debug::)?unordered_multiset with 0 elements" } }
std::unordered_map<int, std::string> uom;
uom[5] = "three";
uom[3] = "seven";
-// { dg-final { note-test uom {std::unordered_map with 2 elements = {[3] = "seven", [5] = "three"}} } }
+// { dg-final { regexp-test uom {std::(__debug::)?unordered_map with 2 elements = {\[3\] = "seven", \[5\] = "three"}} } }
std::unordered_map<int, std::string> &ruom = uom;
-// { dg-final { note-test ruom {std::unordered_map with 2 elements = {[3] = "seven", [5] = "three"}} } }
+// { dg-final { regexp-test ruom {std::(__debug::)?unordered_map with 2 elements = {\[3\] = "seven", \[5\] = "three"}} } }
std::unordered_multimap<int, std::string> uomm;
uomm.insert(std::pair<int, std::string> (5, "three"));
uomm.insert(std::pair<int, std::string> (5, "seven"));
-// { dg-final { note-test uomm {std::unordered_multimap with 2 elements = {[5] = "seven", [5] = "three"}} } }
+// { dg-final { regexp-test uomm {std::(__debug::)?unordered_multimap with 2 elements = {\[5\] = "seven", \[5\] = "three"}} } }
std::unordered_multimap<int, std::string> &ruomm = uomm;
-// { dg-final { note-test ruomm {std::unordered_multimap with 2 elements = {[5] = "seven", [5] = "three"}} } }
+// { dg-final { regexp-test ruomm {std::(__debug::)?unordered_multimap with 2 elements = {\[5\] = "seven", \[5\] = "three"}} } }
std::unordered_set<int> uos;
uos.insert(5);
-// { dg-final { note-test uos {std::unordered_set with 1 element = {[0] = 5}} } }
+// { dg-final { regexp-test uos {std::(__debug::)?unordered_set with 1 element = {\[0\] = 5}} } }
std::unordered_set<int> &ruos = uos;
-// { dg-final { note-test ruos {std::unordered_set with 1 element = {[0] = 5}} } }
+// { dg-final { regexp-test ruos {std::(__debug::)?unordered_set with 1 element = {\[0\] = 5}} } }
std::unordered_multiset<int> uoms;
uoms.insert(5);
-// { dg-final { note-test uoms {std::unordered_multiset with 1 element = {[0] = 5}} } }
+// { dg-final { regexp-test uoms {std::(__debug::)?unordered_multiset with 1 element = {\[0\] = 5}} } }
std::unordered_multiset<int> &ruoms = uoms;
-// { dg-final { note-test ruoms {std::unordered_multiset with 1 element = {[0] = 5}} } }
+// { dg-final { regexp-test ruoms {std::(__debug::)?unordered_multiset with 1 element = {\[0\] = 5}} } }
std::unique_ptr<datum> uptr (new datum);
uptr->s = "hi bob";
@@ -152,15 +145,77 @@ main()
std::unique_ptr<data>& rarrptr = arrptr;
// { dg-final { regexp-test rarrptr {std::unique_ptr.datum \[\]. = {get\(\) = 0x.*}} } }
+ struct Deleter
+ {
+ int deleter_member = -1;
+ using pointer = __gnu_test::NullablePointer<void>;
+ void operator()(pointer) const noexcept { }
+ };
+ static_assert( !std::is_empty<Deleter>(), "Deleter is not empty" );
+ static_assert( std::is_empty<Deleter::pointer>(), "but pointer is empty" );
+
std::unique_ptr<int, Deleter> empty_ptr;
// { dg-final { note-test empty_ptr {std::unique_ptr<int> = {get() = {<No data fields>}}} } }
std::unique_ptr<int, Deleter>& rempty_ptr = empty_ptr;
// { dg-final { note-test rempty_ptr {std::unique_ptr<int> = {get() = {<No data fields>}}} } }
+ struct Deleter_pr103086
+ {
+ int deleter_member = -1;
+ void operator()(int*) const noexcept { }
+ };
+
+ std::unique_ptr<int, Deleter_pr103086> uniq_ptr;
+// { dg-final { note-test uniq_ptr {std::unique_ptr<int> = {get() = 0x0}} } }
+ std::unique_ptr<int, Deleter_pr103086>& runiq_ptr = uniq_ptr;
+// { dg-final { note-test runiq_ptr {std::unique_ptr<int> = {get() = 0x0}} } }
+
ExTuple tpl(6,7);
-// { dg-final { note-test tpl {std::tuple containing = {[1] = 6, [2] = 7}} } }
+// { dg-final { note-test tpl {std::tuple containing = {[0] = 6, [1] = 7}} } }
ExTuple &rtpl = tpl;
-// { dg-final { note-test rtpl {std::tuple containing = {[1] = 6, [2] = 7}} } }
+// { dg-final { note-test rtpl {std::tuple containing = {[0] = 6, [1] = 7}} } }
+
+ std::error_code e0;
+ // { dg-final { note-test e0 {std::error_code = { }} } }
+ std::error_condition ec0;
+ // { dg-final { note-test ec0 {std::error_condition = { }} } }
+ std::error_code einval = std::make_error_code(std::errc::invalid_argument);
+ // { dg-final { note-test einval {std::error_code = {"generic": EINVAL}} } }
+ std::error_condition ecinval = std::make_error_condition(std::errc::invalid_argument);
+ // { dg-final { note-test ecinval {std::error_condition = {"generic": EINVAL}} } }
+
+ custom_cat cat;
+ std::error_code emiaow(42, cat);
+ // { dg-final { note-test emiaow {std::error_code = {custom_cat: 42}} } }
+ std::error_condition ecmiaow(42, cat);
+ // { dg-final { note-test ecmiaow {std::error_condition = {custom_cat: 42}} } }
+
+ std::error_code ecio = std::make_error_code(std::io_errc::stream);
+ // { dg-final { note-test ecio {std::error_code = {"io": stream}} } }
+ std::error_code ecfut0 = std::make_error_code(std::future_errc{});
+ // { dg-final { note-test ecfut0 {std::error_code = {"future": 0}} } }
+
+ std::initializer_list<int> emptyIl = {};
+ // { dg-final { note-test emptyIl {std::initializer_list of length 0} } }
+ std::initializer_list<int> il = {3, 4};
+ // { dg-final { note-test il {std::initializer_list of length 2 = {3, 4}} } }
+
+ std::atomic<int> ai{100};
+ // { dg-final { note-test ai {std::atomic<int> = { 100 }} } }
+ long l{};
+ std::atomic<long*> ap{&l};
+ // { dg-final { regexp-test ap {std::atomic.long \*. = { 0x.* }} } }
+ struct Value { int i, j; };
+ std::atomic<Value> av{{8, 9}};
+ // { dg-final { note-test av {std::atomic<Value> = { {i = 8, j = 9} }} } }
+
+ std::integral_constant<int, 1> one;
+ // { dg-final { note-test one {std::integral_constant<int, 1>} } }
+ std::integral_constant<bool, true> truth;
+ // { dg-final { note-test truth {std::true_type} } }
+ std::integral_constant<bool, 0> lies;
+ // { dg-final { note-test lies {std::false_type} } }
+
placeholder(""); // Mark SPOT
use(efl);
use(fl);
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
index 0c7cb4c9bb6..c8b70622bef 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
@@ -1,8 +1,7 @@
-// { dg-options "-g -O0 -std=gnu++17" }
+// { dg-options "-g -O0" }
// { dg-do run { target c++17 } }
-// { dg-skip-if "" { *-*-* } { "-D_GLIBCXX_PROFILE" } }
-// Copyright (C) 2014-2018 Free Software Foundation, Inc.
+// Copyright (C) 2014-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -19,9 +18,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// Type printers only recognize the old std::string for now.
-#define _GLIBCXX_USE_CXX11_ABI 0
-
+#include <filesystem>
#include <any>
#include <optional>
#include <variant>
@@ -41,6 +38,11 @@ using std::unordered_set;
using std::shared_ptr;
using std::weak_ptr;
+struct X {
+ X(int) { }
+ X(const X&) { } // not trivially-copyable
+};
+
int
main()
{
@@ -48,18 +50,18 @@ main()
// { dg-final { note-test str "\"string\"" } }
optional<int> o;
-// { dg-final { note-test o {std::optional<int> [no contained value]} } }
+// { dg-final { note-test o {std::optional [no contained value]} } }
optional<bool> ob{false};
-// { dg-final { note-test ob {std::optional<bool> = {[contained value] = false}} } }
+// { dg-final { note-test ob {std::optional = {[contained value] = false}} } }
optional<int> oi{5};
-// { dg-final { note-test oi {std::optional<int> = {[contained value] = 5}} } }
+// { dg-final { note-test oi {std::optional = {[contained value] = 5}} } }
optional<void*> op{nullptr};
-// { dg-final { note-test op {std::optional<void *> = {[contained value] = 0x0}} } }
+// { dg-final { note-test op {std::optional = {[contained value] = 0x0}} } }
optional<std::map<int, double>> om;
om = std::map<int, double>{ {1, 2.}, {3, 4.}, {5, 6.} };
-// { dg-final { note-test om {std::optional<std::map<int, double>> containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
+// { dg-final { regexp-test om {std::optional containing std::(__debug::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
optional<std::string> os{ "stringy" };
-// { dg-final { note-test os {std::optional<std::string> = {[contained value] = "stringy"}} } }
+// { dg-final { note-test os {std::optional = {[contained value] = "stringy"}} } }
any a;
// { dg-final { note-test a {std::any [no contained value]} } }
@@ -74,22 +76,25 @@ main()
any as2("stringiest");
// { dg-final { regexp-test as2 {std::any containing const char \* = {\[contained value\] = 0x[[:xdigit:]]+ "stringiest"}} } }
any am = *om;
-// { dg-final { note-test am {std::any containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
+// { dg-final { regexp-test am {std::any containing std::(__debug::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
+ struct local_type { int i = 99; };
+ any al = local_type{};
+// { dg-final { note-test al {std::any containing local_type = {[contained value] = {i = 99}}} } }
struct S { operator int() { throw 42; }};
variant<float, int, string_view> v0;
-// { dg-final { note-test v0 {std::variant<float, int, std::string_view> [index 0] = {0}} } }
+// { dg-final { note-test v0 {std::variant [index 0] = {0}} } }
variant<float, int, string_view> v1{ 0.5f };
-// { dg-final { note-test v1 {std::variant<float, int, std::string_view> [index 0] = {0.5}} } }
- variant<float, int, string_view> v2;
+// { dg-final { note-test v1 {std::variant [index 0] = {0.5}} } }
+ variant<float, X, string_view> v2;
try {
v2.emplace<1>(S());
} catch (int) { }
-// { dg-final { note-test v2 {std::variant<float, int, std::string_view> [no contained value]} } }
+// { dg-final { note-test v2 {std::variant [no contained value]} } }
variant<float, int, string_view> v3{ 3 };
-// { dg-final { note-test v3 {std::variant<float, int, std::string_view> [index 1] = {3}} } }
+// { dg-final { note-test v3 {std::variant [index 1] = {3}} } }
variant<float, int, string_view> v4{ str };
-// { dg-final { note-test v4 {std::variant<float, int, std::string_view> [index 2] = {"string"}} } }
+// { dg-final { note-test v4 {std::variant [index 2] = {"string"}} } }
map<int, string_view> m{ {1, "one"} };
map<int, string_view>::node_type n0;
@@ -115,6 +120,13 @@ main()
// { dg-final { regexp-test q {std::shared_ptr.int \[2\]. \(use count 2, weak count 1\) = {get\(\) = 0x.*}} } }
// { dg-final { regexp-test wq {std::weak_ptr.int \[2\]. \(use count 2, weak count 1\) = {get\(\) = 0x.*}} } }
+ std::filesystem::path path0;
+// { dg-final { note-test path0 {filesystem::path ""} } }
+ std::filesystem::path path1("filename");
+// { dg-final { note-test path1 {filesystem::path "filename"} } }
+ std::filesystem::path path2("/dir/.");
+// { dg-final { note-test path2 {filesystem::path "/dir/." = {[root-directory] = "/", [1] = "dir", [2] = "."}} } }
+
std::cout << "\n";
return 0; // Mark SPOT
}
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc
index 8a1398f6c85..9faeed02852 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc
@@ -2,7 +2,7 @@
// { dg-do run { target c++11 } }
// { dg-require-filesystem-ts "" }
-// Copyright (C) 2020 Free Software Foundation, Inc.
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -26,11 +26,11 @@ int
main()
{
std::experimental::filesystem::path path0;
-// { dg-final { note-test path0 {filesystem::path ""} } }
+// { dg-final { note-test path0 {experimental::filesystem::path ""} } }
std::experimental::filesystem::path path1("filename");
-// { dg-final { note-test path1 {filesystem::path "filename"} } }
+// { dg-final { note-test path1 {experimental::filesystem::path "filename"} } }
std::experimental::filesystem::path path2("/dir/.");
-// { dg-final { note-test path2 {filesystem::path "/dir/." = {[root-directory] = "/", [1] = "dir", [2] = "."}} } }
+// { dg-final { note-test path2 {experimental::filesystem::path "/dir/." = {[root-directory] = "/", [1] = "dir", [2] = "."}} } }
std::cout << "\n";
return 0; // Mark SPOT
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
index ea13ebe71ee..7a6ee8d281e 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
@@ -1,8 +1,7 @@
// { dg-do run { target c++14 } }
// { dg-options "-g -O0" }
-// { dg-skip-if "" { *-*-* } { "-D_GLIBCXX_PROFILE" } }
-// Copyright (C) 2014-2018 Free Software Foundation, Inc.
+// Copyright (C) 2014-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -19,9 +18,6 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// Type printers only recognize the old std::string for now.
-#define _GLIBCXX_USE_CXX11_ABI 0
-
#include <experimental/any>
#include <experimental/optional>
#include <experimental/string_view>
@@ -36,22 +32,28 @@ using std::experimental::string_view;
int
main()
{
+ // Ensure debug info for std::string is issued in the local
+ // translation unit, so that GDB won't pick up any alternate
+ // std::string notion that might be present in libstdc++.so.
+ std::string bah = "hi";
+ (void)bah;
+
string_view str = "string";
// { dg-final { note-test str "\"string\"" } }
optional<int> o;
-// { dg-final { note-test o {std::experimental::optional<int> [no contained value]} } }
+// { dg-final { note-test o {std::experimental::optional [no contained value]} } }
optional<bool> ob{false};
-// { dg-final { note-test ob {std::experimental::optional<bool> = {[contained value] = false}} } }
+// { dg-final { note-test ob {std::experimental::optional = {[contained value] = false}} } }
optional<int> oi{5};
-// { dg-final { note-test oi {std::experimental::optional<int> = {[contained value] = 5}} } }
+// { dg-final { note-test oi {std::experimental::optional = {[contained value] = 5}} } }
optional<void*> op{nullptr};
-// { dg-final { note-test op {std::experimental::optional<void *> = {[contained value] = 0x0}} } }
+// { dg-final { note-test op {std::experimental::optional = {[contained value] = 0x0}} } }
optional<std::map<int, double>> om;
om = std::map<int, double>{ {1, 2.}, {3, 4.}, {5, 6.} };
-// { dg-final { note-test om {std::experimental::optional<std::map<int, double>> containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
+// { dg-final { regexp-test om {std::experimental::optional containing std::(__debug::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
optional<std::string> os{ "stringy" };
-// { dg-final { note-test os {std::experimental::optional<std::string> = {[contained value] = "stringy"}} } }
+// { dg-final { note-test os {std::experimental::optional = {[contained value] = "stringy"}} } }
any a;
// { dg-final { note-test a {std::experimental::any [no contained value]} } }
@@ -66,7 +68,7 @@ main()
any as2("stringiest");
// { dg-final { regexp-test as2 {std::experimental::any containing const char \* = {\[contained value\] = 0x[[:xdigit:]]+ "stringiest"}} } }
any am = *om;
-// { dg-final { note-test am {std::experimental::any containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
+// { dg-final { regexp-test am {std::experimental::any containing std::(__debug::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
std::cout << "\n";
return 0; // Mark SPOT

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
commit ba374dfb937a8ac1c7c4740913331951a924f88b
Author: Jakub Jelinek <jakub@redhat.com>
Date: Wed May 12 10:38:35 2021 +0200
expand: Don't reuse DEBUG_EXPRs with vector type if they have different modes [PR100508]
The inliner doesn't remap DEBUG_EXPR_DECLs, so the same decls can appear
in multiple functions.
Furthermore, expansion reuses corresponding DEBUG_EXPRs too, so they again
can be reused in multiple functions.
Neither of that is a major problem, DEBUG_EXPRs are just magic value holders
and what value they stand for is independent in each function and driven by
what debug stmts or DEBUG_INSNs they are bound to.
Except for DEBUG_EXPR*s with vector types, TYPE_MODE can be either BLKmode
or some vector mode depending on whether current function's enabled ISAs
support that vector mode or not. On the following testcase, we expand it
first in foo function without AVX2 enabled and so the DEBUG_EXPR is
BLKmode, but later the same DEBUG_EXPR_DECL is used in a simd clone with
AVX2 enabled and expansion ICEs because of a mode mismatch.
The following patch fixes that by forcing recreation of a DEBUG_EXPR if
there is a mode mismatch for vector typed DEBUG_EXPR_DECL, DEBUG_EXPRs
will be still reused in between functions otherwise and within the same
function the mode should be always the same.
2021-05-12 Jakub Jelinek <jakub@redhat.com>
PR middle-end/100508
* cfgexpand.c (expand_debug_expr): For DEBUG_EXPR_DECL with vector
type, don't reuse DECL_RTL if it has different mode, instead force
creation of a new DEBUG_EXPR.
* gcc.dg/gomp/pr100508.c: New test.
(cherry picked from commit 19040050aa2c8ee890fc58dda48639fc91bf0af0)
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index b1535e15d28..a7d05202184 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -4358,7 +4358,12 @@ expand_debug_expr (tree exp)
op0 = DECL_RTL_IF_SET (exp);
if (op0)
- return op0;
+ {
+ if (GET_MODE (op0) != mode)
+ gcc_assert (VECTOR_TYPE_P (TREE_TYPE (exp)));
+ else
+ return op0;
+ }
op0 = gen_rtx_DEBUG_EXPR (mode);
DEBUG_EXPR_TREE_DECL (op0) = exp;
diff --git a/gcc/testsuite/gcc.dg/gomp/pr100508.c b/gcc/testsuite/gcc.dg/gomp/pr100508.c
new file mode 100644
index 00000000000..c3fa2fc258e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/pr100508.c
@@ -0,0 +1,14 @@
+/* PR middle-end/100508 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -g -fopenmp-simd" } */
+
+typedef int __attribute__((__vector_size__(32))) V;
+V j;
+
+#pragma omp declare simd
+int
+foo (void)
+{
+ V m = j;
+ return 0;
+}

View File

@ -0,0 +1,61 @@
commit e150cbf591759af10f3d57acbe0eb381aafa00de
Author: Richard Biener <rguenther@suse.de>
Date: Thu Aug 17 13:10:14 2023 +0200
tree-optimization/111039 - abnormals and bit test merging
The following guards the bit test merging code in if-combine against
the appearance of SSA names used in abnormal PHIs.
PR tree-optimization/111039
* tree-ssa-ifcombine.cc (ifcombine_ifandif): Check for
SSA_NAME_OCCURS_IN_ABNORMAL_PHI.
* gcc.dg/pr111039.c: New testcase.
(cherry picked from commit 482551a79a3d3f107f6239679ee74655cfe8707e)
diff --git a/gcc/testsuite/gcc.dg/pr111039.c b/gcc/testsuite/gcc.dg/pr111039.c
new file mode 100644
index 00000000000..bec9983b35f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr111039.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+int _setjmp ();
+void abcd ();
+void abcde ();
+void compiler_corruption_function(int flags)
+{
+ int nowait = flags & 1048576, isexpand = flags & 8388608;
+ abcd();
+ _setjmp(flags);
+ if (nowait && isexpand)
+ flags &= 0;
+ abcde();
+}
--- a/gcc/tree-ssa-ifcombine.c
+++ b/gcc/tree-ssa-ifcombine.c
@@ -407,6 +407,9 @@ ifcombine_ifandif (basic_block inner_con
{
tree t, t2;
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name1))
+ return false;
+
/* Do it. */
gsi = gsi_for_stmt (inner_cond);
t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
@@ -457,6 +460,10 @@ ifcombine_ifandif (basic_block inner_con
gimple_stmt_iterator gsi;
tree t;
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name1)
+ || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name2))
+ return false;
+
/* Find the common name which is bit-tested. */
if (name1 == name2)
;

View File

@ -0,0 +1,68 @@
commit ad42dcf501e41713047cf6c47cbb1dd9f01088a4
Author: Richard Biener <rguenther@suse.de>
Date: Mon Aug 21 09:01:00 2023 +0200
tree-optimization/111070 - fix ICE with recent ifcombine fix
We now got test coverage for non-SSA name bits so the following amends
the SSA_NAME_OCCURS_IN_ABNORMAL_PHI checks.
PR tree-optimization/111070
* tree-ssa-ifcombine.cc (ifcombine_ifandif): Check we have
an SSA name before checking SSA_NAME_OCCURS_IN_ABNORMAL_PHI.
* gcc.dg/pr111070.c: New testcase.
(cherry picked from commit 966b0a96523fb7adbf498ac71df5e033c70dc546)
diff --git a/gcc/testsuite/gcc.dg/pr111070.c b/gcc/testsuite/gcc.dg/pr111070.c
new file mode 100644
index 00000000000..1ebc7adf782
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr111070.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+/* common */
+char c;
+/* arrays must be 8 byte aligned, regardless of size */
+char c_ary[1];
+
+/* data */
+char d = 1;
+char d_ary[1] = {1};
+
+int main ()
+{
+ if (((unsigned long)&c_ary[0] & 7) != 0)
+ return 1;
+ if (((unsigned long)&d_ary[0] & 7) != 0)
+ return 1;
+ return 0;
+}
--- a/gcc/tree-ssa-ifcombine.c
+++ b/gcc/tree-ssa-ifcombine.c
@@ -436,7 +436,8 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
{
tree t, t2;
- if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name1))
+ if (TREE_CODE (name1) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name1))
return false;
/* Do it. */
@@ -495,8 +496,10 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
gimple_stmt_iterator gsi;
tree t;
- if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name1)
- || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name2))
+ if ((TREE_CODE (name1) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name1))
+ || (TREE_CODE (name2) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name2)))
return false;
/* Find the common name which is bit-tested. */

View File

@ -0,0 +1,71 @@
commit 8c21b0d164f33d9d47acc26f4f9b99b53e3b1945
Author: Andreas Krebbel <krebbel@linux.ibm.com>
Date: Tue Nov 6 10:22:05 2018 +0000
S/390: Fix PR87723
gcc/ChangeLog:
2018-11-06 Andreas Krebbel <krebbel@linux.ibm.com>
PR target/87723
* config/s390/s390.md ("*r<noxa>sbg_di_rotl"): Remove mode
attributes for operands 3 and 4.
gcc/testsuite/ChangeLog:
2018-11-06 Andreas Krebbel <krebbel@linux.ibm.com>
PR target/87723
* gcc.target/s390/pr87723.c: New test.
From-SVN: r265832
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 8e7b285e1c3..4ffd438c07c 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -4230,7 +4230,7 @@ (define_insn "*r<noxa>sbg_di_rotl"
(match_operand:DI 4 "nonimmediate_operand" "0")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_Z10"
- "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%b3"
+ "r<noxa>sbg\t%0,%1,%s2,%e2,%b3"
[(set_attr "op_type" "RIE")])
; rosbg, rxsbg
diff --git a/gcc/testsuite/gcc.target/s390/pr87723.c b/gcc/testsuite/gcc.target/s390/pr87723.c
new file mode 100644
index 00000000000..b0e8a5a3118
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/pr87723.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z196 -m64 -mzarch" } */
+
+unsigned long a;
+int b;
+void c(char* i) {
+ for (;;) {
+ char g = 0;
+ for (; g < 24; ++g)
+ b = a << g | a >> 64 - g;
+ {
+ char *d = i;
+ long h = b;
+ char e = 0;
+ for (; e < 8; ++e)
+ d[e] = h;
+ }
+ char *d = i;
+ signed e;
+ unsigned long f = 0;
+ e = 7;
+ for (; e; --e) {
+ f <<= 8;
+ f |= d[e];
+ }
+ for (; e < 8; ++e)
+ d[e] = f;
+ }
+}

View File

@ -0,0 +1,77 @@
commit 6d134ca4b963706f31251f061fc180e517b32546
Author: Martin Sebor <msebor@redhat.com>
Date: Tue Feb 23 14:09:00 2021 -0700
PR c++/99074 - crash in dynamic_cast<>() on null pointer
libstdc++-v3/ChangeLog:
PR c++/99074
* libsupc++/dyncast.cc (__dynamic_cast): Return null when
first argument is null.
gcc/testsuite/ChangeLog:
PR c++/99074
* g++.dg/warn/Wnonnull11.C: New test.
diff --git a/gcc/testsuite/g++.dg/warn/Wnonnull11.C b/gcc/testsuite/g++.dg/warn/Wnonnull11.C
new file mode 100644
index 00000000000..5f1b69d9a41
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wnonnull11.C
@@ -0,0 +1,40 @@
+/* PR c++/99074 - gcc 8 and above is crashing with dynamic_cast<>() on null
+ pointer with optimization level -O1 and above
+ { dg-do run }
+ { dg-options "-O1 -Wall" } */
+
+class Base
+{
+public:
+ virtual ~Base() {}
+ virtual void op() = 0;
+};
+
+class Object: public virtual Base { };
+
+class AbstractBase: public virtual Base
+{
+public:
+ Object* _to_object ()
+ {
+ return dynamic_cast<Object*>(this); // { dg-warning "\\\[-Wnonnull" "" { xfail *-*-* } }
+ }
+};
+
+class MyAbstractClass: public virtual AbstractBase
+{
+public:
+ static MyAbstractClass* _nil () { return 0; }
+};
+
+
+int main ()
+{
+ MyAbstractClass *my_abs_type = MyAbstractClass::_nil ();
+ AbstractBase *abs_base = my_abs_type;
+ Object *obj = abs_base->_to_object ();
+
+ __builtin_printf ("object is: %p\n", obj);
+
+ return 0;
+}
diff --git a/libstdc++-v3/libsupc++/dyncast.cc b/libstdc++-v3/libsupc++/dyncast.cc
index b7d98495ad3..f8f707ee4d4 100644
--- a/libstdc++-v3/libsupc++/dyncast.cc
+++ b/libstdc++-v3/libsupc++/dyncast.cc
@@ -47,6 +47,9 @@ __dynamic_cast (const void *src_ptr, // object started from
const __class_type_info *dst_type, // desired target type
ptrdiff_t src2dst) // how src and dst are related
{
+ if (!src_ptr)
+ /* Handle precondition violations gracefully. */
+ return NULL;
const void *vtable = *static_cast <const void *const *> (src_ptr);
const vtable_prefix *prefix =
adjust_pointer <vtable_prefix> (vtable,

View File

@ -0,0 +1,75 @@
From 6f989c5c6e5f909996a117bb24ecac936e7526c1 Mon Sep 17 00:00:00 2001
From: Marek Polacek <polacek@redhat.com>
Date: Wed, 14 Jun 2023 17:09:15 -0400
Subject: [PATCH] final: fix for TLSLD references [BZ#2213753]
Patch by Jakub Jelinek.
---
gcc/final.c | 17 +++++++++++++++++
gcc/testsuite/g++.dg/tls/bz2213753.C | 26 ++++++++++++++++++++++++++
2 files changed, 43 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/tls/bz2213753.C
diff --git a/gcc/final.c b/gcc/final.c
index 5a65a8ce07c..c783fbb83d7 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -1691,6 +1691,23 @@ get_some_local_dynamic_name ()
}
}
+ /* If all the TLSLD references from current function were DCEd, try harder and pick
+ name of any TLSLD symbol in current TU. */
+ varpool_node *node;
+ if (!this_is_asm_operands)
+ FOR_EACH_VARIABLE (node)
+ if (DECL_THREAD_LOCAL_P (node->decl)
+ && TREE_STATIC (node->decl)
+ && decl_tls_model (node->decl) == TLS_MODEL_LOCAL_DYNAMIC
+ && DECL_RTL_SET_P (node->decl))
+ {
+ rtx rtl = DECL_RTL (node->decl);
+ if (MEM_P (rtl)
+ && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
+ && SYMBOL_REF_TLS_MODEL (XEXP (rtl, 0)) == TLS_MODEL_LOCAL_DYNAMIC)
+ return XSTR (XEXP (rtl, 0), 0);
+ }
+
return 0;
}
diff --git a/gcc/testsuite/g++.dg/tls/bz2213753.C b/gcc/testsuite/g++.dg/tls/bz2213753.C
new file mode 100644
index 00000000000..0c4742d8058
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/bz2213753.C
@@ -0,0 +1,26 @@
+// RHBZ #2213753
+// { dg-do compile { target c++11 } }
+// { dg-require-effective-target fpic }
+// { dg-require-effective-target shared }
+// { dg-require-effective-target tls }
+// { dg-options "-fPIC -O2" }
+// { dg-add-options tls }
+
+struct A { ~A (); };
+static thread_local int *t;
+int a;
+A::~A () { t = &a; }
+long b;
+
+void *
+foo ()
+{
+ void *c;
+ if (t)
+ {
+ c = operator new (b);
+ return c;
+ }
+ void *d = operator new (b);
+ return d;
+}
--
2.40.1

View File

@ -0,0 +1,91 @@
commit ef5f7b89bbc352255595069eb870d6f30f1f9134
Author: Andreas Krebbel <krebbel@linux.ibm.com>
Date: Wed Feb 1 08:59:41 2023 +0100
New reg note REG_CFA_NORESTORE
This patch introduces a new reg note which can be used to tell the CFI
verification in dwarf2cfi that a register is stored without intending
to restore from it.
This is useful when storing e.g. register contents to the stack and
generate CFI for it although the register is not really supposed to be
restored.
gcc/ChangeLog:
* dwarf2cfi.c (dwarf2out_frame_debug_cfa_restore): Add
EMIT_CFI parameter.
(dwarf2out_frame_debug): Add case for REG_CFA_NORESTORE.
* reg-notes.def (REG_CFA_NOTE): New reg note definition.
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -1496,10 +1496,12 @@ dwarf2out_frame_debug_cfa_val_expression (rtx set)
update_row_reg_save (cur_row, dwf_regno (dest), cfi);
}
-/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_RESTORE note. */
+/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_RESTORE
+ note. When called with EMIT_CFI set to false emitting a CFI
+ statement is suppressed. */
static void
-dwarf2out_frame_debug_cfa_restore (rtx reg)
+dwarf2out_frame_debug_cfa_restore (rtx reg, bool emit_cfi)
{
gcc_assert (REG_P (reg));
@@ -1507,7 +1509,8 @@ dwarf2out_frame_debug_cfa_restore (rtx reg)
if (!span)
{
unsigned int regno = dwf_regno (reg);
- add_cfi_restore (regno);
+ if (emit_cfi)
+ add_cfi_restore (regno);
update_row_reg_save (cur_row, regno, NULL);
}
else
@@ -1522,7 +1525,8 @@ dwarf2out_frame_debug_cfa_restore (rtx reg)
reg = XVECEXP (span, 0, par_index);
gcc_assert (REG_P (reg));
unsigned int regno = dwf_regno (reg);
- add_cfi_restore (regno);
+ if (emit_cfi)
+ add_cfi_restore (regno);
update_row_reg_save (cur_row, regno, NULL);
}
}
@@ -2309,6 +2313,7 @@ dwarf2out_frame_debug (rtx_insn *insn)
break;
case REG_CFA_RESTORE:
+ case REG_CFA_NO_RESTORE:
n = XEXP (note, 0);
if (n == NULL)
{
@@ -2317,7 +2322,7 @@ dwarf2out_frame_debug (rtx_insn *insn)
n = XVECEXP (n, 0, 0);
n = XEXP (n, 0);
}
- dwarf2out_frame_debug_cfa_restore (n);
+ dwarf2out_frame_debug_cfa_restore (n, REG_NOTE_KIND (note) == REG_CFA_RESTORE);
handled_one = true;
break;
diff --git a/gcc/reg-notes.def b/gcc/reg-notes.def
index 23de1f13ee9..1f74a605b3e 100644
--- a/gcc/reg-notes.def
+++ b/gcc/reg-notes.def
@@ -157,6 +157,11 @@ REG_CFA_NOTE (CFA_VAL_EXPRESSION)
first pattern is the register to be restored. */
REG_CFA_NOTE (CFA_RESTORE)
+/* Like CFA_RESTORE but without actually emitting CFI. This can be
+ used to tell the verification infrastructure that a register is
+ saved without intending to restore it. */
+REG_CFA_NOTE (CFA_NO_RESTORE)
+
/* Attached to insns that are RTX_FRAME_RELATED_P, marks insn that sets
vDRAP from DRAP. If vDRAP is a register, vdrap_reg is initalized
to the argument, if it is a MEM, it is ignored. */

View File

@ -0,0 +1,106 @@
commit 1467907e405bc18fb6935b5d432cfa5f936e838d
Author: Andreas Krebbel <krebbel@linux.ibm.com>
Date: Thu Mar 30 13:57:54 2023 +0200
IBM zSystems: Make stack_tie to work with hard frame pointer
With this patch a scheduling barrier is created to prevent the insn
setting up the frame-pointer and instructions which save GPRs to the
stack to be swapped. Otherwise broken CFI information would be
generated since the stack save insns would use a base register which
is not currently declared as holding the CFA.
Without -mpreserve-args this did not happen because the store multiple
we used for saving the GPRs would also cover the frame-pointer
register and therefore creates a dependency on the frame-pointer
hardreg. However, with this patch the stack_tie is emitted regardless
of -mpreserve-args since this in general appears to be the safer
approach.
* config/s390/s390.c (save_gprs): Use gen_frame_mem.
(restore_gprs): Likewise.
(s390_emit_stack_tie): Make the stack_tie to be dependent on the
frame pointer if a frame-pointer is used.
(s390_emit_prologue): Emit stack_tie when frame-pointer is needed.
* config/s390/s390.md (stack_tie): Add a register operand and
rename to ...
(stack_tiesi, stack_tiedi): ... this.
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 20424537558..952c708be7a 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -10921,9 +10921,7 @@ save_gprs (rtx base, int offset, int first, int last)
int i;
addr = plus_constant (Pmode, base, offset);
- addr = gen_rtx_MEM (Pmode, addr);
-
- set_mem_alias_set (addr, get_frame_alias_set ());
+ addr = gen_frame_mem (Pmode, addr);
/* Special-case single register. */
if (first == last)
@@ -11035,8 +11033,7 @@ restore_gprs (rtx base, int offset, int first, int last)
rtx addr, insn;
addr = plus_constant (Pmode, base, offset);
- addr = gen_rtx_MEM (Pmode, addr);
- set_mem_alias_set (addr, get_frame_alias_set ());
+ addr = gen_frame_mem (Pmode, addr);
/* Special-case single register. */
if (first == last)
@@ -11105,10 +11102,14 @@ s390_load_got (void)
static void
s390_emit_stack_tie (void)
{
- rtx mem = gen_frame_mem (BLKmode,
- gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
-
- emit_insn (gen_stack_tie (mem));
+ rtx mem = gen_frame_mem (BLKmode, stack_pointer_rtx);
+ rtx stack_reg = (frame_pointer_needed
+ ? hard_frame_pointer_rtx
+ : stack_pointer_rtx);
+ if (TARGET_64BIT)
+ emit_insn (gen_stack_tiedi (mem, stack_reg));
+ else
+ emit_insn (gen_stack_tiesi (mem, stack_reg));
}
/* Copy GPRS into FPR save slots. */
@@ -11701,6 +11702,7 @@ s390_emit_prologue (void)
if (frame_pointer_needed)
{
+ s390_emit_stack_tie ();
insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
}
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 7114609b676..f235df3a25d 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -11366,10 +11366,19 @@
; This is used in s390_emit_prologue in order to prevent insns
; adjusting the stack pointer to be moved over insns writing stack
; slots using a copy of the stack pointer in a different register.
-(define_insn "stack_tie"
+(define_insn "stack_tiesi"
[(set (match_operand:BLK 0 "memory_operand" "+m")
- (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
+ (unspec:BLK [(match_dup 0)
+ (match_operand:SI 1 "register_operand" "r")] UNSPEC_TIE))]
+ "!TARGET_64BIT"
""
+ [(set_attr "length" "0")])
+
+(define_insn "stack_tiedi"
+ [(set (match_operand:BLK 0 "memory_operand" "+m")
+ (unspec:BLK [(match_dup 0)
+ (match_operand:DI 1 "register_operand" "r")] UNSPEC_TIE))]
+ "TARGET_64BIT"
""
[(set_attr "length" "0")])

View File

@ -0,0 +1,545 @@
commit 8091199cdf4d0aa9c28e4526548ddc25d02898ca
Author: Andreas Krebbel <krebbel@linux.ibm.com>
Date: Wed Feb 1 08:59:42 2023 +0100
IBM zSystems: Save argument registers to the stack -mpreserve-args
This adds support for preserving the content of parameter registers to
the stack and emit CFI for it. This useful for applications which want
to implement their own stack unwinding and need access to function
arguments.
With the -mpreserve-args option GPRs and FPRs are save to the stack
slots which are reserved for stdargs in the register save area.
gcc/ChangeLog:
* config/s390/s390.c (s390_restore_gpr_p): New function.
(s390_preserve_gpr_arg_in_range_p): New function.
(s390_preserve_gpr_arg_p): New function.
(s390_preserve_fpr_arg_p): New function.
(s390_register_info_stdarg_fpr): Rename to ...
(s390_register_info_arg_fpr): ... this. Add -mpreserve-args handling.
(s390_register_info_stdarg_gpr): Rename to ...
(s390_register_info_arg_gpr): ... this. Add -mpreserve-args handling.
(s390_register_info): Use the renamed functions above.
(s390_optimize_register_info): Likewise.
(save_fpr): Generate CFI for -mpreserve-args.
(save_gprs): Generate CFI for -mpreserve-args. Drop return value.
(s390_emit_prologue): Adjust to changed calling convention of save_gprs.
(s390_optimize_prologue): Likewise.
* config/s390/s390.opt: New option -mpreserve-args
gcc/testsuite/ChangeLog:
* gcc.target/s390/preserve-args-1.c: New test.
* gcc.target/s390/preserve-args-2.c: New test.
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -411,6 +411,45 @@ struct s390_address
#define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
#define VEC_ARG_NUM_REG 8
+/* Return TRUE if GPR REGNO is supposed to be restored in the function
+ epilogue. */
+static inline bool
+s390_restore_gpr_p (int regno)
+{
+ return (cfun_frame_layout.first_restore_gpr != -1
+ && regno >= cfun_frame_layout.first_restore_gpr
+ && regno <= cfun_frame_layout.last_restore_gpr);
+}
+
+/* Return TRUE if any of the registers in range [FIRST, LAST] is saved
+ because of -mpreserve-args. */
+static inline bool
+s390_preserve_gpr_arg_in_range_p (int first, int last)
+{
+ int num_arg_regs = MIN (crtl->args.info.gprs + cfun->va_list_gpr_size,
+ GP_ARG_NUM_REG);
+ return (num_arg_regs
+ && s390_preserve_args_p
+ && first <= GPR2_REGNUM + num_arg_regs - 1
+ && last >= GPR2_REGNUM);
+}
+
+static inline bool
+s390_preserve_gpr_arg_p (int regno)
+{
+ return s390_preserve_gpr_arg_in_range_p (regno, regno);
+}
+
+static inline bool
+s390_preserve_fpr_arg_p (int regno)
+{
+ int num_arg_regs = MIN (crtl->args.info.fprs + cfun->va_list_fpr_size,
+ FP_ARG_NUM_REG);
+ return (s390_preserve_args_p
+ && regno <= FPR0_REGNUM + num_arg_regs - 1
+ && regno >= FPR0_REGNUM);
+}
+
/* A couple of shortcuts. */
#define CONST_OK_FOR_J(x) \
CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
@@ -9893,61 +9932,89 @@ s390_register_info_gprtofpr ()
}
/* Set the bits in fpr_bitmap for FPRs which need to be saved due to
- stdarg.
+ stdarg or -mpreserve-args.
This is a helper routine for s390_register_info. */
-
static void
-s390_register_info_stdarg_fpr ()
+s390_register_info_arg_fpr ()
{
int i;
- int min_fpr;
- int max_fpr;
+ int min_stdarg_fpr = INT_MAX, max_stdarg_fpr = -1;
+ int min_preserve_fpr = INT_MAX, max_preserve_fpr = -1;
+ int min_fpr, max_fpr;
/* Save the FP argument regs for stdarg. f0, f2 for 31 bit and
f0-f4 for 64 bit. */
- if (!cfun->stdarg
- || !TARGET_HARD_FLOAT
- || !cfun->va_list_fpr_size
- || crtl->args.info.fprs >= FP_ARG_NUM_REG)
- return;
+ if (cfun->stdarg
+ && TARGET_HARD_FLOAT
+ && cfun->va_list_fpr_size
+ && crtl->args.info.fprs < FP_ARG_NUM_REG)
+ {
+ min_stdarg_fpr = crtl->args.info.fprs;
+ max_stdarg_fpr = min_stdarg_fpr + cfun->va_list_fpr_size - 1;
+ if (max_stdarg_fpr >= FP_ARG_NUM_REG)
+ max_stdarg_fpr = FP_ARG_NUM_REG - 1;
+
+ /* FPR argument regs start at f0. */
+ min_stdarg_fpr += FPR0_REGNUM;
+ max_stdarg_fpr += FPR0_REGNUM;
+ }
- min_fpr = crtl->args.info.fprs;
- max_fpr = min_fpr + cfun->va_list_fpr_size - 1;
- if (max_fpr >= FP_ARG_NUM_REG)
- max_fpr = FP_ARG_NUM_REG - 1;
+ if (s390_preserve_args_p && crtl->args.info.fprs)
+ {
+ min_preserve_fpr = FPR0_REGNUM;
+ max_preserve_fpr = MIN (FPR0_REGNUM + FP_ARG_NUM_REG - 1,
+ FPR0_REGNUM + crtl->args.info.fprs - 1);
+ }
- /* FPR argument regs start at f0. */
- min_fpr += FPR0_REGNUM;
- max_fpr += FPR0_REGNUM;
+ min_fpr = MIN (min_stdarg_fpr, min_preserve_fpr);
+ max_fpr = MAX (max_stdarg_fpr, max_preserve_fpr);
+
+ if (max_fpr == -1)
+ return;
for (i = min_fpr; i <= max_fpr; i++)
cfun_set_fpr_save (i);
}
+
/* Reserve the GPR save slots for GPRs which need to be saved due to
- stdarg.
+ stdarg or -mpreserve-args.
This is a helper routine for s390_register_info. */
static void
-s390_register_info_stdarg_gpr ()
+s390_register_info_arg_gpr ()
{
int i;
- int min_gpr;
- int max_gpr;
+ int min_stdarg_gpr = INT_MAX, max_stdarg_gpr = -1;
+ int min_preserve_gpr = INT_MAX, max_preserve_gpr = -1;
+ int min_gpr, max_gpr;
- if (!cfun->stdarg
- || !cfun->va_list_gpr_size
- || crtl->args.info.gprs >= GP_ARG_NUM_REG)
- return;
+ if (cfun->stdarg
+ && cfun->va_list_gpr_size
+ && crtl->args.info.gprs < GP_ARG_NUM_REG)
+ {
+ min_stdarg_gpr = crtl->args.info.gprs;
+ max_stdarg_gpr = min_stdarg_gpr + cfun->va_list_gpr_size - 1;
+ if (max_stdarg_gpr >= GP_ARG_NUM_REG)
+ max_stdarg_gpr = GP_ARG_NUM_REG - 1;
+
+ /* GPR argument regs start at r2. */
+ min_stdarg_gpr += GPR2_REGNUM;
+ max_stdarg_gpr += GPR2_REGNUM;
+ }
+
+ if (s390_preserve_args_p && crtl->args.info.gprs)
+ {
+ min_preserve_gpr = GPR2_REGNUM;
+ max_preserve_gpr = MIN (GPR6_REGNUM,
+ GPR2_REGNUM + crtl->args.info.gprs - 1);
+ }
- min_gpr = crtl->args.info.gprs;
- max_gpr = min_gpr + cfun->va_list_gpr_size - 1;
- if (max_gpr >= GP_ARG_NUM_REG)
- max_gpr = GP_ARG_NUM_REG - 1;
+ min_gpr = MIN (min_stdarg_gpr, min_preserve_gpr);
+ max_gpr = MAX (max_stdarg_gpr, max_preserve_gpr);
- /* GPR argument regs start at r2. */
- min_gpr += GPR2_REGNUM;
- max_gpr += GPR2_REGNUM;
+ if (max_gpr == -1)
+ return;
/* If r6 was supposed to be saved into an FPR and now needs to go to
the stack for vararg we have to adjust the restore range to make
@@ -10079,14 +10146,14 @@ s390_register_info ()
if (clobbered_regs[i])
cfun_gpr_save_slot (i) = SAVE_SLOT_STACK;
- s390_register_info_stdarg_fpr ();
+ s390_register_info_arg_fpr ();
s390_register_info_gprtofpr ();
s390_register_info_set_ranges ();
- /* stdarg functions might need to save GPRs 2 to 6. This might
- override the GPR->FPR save decision made by
- s390_register_info_gprtofpr for r6 since vararg regs must go to
- the stack. */
- s390_register_info_stdarg_gpr ();
+
+ /* Forcing argument registers to be saved on the stack might
+ override the GPR->FPR save decision for r6 so this must come
+ last. */
+ s390_register_info_arg_gpr ();
}
/* Return true if REGNO is a global register, but not one
@@ -10141,7 +10208,7 @@ s390_optimize_register_info ()
cfun_gpr_save_slot (i) = SAVE_SLOT_NONE;
s390_register_info_set_ranges ();
- s390_register_info_stdarg_gpr ();
+ s390_register_info_arg_gpr ();
}
/* Fill cfun->machine with info about frame of current function. */
@@ -10864,14 +10931,28 @@ static rtx
save_fpr (rtx base, int offset, int regnum)
{
rtx addr;
+ rtx insn;
+
addr = gen_rtx_MEM (DFmode, plus_constant (Pmode, base, offset));
- if (regnum >= 16 && regnum <= (16 + FP_ARG_NUM_REG))
+ if (regnum >= FPR0_REGNUM && regnum <= (FPR0_REGNUM + FP_ARG_NUM_REG))
set_mem_alias_set (addr, get_varargs_alias_set ());
else
set_mem_alias_set (addr, get_frame_alias_set ());
- return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
+ insn = emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
+
+ if (!call_used_regs[regnum] || s390_preserve_fpr_arg_p (regnum))
+ RTX_FRAME_RELATED_P (insn) = 1;
+
+ if (s390_preserve_fpr_arg_p (regnum) && !cfun_fpr_save_p (regnum))
+ {
+ rtx reg = gen_rtx_REG (DFmode, regnum);
+ add_reg_note (insn, REG_CFA_NO_RESTORE, reg);
+ add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (addr, reg));
+ }
+
+ return insn;
}
/* Emit insn to restore fpr REGNUM from offset OFFSET relative
@@ -10891,10 +10972,11 @@ restore_fpr (rtx base, int offset, int regnum)
the register save area located at offset OFFSET
relative to register BASE. */
-static rtx
-save_gprs (rtx base, int offset, int first, int last)
+static void
+save_gprs (rtx base, int offset, int first, int last, rtx_insn *before = NULL)
{
rtx addr, insn, note;
+ rtx_insn *out_insn;
int i;
addr = plus_constant (Pmode, base, offset);
@@ -10910,7 +10992,15 @@ save_gprs (rtx base, int offset, int first, int last)
if (!global_not_special_regno_p (first))
RTX_FRAME_RELATED_P (insn) = 1;
- return insn;
+
+ if (s390_preserve_gpr_arg_p (first) && !s390_restore_gpr_p (first))
+ {
+ rtx reg = gen_rtx_REG (Pmode, first);
+ add_reg_note (insn, REG_CFA_NO_RESTORE, reg);
+ add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (addr, reg));
+ }
+
+ goto emit;
}
@@ -10939,7 +11029,12 @@ save_gprs (rtx base, int offset, int first, int last)
set, even if it does not. Therefore we emit a new pattern
without those registers as REG_FRAME_RELATED_EXPR note. */
- if (first >= 6 && !global_not_special_regno_p (first))
+ /* In these cases all of the sets are marked as frame related:
+ 1. call-save GPR saved and restored
+ 2. argument GPR saved because of -mpreserve-args */
+ if ((first >= GPR6_REGNUM && !global_not_special_regno_p (first))
+ || s390_preserve_gpr_arg_in_range_p (first, last))
+
{
rtx pat = PATTERN (insn);
@@ -10950,6 +11045,24 @@ save_gprs (rtx base, int offset, int first, int last)
RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
RTX_FRAME_RELATED_P (insn) = 1;
+
+ /* For the -mpreserve-args register saves no restore operations
+ will be emitted. CFI checking would complain about this. We
+ manually generate the REG_CFA notes here to be able to mark
+ those operations with REG_CFA_NO_RESTORE. */
+ if (s390_preserve_gpr_arg_in_range_p (first, last))
+ {
+ for (int regno = first; regno <= last; regno++)
+ {
+ rtx reg = gen_rtx_REG (Pmode, regno);
+ rtx reg_addr = plus_constant (Pmode, base,
+ offset + (regno - first) * UNITS_PER_LONG);
+ if (!s390_restore_gpr_p (regno))
+ add_reg_note (insn, REG_CFA_NO_RESTORE, reg);
+ add_reg_note (insn, REG_CFA_OFFSET,
+ gen_rtx_SET (gen_frame_mem (Pmode, reg_addr), reg));
+ }
+ }
}
else if (last >= 6)
{
@@ -10960,7 +11073,7 @@ save_gprs (rtx base, int offset, int first, int last)
break;
if (start > last)
- return insn;
+ goto emit;
addr = plus_constant (Pmode, base,
offset + (start - first) * UNITS_PER_LONG);
@@ -10978,7 +11091,7 @@ save_gprs (rtx base, int offset, int first, int last)
add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
RTX_FRAME_RELATED_P (insn) = 1;
- return insn;
+ goto emit;
}
note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
@@ -10997,9 +11110,15 @@ save_gprs (rtx base, int offset, int first, int last)
RTX_FRAME_RELATED_P (insn) = 1;
}
- return insn;
+ emit:
+ if (before != NULL_RTX)
+ out_insn = emit_insn_before (insn, before);
+ else
+ out_insn = emit_insn (insn);
+ INSN_ADDRESSES_NEW (out_insn, -1);
}
+
/* Generate insn to restore registers FIRST to LAST from
the register save area located at offset OFFSET
relative to register BASE. */
@@ -11423,12 +11542,12 @@ s390_emit_prologue (void)
/* Save call saved gprs. */
if (cfun_frame_layout.first_save_gpr != -1)
{
- insn = save_gprs (stack_pointer_rtx,
- cfun_frame_layout.gprs_offset +
- UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr
- - cfun_frame_layout.first_save_gpr_slot),
- cfun_frame_layout.first_save_gpr,
- cfun_frame_layout.last_save_gpr);
+ save_gprs (stack_pointer_rtx,
+ cfun_frame_layout.gprs_offset +
+ UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr
+ - cfun_frame_layout.first_save_gpr_slot),
+ cfun_frame_layout.first_save_gpr,
+ cfun_frame_layout.last_save_gpr);
/* This is not 100% correct. If we have more than one register saved,
then LAST_PROBE_OFFSET can move even closer to sp. */
@@ -11436,8 +11555,6 @@ s390_emit_prologue (void)
= (cfun_frame_layout.gprs_offset +
UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr
- cfun_frame_layout.first_save_gpr_slot));
-
- emit_insn (insn);
}
/* Dummy insn to mark literal pool slot. */
@@ -11467,15 +11584,10 @@ s390_emit_prologue (void)
{
if (cfun_fpr_save_p (i))
{
- insn = save_fpr (stack_pointer_rtx, offset, i);
+ save_fpr (stack_pointer_rtx, offset, i);
if (offset < last_probe_offset)
last_probe_offset = offset;
offset += 8;
-
- /* If f4 and f6 are call clobbered they are saved due to
- stdargs and therefore are not frame related. */
- if (!call_really_used_regs[i])
- RTX_FRAME_RELATED_P (insn) = 1;
}
else if (!TARGET_PACKED_STACK || call_really_used_regs[i])
offset += 8;
@@ -11491,11 +11603,10 @@ s390_emit_prologue (void)
for (i = FPR15_REGNUM; i >= FPR8_REGNUM && offset >= 0; i--)
if (cfun_fpr_save_p (i))
{
- insn = save_fpr (stack_pointer_rtx, offset, i);
+ save_fpr (stack_pointer_rtx, offset, i);
if (offset < last_probe_offset)
last_probe_offset = offset;
- RTX_FRAME_RELATED_P (insn) = 1;
offset -= 8;
}
if (offset >= cfun_frame_layout.f8_offset)
@@ -11663,7 +11774,6 @@ s390_emit_prologue (void)
insn = save_fpr (temp_reg, offset, i);
offset += 8;
- RTX_FRAME_RELATED_P (insn) = 1;
add_reg_note (insn, REG_FRAME_RELATED_EXPR,
gen_rtx_SET (gen_rtx_MEM (DFmode, addr),
gen_rtx_REG (DFmode, i)));
@@ -14158,15 +14268,11 @@ s390_optimize_prologue (void)
continue;
if (cfun_frame_layout.first_save_gpr != -1)
- {
- rtx s_pat = save_gprs (base,
- off + (cfun_frame_layout.first_save_gpr
- - first) * UNITS_PER_LONG,
- cfun_frame_layout.first_save_gpr,
- cfun_frame_layout.last_save_gpr);
- new_insn = emit_insn_before (s_pat, insn);
- INSN_ADDRESSES_NEW (new_insn, -1);
- }
+ save_gprs (base,
+ off + (cfun_frame_layout.first_save_gpr
+ - first) * UNITS_PER_LONG,
+ cfun_frame_layout.first_save_gpr,
+ cfun_frame_layout.last_save_gpr, insn);
remove_insn (insn);
continue;
diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt
index 57d1b95bd65..344aa551f44 100644
--- a/gcc/config/s390/s390.opt
+++ b/gcc/config/s390/s390.opt
@@ -321,3 +321,7 @@ and the default behavior is to emit separate multiplication and addition
-mindirect-branch* or -mfunction-return* options. The sections
consist of an array of 32 bit elements. Each entry holds the offset
from the entry to the patched location.
+
+mpreserve-args
+Target Var(s390_preserve_args_p) Init(0)
+Store all argument registers on the stack.
diff --git a/gcc/testsuite/gcc.target/s390/preserve-args-1.c b/gcc/testsuite/gcc.target/s390/preserve-args-1.c
new file mode 100644
index 00000000000..24dcf547432
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/preserve-args-1.c
@@ -0,0 +1,17 @@
+/* Functional tests for the -mpreserve-args cmdline option. */
+
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z900 -mpreserve-args" } */
+
+
+int
+foo (int a, int b, int c, double d, double e)
+{
+ return a + c + (int)d + (int)e;
+}
+
+/* { dg-final { scan-assembler "stmg\t%r2,%r4,\[0-9\]*\\(%r15\\)" { target lp64 } } } */
+/* { dg-final { scan-assembler "stm\t%r2,%r4,\[0-9\]*\\(%r15\\)" { target { ! lp64 } } } } */
+
+/* { dg-final { scan-assembler "std\t%f0,\[0-9\]*\\(%r15\\)" } } */
+/* { dg-final { scan-assembler "std\t%f2,\[0-9\]*\\(%r15\\)" } } */
diff --git a/gcc/testsuite/gcc.target/s390/preserve-args-2.c b/gcc/testsuite/gcc.target/s390/preserve-args-2.c
new file mode 100644
index 00000000000..006aad9c371
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/preserve-args-2.c
@@ -0,0 +1,19 @@
+/* This test requires special handling of a GPR which is saved because
+ of -mpreserve-args but not restored. dwarf2cfi used to ICE for
+ this in maybe_record_trace_start. The solution was to introduce a
+ REG_CFA_NORESTORE reg note. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=z900 -mpreserve-args" } */
+
+void *foo (void *);
+void bar ();
+int x;
+void *
+baz (void *y)
+{
+ if (__builtin_expect (x, 0))
+ return foo (y);
+ bar ();
+ return foo (y);
+}
diff --git a/gcc/testsuite/gcc.target/s390/preserve-args-3.c b/gcc/testsuite/gcc.target/s390/preserve-args-3.c
new file mode 100644
index 00000000000..f4b135ab8e6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/preserve-args-3.c
@@ -0,0 +1,19 @@
+/* Functional tests for the -mpreserve-args cmdline option. */
+
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z900 -mpreserve-args" } */
+
+#include <stdarg.h>
+int
+foo (int a, int, int c, double d, ...)
+{
+ va_list argp;
+ va_start(argp, d);
+ return a + c + va_arg(argp, int) + va_arg(argp, int) + (int)va_arg(argp, double);
+}
+
+/* { dg-final { scan-assembler "stmg\t%r2,%r15,\[0-9\]*\\(%r15\\)" { target lp64 } } } */
+/* { dg-final { scan-assembler "stm\t%r2,%r15,\[0-9\]*\\(%r15\\)" { target { ! lp64 } } } } */
+
+/* { dg-final { scan-assembler "std\t%f0,\[0-9\]*\\(%r15\\)" } } */
+/* { dg-final { scan-assembler "std\t%f2,\[0-9\]*\\(%r15\\)" } } */

View File

@ -1,10 +1,11 @@
%global source_date_epoch_from_changelog 1
%global DATE 20210514 %global DATE 20210514
%global gitrev a3253c88425835d5b339d6998a1110a66ccd8b44 %global gitrev a3253c88425835d5b339d6998a1110a66ccd8b44
%global gcc_version 8.5.0 %global gcc_version 8.5.0
%global gcc_major 8 %global gcc_major 8
# Note, gcc_release must be integer, if you want to add suffixes to # Note, gcc_release must be integer, if you want to add suffixes to
# %%{release}, append them after %%{gcc_release} on Release: line. # %%{release}, append them after %%{gcc_release} on Release: line.
%global gcc_release 18 %global gcc_release 26
%global nvptx_tools_gitrev c28050f60193b3b95a18866a96f03334e874e78f %global nvptx_tools_gitrev c28050f60193b3b95a18866a96f03334e874e78f
%global nvptx_newlib_gitrev aadc8eb0ec43b7cd0dd2dfb484bae63c8b05ef24 %global nvptx_newlib_gitrev aadc8eb0ec43b7cd0dd2dfb484bae63c8b05ef24
%global _unpackaged_files_terminate_build 0 %global _unpackaged_files_terminate_build 0
@ -298,10 +299,27 @@ Patch37: gcc8-pr105502.patch
Patch38: gcc8-pr99536.patch Patch38: gcc8-pr99536.patch
Patch39: gcc8-libstdc++-make_shared.patch Patch39: gcc8-libstdc++-make_shared.patch
Patch40: gcc8-rh2137448.patch Patch40: gcc8-rh2137448.patch
Patch41: gcc8-s390x-regarg-1.patch
Patch42: gcc8-s390x-regarg-2.patch
Patch43: gcc8-s390x-regarg-3.patch
Patch44: gcc8-rh2213753.patch
Patch45: gcc8-pr99074.patch
Patch46: gcc8-pr87723.patch
Patch47: gcc8-pr111039.patch
Patch48: gcc8-pr111070.patch
Patch49: gcc8-RHEL-32886.patch
Patch50: gcc8-pr100508.patch
Patch1000: nvptx-tools-no-ptxas.patch # Any patches changing libstdc++-v3/python and its tests should go after this.
Patch1001: nvptx-tools-build.patch Patch1000: gcc8-libstdc++-prettyprinter-update-14.patch
Patch1002: nvptx-tools-glibc.patch Patch1001: gcc8-libstdc++-prettyprinter-update-14-tests.patch
Patch1002: gcc8-libstdc++-prettyprinter-update-14-tests-48362.patch
Patch1003: gcc8-libstdc++-prettyprinter-update-14-tests-cxx11.patch
Patch1004: gcc8-libstdc++-prettyprinter-update-14-tests-cxx17.patch
Patch2000: nvptx-tools-no-ptxas.patch
Patch2001: nvptx-tools-build.patch
Patch2002: nvptx-tools-glibc.patch
# On ARM EABI systems, we do want -gnueabi to be part of the # On ARM EABI systems, we do want -gnueabi to be part of the
@ -913,11 +931,27 @@ so that there cannot be any synchronization problems.
%patch38 -p1 -b .pr99536~ %patch38 -p1 -b .pr99536~
%patch39 -p1 -b .make_shared~ %patch39 -p1 -b .make_shared~
%patch40 -p1 -b .rh2137448~ %patch40 -p1 -b .rh2137448~
%patch41 -p1 -b .s390x-regarg-1~
%patch42 -p1 -b .s390x-regarg-2~
%patch43 -p1 -b .s390x-regarg-3~
%patch44 -p1 -b .rh2213753~
%patch45 -p1 -b .pr99074~
%patch46 -p1 -b .pr87723~
%patch47 -p1 -b .pr111039~
%patch48 -p1 -b .pr111070~
%patch49 -p0 -b .32886~
%patch50 -p1 -b .pr100508~
%patch1000 -p1 -b .libstdc++-prettyprinter-update-14~
%patch1001 -p1 -b .libstdc++-prettyprinter-update-14-tests~
%patch1002 -p1 -b .libstdc++-prettyprinter-update-14-tests-48362~
%patch1003 -p1 -b .libstdc++-prettyprinter-update-14-tests-cxx11~
%patch1004 -p1 -b .libstdc++-prettyprinter-update-14-tests-cxx17~
cd nvptx-tools-%{nvptx_tools_gitrev} cd nvptx-tools-%{nvptx_tools_gitrev}
%patch1000 -p1 -b .nvptx-tools-no-ptxas~ %patch2000 -p1 -b .nvptx-tools-no-ptxas~
%patch1001 -p1 -b .nvptx-tools-build~ %patch2001 -p1 -b .nvptx-tools-build~
%patch1002 -p1 -b .nvptx-tools-glibc~ %patch2002 -p1 -b .nvptx-tools-glibc~
cd .. cd ..
echo 'Red Hat %{version}-%{gcc_release}' > gcc/DEV-PHASE echo 'Red Hat %{version}-%{gcc_release}' > gcc/DEV-PHASE
@ -1538,9 +1572,9 @@ mv -f %{buildroot}%{_prefix}/%{_lib}/libstdc++*gdb.py* \
%{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/ %{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/
pushd ../libstdc++-v3/python pushd ../libstdc++-v3/python
for i in `find . -name \*.py`; do for i in `find . -name \*.py`; do
touch -r $i %{buildroot}%{_prefix}/share/gcc-%{gcc_major}/python/$i touch -d @$SOURCE_DATE_EPOCH %{buildroot}%{_prefix}/share/gcc-%{gcc_major}/python/$i
done done
touch -r hook.in %{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/libstdc++*gdb.py touch -d @$SOURCE_DATE_EPOCH %{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/libstdc++*gdb.py
popd popd
for f in `find %{buildroot}%{_prefix}/share/gcc-%{gcc_major}/python/ \ for f in `find %{buildroot}%{_prefix}/share/gcc-%{gcc_major}/python/ \
%{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/ -name \*.py`; do %{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/ -name \*.py`; do
@ -3320,6 +3354,32 @@ fi
%{ANNOBIN_GCC_PLUGIN_DIR}/gcc-annobin.so.0.0.0 %{ANNOBIN_GCC_PLUGIN_DIR}/gcc-annobin.so.0.0.0
%changelog %changelog
* Fri Mar 21 2025 Siddhesh Poyarekar <siddhesh@redhat.com> 8.5.0-26
- Pin modification time for python files to SOURCE_DATE_EPOCH (RHEL-50290).
* Fri Feb 28 2025 Siddhesh Poyarekar <siddhesh@redhat.com> 8.5.0-25
- Sync libstdc++ pretty printers to latest GTS (RHEL-50290).
* Mon Feb 24 2025 Marek Polacek <polacek@redhat.com> 8.5.0-24
- don't reuse DEBUG_EXPRs with vector type (PR middle-end/100508, RHEL-79501)
* Fri Feb 7 2025 Marek Polacek <polacek@redhat.com> 8.5.0-23
- rebuild for CVE-2020-11023 (RHEL-78274)
* Thu Apr 18 2024 Marek Polacek <polacek@redhat.com> 8.5.0-22
- fix ICE in the vectorizer (RHEL-32886)
* Wed Oct 4 2023 Marek Polacek <polacek@redhat.com> 8.5.0-21
- guard the bit test merging code in if-combine (RHEL-11483)
* Wed Jun 14 2023 Marek Polacek <polacek@redhat.com> 8.5.0-20
- fix for TLSLD references (#2213753)
- fix crash in dynamic_cast<>() on null pointer (PR c++/99074, #2211506)
- adjust a pattern in s390.md (PR target/87723, #2214847)
* Tue Apr 4 2023 Marek Polacek <polacek@redhat.com> 8.5.0-19
- s390x: add support for register arguments preserving (#2168205)
* Tue Dec 6 2022 Marek Polacek <polacek@redhat.com> 8.5.0-18 * Tue Dec 6 2022 Marek Polacek <polacek@redhat.com> 8.5.0-18
- fix strlen range with a flexible member array (#2137448) - fix strlen range with a flexible member array (#2137448)