diff mbox

DOn't miscompile programs with -flto -fno-merge-constants (PR middle-end/50199)

Message ID 20170110225510.GE21933@tucnak
State New
Headers show

Commit Message

Jakub Jelinek Jan. 10, 2017, 10:55 p.m. UTC
Hi!

LTO partitioning can actually take appart uses of STRING_CSTs or other
constants and put those into multiple partitions.  When -fno-merge-constants
is in effect, it means those constants aren't merged by the linker and
e.g. following testcase fails.

I fail to see what -flto -fno-merge-constants would be good for,
-fno-merge-constants can be used to decrease link time, or when producing
assembly and parsing something in it, but both cases don't make much sense
with LTO.  So for now the patch just forces constant merging when in lto.

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

2017-01-10  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/50199
	* lto-lang.c (lto_post_options): Force flag_merge_constants = 1
	if it was 0.

	* gcc.dg/lto/pr50199_0.c: New test.


	Jakub

Comments

Richard Biener Jan. 11, 2017, 8:33 a.m. UTC | #1
On Tue, 10 Jan 2017, Jakub Jelinek wrote:

> Hi!
> 
> LTO partitioning can actually take appart uses of STRING_CSTs or other
> constants and put those into multiple partitions.  When -fno-merge-constants
> is in effect, it means those constants aren't merged by the linker and
> e.g. following testcase fails.
> 
> I fail to see what -flto -fno-merge-constants would be good for,
> -fno-merge-constants can be used to decrease link time, or when producing
> assembly and parsing something in it, but both cases don't make much sense
> with LTO.  So for now the patch just forces constant merging when in lto.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Richard.

> 2017-01-10  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR middle-end/50199
> 	* lto-lang.c (lto_post_options): Force flag_merge_constants = 1
> 	if it was 0.
> 
> 	* gcc.dg/lto/pr50199_0.c: New test.
> 
> --- gcc/lto/lto-lang.c.jj	2017-01-01 12:45:47.000000000 +0100
> +++ gcc/lto/lto-lang.c	2017-01-10 14:37:20.158387918 +0100
> @@ -857,6 +857,12 @@ lto_post_options (const char **pfilename
>       support.  */
>    flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;
>  
> +  /* When partitioning, we can tear appart STRING_CSTs uses from the same
> +     TU into multiple partitions.  Without constant merging the constants
> +     might not be equal at runtime.  See PR50199.  */
> +  if (!flag_merge_constants)
> +    flag_merge_constants = 1;
> +
>    /* Initialize the compiler back end.  */
>    return false;
>  }
> --- gcc/testsuite/gcc.dg/lto/pr50199_0.c.jj	2017-01-10 14:44:06.276071432 +0100
> +++ gcc/testsuite/gcc.dg/lto/pr50199_0.c	2017-01-10 14:43:49.000000000 +0100
> @@ -0,0 +1,17 @@
> +/* PR middle-end/50199 */
> +/* { dg-lto-options {{-O2 -flto -fno-merge-constants --param=lto-min-partition=1}} } */
> +
> +__attribute__ ((noinline)) const char *
> +foo (const char *x)
> +{
> +  return x;
> +}
> +
> +int
> +main ()
> +{
> +  const char *a = "ab";
> +  if (a != foo (a))
> +    __builtin_abort ();
> +  return 0;
> +}
> 
> 	Jakub
> 
>
diff mbox

Patch

--- gcc/lto/lto-lang.c.jj	2017-01-01 12:45:47.000000000 +0100
+++ gcc/lto/lto-lang.c	2017-01-10 14:37:20.158387918 +0100
@@ -857,6 +857,12 @@  lto_post_options (const char **pfilename
      support.  */
   flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;
 
+  /* When partitioning, we can tear appart STRING_CSTs uses from the same
+     TU into multiple partitions.  Without constant merging the constants
+     might not be equal at runtime.  See PR50199.  */
+  if (!flag_merge_constants)
+    flag_merge_constants = 1;
+
   /* Initialize the compiler back end.  */
   return false;
 }
--- gcc/testsuite/gcc.dg/lto/pr50199_0.c.jj	2017-01-10 14:44:06.276071432 +0100
+++ gcc/testsuite/gcc.dg/lto/pr50199_0.c	2017-01-10 14:43:49.000000000 +0100
@@ -0,0 +1,17 @@ 
+/* PR middle-end/50199 */
+/* { dg-lto-options {{-O2 -flto -fno-merge-constants --param=lto-min-partition=1}} } */
+
+__attribute__ ((noinline)) const char *
+foo (const char *x)
+{
+  return x;
+}
+
+int
+main ()
+{
+  const char *a = "ab";
+  if (a != foo (a))
+    __builtin_abort ();
+  return 0;
+}