summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2019-09-19 12:49:45 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2019-09-19 12:49:45 +0000
commitd9e736e7194b524c3624172b896d5ace9cb459aa (patch)
tree7ddc9268cae4641b035d9e5e82d478a5ba2d7b2d
parentf24f4c15884bf1ee65a10e2f959842eec4198876 (diff)
re PR tree-optimization/91812 (GCC ignores volatile modifier)
2019-09-19 Richard Biener <rguenther@suse.de> PR tree-optimization/91812 * tree-ssa-phiprop.c (propagate_with_phi): Do not replace volatile loads. * gcc.dg/torture/pr91812.c: New testcase. From-SVN: r275960
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr91812.c26
-rw-r--r--gcc/tree-ssa-phiprop.c11
4 files changed, 46 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c51b6f65720..1810fe92af0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2019-09-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91812
+ * tree-ssa-phiprop.c (propagate_with_phi): Do not replace
+ volatile loads.
+
2019-09-19 Richard Sandiford <richard.sandiford@arm.com>
* defaults.h (TARGET_UNIT): New macro.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 07adb119850..c5854bd363d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-09-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91812
+ * gcc.dg/torture/pr91812.c: New testcase.
+
2019-09-19 Tom Tromey <tromey@adacore.com>
* gnat.dg/bias1.adb: New testcase.
diff --git a/gcc/testsuite/gcc.dg/torture/pr91812.c b/gcc/testsuite/gcc.dg/torture/pr91812.c
new file mode 100644
index 00000000000..ebc67a01e33
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr91812.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */
+/* { dg-options "-fdump-tree-optimized-blocks" } */
+
+unsigned register1;
+unsigned register2;
+
+void busy_wait_for_register (int x)
+{
+ volatile unsigned* ptr;
+ switch(x) {
+ case 0x1111:
+ ptr = &register1;
+ break;
+
+ case 0x2222:
+ ptr = &register2;
+ break;
+
+ default:
+ return;
+ }
+ while (*ptr) {}
+}
+
+/* { dg-final { scan-tree-dump "loop depth 1" "optimized" } } */
diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c
index d710582a915..e90ae6a89cb 100644
--- a/gcc/tree-ssa-phiprop.c
+++ b/gcc/tree-ssa-phiprop.c
@@ -338,8 +338,15 @@ propagate_with_phi (basic_block bb, gphi *phi, struct phiprop_d *phivn,
&& (!type
|| types_compatible_p
(TREE_TYPE (gimple_assign_lhs (use_stmt)), type))
- /* We cannot replace a load that may throw or is volatile. */
- && !stmt_can_throw_internal (cfun, use_stmt)))
+ /* We cannot replace a load that may throw or is volatile.
+ For volatiles the transform can change the number of
+ executions if the load is inside a loop but the address
+ computations outside (PR91812). We could relax this
+ if we guard against that appropriately. For loads that can
+ throw we could relax things if the moved loads all are
+ known to not throw. */
+ && !stmt_can_throw_internal (cfun, use_stmt)
+ && !gimple_has_volatile_ops (use_stmt)))
continue;
/* Check if we can move the loads. The def stmt of the virtual use