diff mbox series

[committed] combine: Don't replace SET_SRC with REG_EQUAL note content if SET_SRC has side-effects [PR94873]

Message ID 20200506073655.GV8462@tucnak
State New
Headers show
Series [committed] combine: Don't replace SET_SRC with REG_EQUAL note content if SET_SRC has side-effects [PR94873] | expand

Commit Message

Jakub Jelinek May 6, 2020, 7:36 a.m. UTC
Hi!

There were some discussions about whether REG_EQUAL notes are valid on insns with a single
set which contains auto-inc-dec side-effects in the SET_SRC and the majority thinks that
it should be valid.  So, this patch fixes the combiner to punt in that case, because otherwise
the auto-inc-dec side-effects from the SET_SRC are lost.

Bootstrapped/regtested on {x86_64,i686,aarch64,powerpc64{,le}}-linux,
preapproved in the PR by Segher, committed to trunk so far.

2020-05-06  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/94873
	* combine.c (combine_instructions): Don't optimize using REG_EQUAL
	note if SET_SRC (set) has side-effects.

	* gcc.dg/pr94873.c: New test.



	Jakub

Comments

Segher Boessenkool May 6, 2020, 8:33 p.m. UTC | #1
On Wed, May 06, 2020 at 09:36:55AM +0200, Jakub Jelinek wrote:
> There were some discussions about whether REG_EQUAL notes are valid on insns with a single
> set which contains auto-inc-dec side-effects in the SET_SRC and the majority thinks that
> it should be valid.  So, this patch fixes the combiner to punt in that case, because otherwise
> the auto-inc-dec side-effects from the SET_SRC are lost.
> 
> Bootstrapped/regtested on {x86_64,i686,aarch64,powerpc64{,le}}-linux,
> preapproved in the PR by Segher, committed to trunk so far.

Thanks!  It would be nice if we could handle this more centrally, make
sure we never lose (significant) side effects.  Maybe that cannot be
done with current RTL :-/


Segher
diff mbox series

Patch

--- gcc/combine.c.jj	2020-04-24 14:40:21.087840193 +0200
+++ gcc/combine.c	2020-05-05 12:15:36.793466471 +0200
@@ -1485,6 +1485,7 @@  combine_instructions (rtx_insn *f, unsig
 	      if ((set = single_set (temp)) != 0
 		  && (note = find_reg_equal_equiv_note (temp)) != 0
 		  && (note = XEXP (note, 0), GET_CODE (note)) != EXPR_LIST
+		  && ! side_effects_p (SET_SRC (set))
 		  /* Avoid using a register that may already been marked
 		     dead by an earlier instruction.  */
 		  && ! unmentioned_reg_p (note, SET_SRC (set))
--- gcc/testsuite/gcc.dg/pr94873.c.jj	2020-05-05 12:18:35.056778567 +0200
+++ gcc/testsuite/gcc.dg/pr94873.c	2020-05-05 12:14:27.437512245 +0200
@@ -0,0 +1,27 @@ 
+/* PR rtl-optimization/94873 */
+/* { dg-do run { target int128 } } */
+/* { dg-options "-O -fno-merge-constants -fno-split-wide-types -fno-tree-fre" } */
+
+__attribute__((noipa)) void
+foo (const char *p, int q)
+{
+  if (p[0] != '%' || p[1] != '0' || p[2] != '2' || p[3] != 'x' || p[4] != '\0')
+    __builtin_abort ();
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+  if ((unsigned char) q != 0x95)
+    __builtin_abort ();
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+  if ((unsigned char) q != 0)
+    __builtin_abort ();
+#endif
+}
+
+int
+main ()
+{
+  union U { __int128 a; char b[sizeof (__int128)]; };
+  char x = ((union U){ .a = 0xF4409395252B9560ULL}).b[1];
+  for (unsigned i = 0; i < sizeof (x); i++)
+    foo ("%02x", i[(volatile unsigned char *) &x]);
+  return 0;
+}