aboutsummaryrefslogtreecommitdiff
path: root/gcc/gcse.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2021-07-08 09:52:49 +0200
committerRichard Biener <rguenther@suse.de>2021-07-12 16:47:45 +0200
commitfedcf3c476aff7533741a1c61071200f0a38cf83 (patch)
tree129cb5cb4d560a1bbfe468aa3684f0a9c2f4991a /gcc/gcse.c
parentfe610051a803131822bd02a8842a67b573b8e46a (diff)
downloadgcc-fedcf3c476aff7533741a1c61071200f0a38cf83.zip
gcc-fedcf3c476aff7533741a1c61071200f0a38cf83.tar.gz
gcc-fedcf3c476aff7533741a1c61071200f0a38cf83.tar.bz2
tree-optimization/101373 - avoid PRE across externally throwing call
PRE already tries to avoid hoisting possibly trapping expressions across calls that might not return normally but fails to consider const calls that throw externally. The following fixes that and also plugs the hole of trapping references not pruned in case they are not catched by the actuall call clobbering it. At -Os we hit the same issue in RTL PRE and postreload-gcse has even more incomplete checks so the patch adjusts both of those as well. 2021-07-08 Richard Biener <rguenther@suse.de> PR tree-optimization/101373 * tree-ssa-pre.c (prune_clobbered_mems): Also prune trapping references when the BB may not return. (compute_avail): Pass in the function we're working on and replace cfun references with it. Externally throwing const calls also possibly terminate the function. (pass_pre::execute): Pass down the function we're working on. * gcse.c (compute_hash_table_work): Externally throwing const/pure calls also need record_last_mem_set_info. * postreload-gcse.c (record_opr_changes): Looping or externally throwing const/pure calls also need record_last_mem_set_info. * g++.dg/torture/pr101373.C: New testcase, XFAILed. * gnat.dg/opt95.adb: Likewise.
Diffstat (limited to 'gcc/gcse.c')
-rw-r--r--gcc/gcse.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/gcc/gcse.c b/gcc/gcse.c
index ecf7e51..ccd3366 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -1537,7 +1537,8 @@ compute_hash_table_work (struct gcse_hash_table_d *table)
record_last_reg_set_info (insn, regno);
if (! RTL_CONST_OR_PURE_CALL_P (insn)
- || RTL_LOOPING_CONST_OR_PURE_CALL_P (insn))
+ || RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)
+ || can_throw_external (insn))
record_last_mem_set_info (insn);
}