aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2020-02-19 11:08:40 +0100
committerMartin Jambor <mjambor@suse.cz>2020-02-19 11:08:40 +0100
commit665c5bad168ab63629b29ed2ce08ed042c088dc2 (patch)
treeecb4038880ce3d049ab4985c927936c0b7af96ee /gcc
parent8d1a1cb1b816381bf60cb1211c93b8eba1fe1472 (diff)
downloadgcc-665c5bad168ab63629b29ed2ce08ed042c088dc2.zip
gcc-665c5bad168ab63629b29ed2ce08ed042c088dc2.tar.gz
gcc-665c5bad168ab63629b29ed2ce08ed042c088dc2.tar.bz2
sra: Avoid totally scalarizing overallping field_decls (PR 93667)
[[no_unique_address]] C++ attribute can cause two fields of a RECORD_TYPE overlap, which currently confuses the totally scalarizing code into creating invalid access tree. For GCC 10, I'd like to simply disable total scalarization of types where this happens. For GCC 11 I'll write down a TODO item to enable total scalarization of cases like this where the problematic fields are basically empty - despite having a non-zero size - i.e. when they are just RECORD_TYPEs without any data fields. 2020-02-19 Martin Jambor <mjambor@suse.cz> gcc/ PR tree-optimization/93667 * tree-sra.c (scalarizable_type_p): Return false if record fields do not follow wach other. gcc/testsuite/ PR tree-optimization/93667 * g++.dg/tree-ssa/pr93667.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr93667.C11
-rw-r--r--gcc/tree-sra.c14
4 files changed, 36 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 77c2a9a..6b53f9a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2020-02-19 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/93667
+ * tree-sra.c (scalarizable_type_p): Return false if record fields
+ do not follow wach other.
+
2020-01-21 Kito Cheng <kito.cheng@sifive.com>
* config/riscv/riscv.c (riscv_output_move) Using fmv.x.w/fmv.w.x
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9b4fe11..8033fa0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-02-19 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/93667
+ * g++.dg/tree-ssa/pr93667.C: New test.
+
2020-02-19 Hongtao Liu <hongtao.liu@intel.com>
* g++.dg/other/i386-2.C: add -mavx512vbmi2
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr93667.C b/gcc/testsuite/g++.dg/tree-ssa/pr93667.C
new file mode 100644
index 0000000..d875f53
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr93667.C
@@ -0,0 +1,11 @@
+// { dg-do compile }
+// { dg-options "-O2 -std=c++2a" } */
+
+struct a {};
+struct b { [[no_unique_address]] a aq; };
+struct c {
+ int d;
+ [[no_unique_address]] b e;
+};
+c f() {return {};}
+void g() { f(); }
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 0cfac0a..4c7d651 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -958,6 +958,9 @@ scalarizable_type_p (tree type, bool const_decl)
if (type_contains_placeholder_p (type))
return false;
+ bool have_predecessor_field = false;
+ HOST_WIDE_INT prev_pos = 0;
+
switch (TREE_CODE (type))
{
case RECORD_TYPE:
@@ -966,6 +969,17 @@ scalarizable_type_p (tree type, bool const_decl)
{
tree ft = TREE_TYPE (fld);
+ if (zerop (DECL_SIZE (fld)))
+ continue;
+
+ HOST_WIDE_INT pos = int_bit_position (fld);
+ if (have_predecessor_field
+ && pos <= prev_pos)
+ return false;
+
+ have_predecessor_field = true;
+ prev_pos = pos;
+
if (DECL_BIT_FIELD (fld))
return false;