Fix PR91812
diff mbox series

Message ID nycvar.YFH.7.76.1909191416030.5566@zhemvz.fhfr.qr
State New
Headers show
Series
  • Fix PR91812
Related show

Commit Message

Richard Biener Sept. 19, 2019, 12:16 p.m. UTC
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

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.

Patch
diff mbox series

Index: gcc/tree-ssa-phiprop.c
===================================================================
--- gcc/tree-ssa-phiprop.c	(revision 275698)
+++ gcc/tree-ssa-phiprop.c	(working copy)
@@ -338,8 +338,15 @@  propagate_with_phi (basic_block bb, gphi
 	    && (!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
Index: gcc/testsuite/gcc.dg/torture/pr91812.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr91812.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr91812.c	(working copy)
@@ -0,0 +1,25 @@ 
+/* { dg-do compile } */
+/* { 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" } } */