process_store_forwarding (forwardings, insn, load_mem);
}
- /* Abort in case that we encounter a memory read/write that is not a
- simple store/load, as we can't make safe assumptions about the
- side-effects of this. */
- if ((writes_mem && !is_simple_store)
- || (reads_mem && !is_simple_load))
- return;
-
- if (removed_count)
+ /* If we encounter a memory read/write that is not a simple
+ store/load, flush all pending store candidates and continue.
+ We can't make safe assumptions about the side-effects, but
+ store-forwarding opportunities later in the BB should still
+ be analyzed. */
+ if ((writes_mem && !is_simple_store)
+ || (reads_mem && !is_simple_load))
+ {
+ store_exprs.truncate (0);
+ continue;
+ }
+
+ if (removed_count)
{
unsigned int i, j;
store_fwd_info *it;
VEC_ORDERED_REMOVE_IF (store_exprs, i, j, it, it->remove);
}
- /* Don't consider store forwarding if the RTL instruction distance is
- more than PARAM_STORE_FORWARDING_MAX_DISTANCE and the cost checks
- are not disabled. */
- const bool unlimited_cost = (param_store_forwarding_max_distance == 0);
- if (!unlimited_cost && !store_exprs.is_empty ()
- && (store_exprs[0].insn_cnt
- + param_store_forwarding_max_distance <= insn_cnt))
- store_exprs.ordered_remove (0);
+ /* Don't consider store forwarding if the RTL instruction distance is
+ more than PARAM_STORE_FORWARDING_MAX_DISTANCE and the cost checks
+ are not disabled. */
+ const bool unlimited_cost = (param_store_forwarding_max_distance == 0);
+ if (!unlimited_cost && !store_exprs.is_empty ()
+ && (store_exprs[0].insn_cnt
+ + param_store_forwarding_max_distance <= insn_cnt))
+ store_exprs.ordered_remove (0);
- insn_cnt++;
+ insn_cnt++;
}
}
--- /dev/null
+/* Check that the pass continues after a complex memory op (volatile load). */
+/* { dg-do compile } */
+/* { dg-options "-O2 -favoid-store-forwarding -fdump-rtl-avoid_store_forwarding" } */
+
+typedef union {
+ char arr_8[8];
+ long long_value;
+} DataUnion;
+
+long ssll_complex_mem (DataUnion *data, char x, volatile int *v)
+{
+ (void)*v;
+ data->arr_8[4] = x;
+ return data->long_value;
+}
+
+/* { dg-final { scan-rtl-dump-times "Store forwarding detected" 1 "avoid_store_forwarding" } } */
+/* { dg-final { scan-rtl-dump-times "Store forwarding avoided" 1 "avoid_store_forwarding" } } */