aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2020-07-09 16:03:45 +0200
committerRichard Biener <rguenther@suse.de>2020-07-10 10:52:47 +0200
commit6e41c27bf549d957eb399d39d7d0c213f8733351 (patch)
treebfd509af5c0156df1f28bc7c79a85132ac7e4802
parentba9c87d3255f168db811dd1fa69e5011d4e8194f (diff)
downloadgcc-6e41c27bf549d957eb399d39d7d0c213f8733351.zip
gcc-6e41c27bf549d957eb399d39d7d0c213f8733351.tar.gz
gcc-6e41c27bf549d957eb399d39d7d0c213f8733351.tar.bz2
fix constant folding from array CTORs
This fixes the case where we try to fold a read from an array initalizer and happen to cross the boundary of multiple CTORs which isn't really supported. For the interesting cases like the testcase we actually handle the folding by encoding the whole initializer. 2020-07-10 Richard Biener <rguenther@suse.de> PR tree-optimization/96133 * gimple-fold.c (fold_array_ctor_reference): Do not recurse to folding a CTOR that does not fully cover the asked for object. * gcc.dg/torture/pr96133.c: New testcase.
-rw-r--r--gcc/gimple-fold.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr96133.c16
2 files changed, 25 insertions, 2 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 41b84ba..dfda6db 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -6875,10 +6875,17 @@ fold_array_ctor_reference (tree type, tree ctor,
SIZE to the size of the accessed element. */
inner_offset = 0;
type = TREE_TYPE (val);
- size = elt_size.to_uhwi () * BITS_PER_UNIT;
+ size = elt_sz * BITS_PER_UNIT;
}
+ else if (size && access_index < CONSTRUCTOR_NELTS (ctor) - 1
+ && TREE_CODE (val) == CONSTRUCTOR
+ && (elt_sz * BITS_PER_UNIT - inner_offset) < size)
+ /* If this isn't the last element in the CTOR and a CTOR itself
+ and it does not cover the whole object we are requesting give up
+ since we're not set up for combining from multiple CTORs. */
+ return NULL_TREE;
- *suboff += (access_index * elt_size * BITS_PER_UNIT).to_uhwi ();
+ *suboff += access_index.to_uhwi () * elt_sz * BITS_PER_UNIT;
return fold_ctor_reference (type, val, inner_offset, size, from_decl,
suboff);
}
diff --git a/gcc/testsuite/gcc.dg/torture/pr96133.c b/gcc/testsuite/gcc.dg/torture/pr96133.c
new file mode 100644
index 0000000..8d051ce
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr96133.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+
+typedef int T;
+static const T a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
+typedef T v2 __attribute__((vector_size(2*sizeof(T))));
+
+int
+main()
+{
+ const T *p = &a[0][2];
+ v2 x = *(const v2 *)p;
+ T z = x[1];
+ if (z != 4)
+ __builtin_abort ();
+ return 0;
+}