[PATCH] Avoid optimizing memory references with side effects in compare-elim.c
Paul Koning
paulkoning@comcast.net
Tue Jun 5 17:49:00 GMT 2018
(Resending -- forgot to include a test case.)
This fixes an ICE if post-reload compare elimination is done and the target supports post_inc and similar modes, as pdp11 does. The ICE is caused by a generated PARALLEL that has the side effect twice, which is not legal.
(Ideally it would generate a similar RTL suitable for a matching constraint with the side effect omitted; I may try for that later on if that is still supported by the constraint machinery.)
Tested against my in-progress CCmode pdp11 target. Ok to commit?
paul
gcc/ChangeLog:
2018-06-05 Paul Koning <ni1d@arrl.net>
* compare-elim.c (addr_side_effect_check): New function.
(addr_side_effect_p): Ditto.
(try_merge_compare): Don't merge compare if address contains a
side effect.
* gcc.c-torture/compile/20180605-1.c: New test case.
Index: compare-elim.c
===================================================================
--- compare-elim.c (revision 261207)
+++ compare-elim.c (working copy)
@@ -127,6 +127,23 @@
static vec<comparison *> all_compares;
+/* Callback function used by addr_side_effect_p. */
+static int
+addr_side_effect_check (rtx mem ATTRIBUTE_UNUSED, rtx op ATTRIBUTE_UNUSED,
+ rtx dest ATTRIBUTE_UNUSED, rtx src ATTRIBUTE_UNUSED,
+ rtx srcoff ATTRIBUTE_UNUSED, void *arg ATTRIBUTE_UNUSED)
+{
+ return 1;
+}
+
+/* Check if addr has side effects (contains autoinc or autodec
+ operations). */
+static int
+addr_side_effect_p (rtx addr)
+{
+ return for_each_inc_dec (addr, addr_side_effect_check, NULL);
+}
+
/* Look for a "conforming" comparison, as defined above. If valid, return
the rtx for the COMPARE itself. */
@@ -690,6 +707,13 @@
return false;
rtx src = SET_SRC (set);
+
+ /* If the source uses addressing modes with side effects, we can't
+ do the merge because we'd end up with a PARALLEL that has two
+ instances of that side effect in it. */
+ if (addr_side_effect_p (src))
+ return false;
+
rtx flags = maybe_select_cc_mode (cmp, src, CONST0_RTX (GET_MODE (src)));
if (!flags)
{
@@ -809,6 +833,12 @@
else
return false;
+ /* If the source uses addressing modes with side effects, we can't
+ do the merge because we'd end up with a PARALLEL that has two
+ instances of that side effect in it. */
+ if (addr_side_effect_p (cmp_src))
+ return false;
+
/* Determine if we ought to use a different CC_MODE here. */
flags = maybe_select_cc_mode (cmp, cmp_src, in_b);
if (flags == NULL)
Index: testsuite/gcc.c-torture/compile/20180605-1.c
===================================================================
--- testsuite/gcc.c-torture/compile/20180605-1.c (nonexistent)
+++ testsuite/gcc.c-torture/compile/20180605-1.c (working copy)
@@ -0,0 +1,9 @@
+void f (int *p, int n)
+{
+ int j = 0, k;
+
+ for (int i = 0; i < n; i++)
+ if ((k = *p++) > 0)
+ j += k;
+ return j;
+}
More information about the Gcc-patches
mailing list