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

2020-05-06 Thread Segher Boessenkool
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


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

2020-05-06 Thread Jakub Jelinek via Gcc-patches
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  

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.

--- gcc/combine.c.jj2020-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 *) ]);
+  return 0;
+}


Jakub