diff mbox series

reassoc: Avoid code generation to depend on hash_map traversal [PR94166]

Message ID 20200314073421.GA2156@tucnak
State New
Headers show
Series reassoc: Avoid code generation to depend on hash_map traversal [PR94166] | expand

Commit Message

Li, Pan2 via Gcc-patches March 14, 2020, 7:34 a.m. UTC
Hi!

On the following testcase, if there is ASLR, the compiler generates
different code each time (out of 1000 invocations 994 unique assembler
contents).  The problem is that undistribute_bitref_for_vector uses
a hash_map from a tree (SSA_NAME) to a vector and such a hash_map is
by default doing pointer hashing on the SSA_NAME rather than using
something stable (SSA_NAME_VERSION).
One possible way would be to use SSA_NAME_VERSION as hash function,
but given that we from the hash_map traversal just populate a vector
which is then sorted, I think it is easier to make the sort callback
use SSA_NAME_VERSION as secondary sorting key and thus ensure stable
sort (that is generally desirable anyway).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2020-03-14  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/94166
	* tree-ssa-reassoc.c (sort_by_mach_mode): Use SSA_NAME_VERSION
	as secondary comparison key.

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


	Jakub

Comments

Richard Biener March 16, 2020, 7:35 a.m. UTC | #1
On Sat, 14 Mar 2020, Jakub Jelinek wrote:

> Hi!
> 
> On the following testcase, if there is ASLR, the compiler generates
> different code each time (out of 1000 invocations 994 unique assembler
> contents).  The problem is that undistribute_bitref_for_vector uses
> a hash_map from a tree (SSA_NAME) to a vector and such a hash_map is
> by default doing pointer hashing on the SSA_NAME rather than using
> something stable (SSA_NAME_VERSION).
> One possible way would be to use SSA_NAME_VERSION as hash function,
> but given that we from the hash_map traversal just populate a vector
> which is then sorted, I think it is easier to make the sort callback
> use SSA_NAME_VERSION as secondary sorting key and thus ensure stable
> sort (that is generally desirable anyway).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2020-03-14  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR tree-optimization/94166
> 	* tree-ssa-reassoc.c (sort_by_mach_mode): Use SSA_NAME_VERSION
> 	as secondary comparison key.
> 
> 	* gcc.dg/pr94166.c: New test.
> 
> --- gcc/tree-ssa-reassoc.c.jj	2020-01-12 11:54:38.510381771 +0100
> +++ gcc/tree-ssa-reassoc.c	2020-03-13 14:06:32.358085863 +0100
> @@ -1793,8 +1793,11 @@ sort_by_mach_mode (const void *p_i, cons
>      return 1;
>    else if (mode1 < mode2)
>      return -1;
> -  else
> -    return 0;
> +  if (SSA_NAME_VERSION (tr1) < SSA_NAME_VERSION (tr2))
> +    return -1;
> +  else if (SSA_NAME_VERSION (tr1) > SSA_NAME_VERSION (tr2))
> +    return 1;
> +  return 0;
>  }
>  
>  /* Cleanup hash map for VECTOR information.  */
> --- gcc/testsuite/gcc.dg/pr94166.c.jj	2020-03-13 14:36:46.382260562 +0100
> +++ gcc/testsuite/gcc.dg/pr94166.c	2020-03-13 14:40:32.536916640 +0100
> @@ -0,0 +1,24 @@
> +/* PR tree-optimization/94166 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fcompare-debug" } */
> +
> +typedef int __m128i __attribute__((__may_alias__, __vector_size__(4 * sizeof (int))));
> +unsigned int b[512];
> +
> +void
> +foo (unsigned int *x, __m128i *y)
> +{
> +#define A(n) __m128i v##n = y[n];
> +#define B(n) A(n##0) A(n##1) A(n##2) A(n##3) A(n##4) A(n##5) A(n##6) A(n##7) \
> +	     A(n##8) A(n##9) A(n##a) A(n##b) A(n##c) A(n##d) A(n##e) A(n##f)
> +#define C(n) B(n##0) B(n##1) B(n##2) B(n##3) B(n##4) B(n##5) B(n##6) B(n##7)
> +  C(0x)
> +#undef A
> +#define A(n) *(__m128i *) &b[4 * n] = v##n;
> +  C(0x)
> +#undef A
> +#define A(n) + b[4 * n] + b[4 * n + 1] + b[4 * n + 2] + b[4 * n + 3]
> +  *x = *x
> +  C(0x)
> +  ;
> +}
> 
> 	Jakub
> 
>
diff mbox series

Patch

--- gcc/tree-ssa-reassoc.c.jj	2020-01-12 11:54:38.510381771 +0100
+++ gcc/tree-ssa-reassoc.c	2020-03-13 14:06:32.358085863 +0100
@@ -1793,8 +1793,11 @@  sort_by_mach_mode (const void *p_i, cons
     return 1;
   else if (mode1 < mode2)
     return -1;
-  else
-    return 0;
+  if (SSA_NAME_VERSION (tr1) < SSA_NAME_VERSION (tr2))
+    return -1;
+  else if (SSA_NAME_VERSION (tr1) > SSA_NAME_VERSION (tr2))
+    return 1;
+  return 0;
 }
 
 /* Cleanup hash map for VECTOR information.  */
--- gcc/testsuite/gcc.dg/pr94166.c.jj	2020-03-13 14:36:46.382260562 +0100
+++ gcc/testsuite/gcc.dg/pr94166.c	2020-03-13 14:40:32.536916640 +0100
@@ -0,0 +1,24 @@ 
+/* PR tree-optimization/94166 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcompare-debug" } */
+
+typedef int __m128i __attribute__((__may_alias__, __vector_size__(4 * sizeof (int))));
+unsigned int b[512];
+
+void
+foo (unsigned int *x, __m128i *y)
+{
+#define A(n) __m128i v##n = y[n];
+#define B(n) A(n##0) A(n##1) A(n##2) A(n##3) A(n##4) A(n##5) A(n##6) A(n##7) \
+	     A(n##8) A(n##9) A(n##a) A(n##b) A(n##c) A(n##d) A(n##e) A(n##f)
+#define C(n) B(n##0) B(n##1) B(n##2) B(n##3) B(n##4) B(n##5) B(n##6) B(n##7)
+  C(0x)
+#undef A
+#define A(n) *(__m128i *) &b[4 * n] = v##n;
+  C(0x)
+#undef A
+#define A(n) + b[4 * n] + b[4 * n + 1] + b[4 * n + 2] + b[4 * n + 3]
+  *x = *x
+  C(0x)
+  ;
+}