From e01a096dd83b73cdc42f33039ecf45baef9f83c3 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 9 Jul 2020 16:03:45 +0200 Subject: [PATCH] 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 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. --- gcc/gimple-fold.c | 11 +++++++++-- gcc/testsuite/gcc.dg/torture/pr96133.c | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr96133.c diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 41b84ba3bb31..dfda6db5e967 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 000000000000..8d051ce29135 --- /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; +} -- 2.47.2