This is a regression present on the mainline in the form of a segfault on the
attached C testcase with -O2 -fnon-call-exceptions -ftracer. The GIMPLE SSA
store merging pass blows up when it is rewriting the stores because it didn't
realize that they don't belong to the same EH region.
Fixed by refusing to merge them. Tested on x86-64/Linux, pre-approved by
Jakub and applied on the mainline.
2019-04-23 Eric Botcazou <ebotca...@adacore.com>
PR tree-optimization/94717
* gimple-ssa-store-merging.c (try_coalesce_bswap): Return false if one
of the stores doesn't have the same landing pad number as the first.
(coalesce_immediate_stores): Do not try to coalesce the store using
bswap if it doesn't have the same landing pad number as the first.
2019-04-23 Eric Botcazou <ebotca...@adacore.com>
* g++.dg/opt/store-merging-4.C: New test.
--
Eric Botcazou
diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c
index a6687cd9c98..25753517cc6 100644
--- a/gcc/gimple-ssa-store-merging.c
+++ b/gcc/gimple-ssa-store-merging.c
@@ -2435,6 +2435,7 @@ imm_store_chain_info::try_coalesce_bswap (merged_store_group *merged_store,
for (unsigned int i = first + 1; i < len; ++i)
{
if (m_store_info[i]->bitpos != m_store_info[first]->bitpos + width
+ || m_store_info[i]->lp_nr != merged_store->lp_nr
|| m_store_info[i]->ins_stmt == NULL)
return false;
width += m_store_info[i]->bitsize;
@@ -2682,6 +2683,7 @@ imm_store_chain_info::coalesce_immediate_stores ()
if (info->bitpos == merged_store->start + merged_store->width
&& merged_store->stores.length () == 1
&& merged_store->stores[0]->ins_stmt != NULL
+ && info->lp_nr == merged_store->lp_nr
&& info->ins_stmt != NULL)
{
unsigned int try_size;
// PR tree-optimization/94717
// Reported by Zdenek Sojka <zso...@seznam.cz>
// { dg-do compile }
// { dg-options "-O2 -fnon-call-exceptions -ftracer" }
int abs (int);
static inline void
bar (int d)
{
d && abs (d);
}
struct S
{
int a;
int b;
int c;
S (unsigned a, unsigned b) : a (a), b (b) { }
};
void
foo (S *x)
{
bar (x->c);
new S (x->a, x->b);
bar (0);
}