tree-optimization/101868 - avoid PRE of trapping mems across calls
This backports a fix for the omission of a check of trapping mems when hoisting them across calls that might not return. This was originally done as part of a fix to handle const functions that throw properly. 2021-08-17 Richard Biener <rguenther@suse.de> PR tree-optimization/101373 PR tree-optimization/101868 * tree-ssa-pre.c (prune_clobbered_mems): Also prune trapping references when the BB may not return. * gcc.dg/lto/pr101868_0.c: New testcase. * gcc.dg/lto/pr101868_1.c: Likewise. * gcc.dg/lto/pr101868_2.c: Likewise. * gcc.dg/lto/pr101868_3.c: Likewise.
This commit is contained in:
parent
a0a0499b8b
commit
ee875b63b2
33
gcc/testsuite/gcc.dg/lto/pr101868_0.c
Normal file
33
gcc/testsuite/gcc.dg/lto/pr101868_0.c
Normal file
@ -0,0 +1,33 @@
|
||||
/* { dg-lto-do run } */
|
||||
/* { dg-lto-options { "-O2 -fno-strict-aliasing -flto" } } */
|
||||
|
||||
typedef unsigned long VALUE;
|
||||
|
||||
__attribute__ ((cold))
|
||||
void rb_check_type(VALUE, int);
|
||||
|
||||
static VALUE
|
||||
repro(VALUE dummy, VALUE hash)
|
||||
{
|
||||
if (hash == 0) {
|
||||
rb_check_type(hash, 1);
|
||||
}
|
||||
else if (*(long *)hash) {
|
||||
rb_check_type(hash, 1);
|
||||
}
|
||||
|
||||
|
||||
return *(long *)hash;
|
||||
}
|
||||
|
||||
static VALUE (*that)(VALUE dummy, VALUE hash) = repro;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
argc--;
|
||||
that(0, argc);
|
||||
|
||||
rb_check_type(argc, argc);
|
||||
|
||||
}
|
23
gcc/testsuite/gcc.dg/lto/pr101868_1.c
Normal file
23
gcc/testsuite/gcc.dg/lto/pr101868_1.c
Normal file
@ -0,0 +1,23 @@
|
||||
typedef unsigned long VALUE;
|
||||
|
||||
|
||||
__attribute__ ((noreturn)) void rexc_raise(VALUE mesg);
|
||||
|
||||
VALUE rb_donothing(VALUE klass);
|
||||
|
||||
static void
|
||||
funexpected_type(VALUE x, int xt, int t)
|
||||
{
|
||||
rexc_raise(rb_donothing(0));
|
||||
}
|
||||
|
||||
__attribute__ ((cold))
|
||||
void
|
||||
rb_check_type(VALUE x, int t)
|
||||
{
|
||||
int xt;
|
||||
|
||||
if (x == 0) {
|
||||
funexpected_type(x, xt, t);
|
||||
}
|
||||
}
|
11
gcc/testsuite/gcc.dg/lto/pr101868_2.c
Normal file
11
gcc/testsuite/gcc.dg/lto/pr101868_2.c
Normal file
@ -0,0 +1,11 @@
|
||||
typedef unsigned long VALUE;
|
||||
|
||||
static void thing(void) {}
|
||||
static void (*ptr)(void) = &thing;
|
||||
|
||||
VALUE
|
||||
rb_donothing(VALUE klass)
|
||||
{
|
||||
ptr();
|
||||
return 0;
|
||||
}
|
8
gcc/testsuite/gcc.dg/lto/pr101868_3.c
Normal file
8
gcc/testsuite/gcc.dg/lto/pr101868_3.c
Normal file
@ -0,0 +1,8 @@
|
||||
typedef unsigned long VALUE;
|
||||
|
||||
__attribute__((noreturn))
|
||||
void
|
||||
rexc_raise(VALUE mesg)
|
||||
{
|
||||
__builtin_exit(0);
|
||||
}
|
@ -2070,6 +2070,13 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block)
|
||||
&& value_dies_in_block_x (expr, block))))
|
||||
to_remove = i;
|
||||
}
|
||||
/* If the REFERENCE may trap make sure the block does not contain
|
||||
a possible exit point.
|
||||
??? This is overly conservative if we translate AVAIL_OUT
|
||||
as the available expression might be after the exit point. */
|
||||
if (BB_MAY_NOTRETURN (block)
|
||||
&& vn_reference_may_trap (ref))
|
||||
to_remove = i;
|
||||
}
|
||||
else if (expr->kind == NARY)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user