Fix -fsanitize=thread -O0 handling of atomics (PR sanitizer/78158)

Submitted by Jakub Jelinek on March 20, 2017, 9:22 p.m.

Details

Message ID 20170320212224.GP11094@tucnak
State New
Headers show

Commit Message

Jakub Jelinek March 20, 2017, 9:22 p.m.
Hi!

libtsan only handles the standard memory model values, so I've added
just in case some new unknown memory model is used bail outs (keeping
the __atomic_* builtins instead of transforming them to __tsan_atomic*).
Except that at -O0 (or if unlucky enough otherwise) if the memory model
is variable, that means we never use __tsan_atomic*, which means libtsan
reports false positive races.  We could do those checks at runtime by
performing if ((last_arg & 0x7fff) >= 6) __atomic_* else __tsan_atomic_*,
but as there are no such values yet I think it isn't worth it (the
sync/hle acq/hle rel bits which are ored are 0x8000, 0x10000 and 0x20000
and memmodel_base strips them off).

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

2017-03-20  Jakub Jelinek  <jakub@redhat.com>

	PR sanitizer/78158
	* tsan.c (instrument_builtin_call): If the memory model argument
	is not a constant, assume it is valid.


	Jakub

Comments

Richard Guenther March 21, 2017, 8:11 a.m.
On Mon, 20 Mar 2017, Jakub Jelinek wrote:

> Hi!
> 
> libtsan only handles the standard memory model values, so I've added
> just in case some new unknown memory model is used bail outs (keeping
> the __atomic_* builtins instead of transforming them to __tsan_atomic*).
> Except that at -O0 (or if unlucky enough otherwise) if the memory model
> is variable, that means we never use __tsan_atomic*, which means libtsan
> reports false positive races.  We could do those checks at runtime by
> performing if ((last_arg & 0x7fff) >= 6) __atomic_* else __tsan_atomic_*,
> but as there are no such values yet I think it isn't worth it (the
> sync/hle acq/hle rel bits which are ored are 0x8000, 0x10000 and 0x20000
> and memmodel_base strips them off).
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Richard.
 
> 2017-03-20  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR sanitizer/78158
> 	* tsan.c (instrument_builtin_call): If the memory model argument
> 	is not a constant, assume it is valid.
> 
> --- gcc/tsan.c.jj	2017-01-01 12:45:38.000000000 +0100
> +++ gcc/tsan.c	2017-03-20 17:55:25.509294018 +0100
> @@ -499,8 +499,8 @@ instrument_builtin_call (gimple_stmt_ite
>  	  case check_last:
>  	  case fetch_op:
>  	    last_arg = gimple_call_arg (stmt, num - 1);
> -	    if (!tree_fits_uhwi_p (last_arg)
> -		|| memmodel_base (tree_to_uhwi (last_arg)) >= MEMMODEL_LAST)
> +	    if (tree_fits_uhwi_p (last_arg)
> +		&& memmodel_base (tree_to_uhwi (last_arg)) >= MEMMODEL_LAST)
>  	      return;
>  	    gimple_call_set_fndecl (stmt, decl);
>  	    update_stmt (stmt);
> @@ -564,11 +564,11 @@ instrument_builtin_call (gimple_stmt_ite
>  	    gcc_assert (num == 6);
>  	    for (j = 0; j < 6; j++)
>  	      args[j] = gimple_call_arg (stmt, j);
> -	    if (!tree_fits_uhwi_p (args[4])
> -		|| memmodel_base (tree_to_uhwi (args[4])) >= MEMMODEL_LAST)
> +	    if (tree_fits_uhwi_p (args[4])
> +		&& memmodel_base (tree_to_uhwi (args[4])) >= MEMMODEL_LAST)
>  	      return;
> -	    if (!tree_fits_uhwi_p (args[5])
> -		|| memmodel_base (tree_to_uhwi (args[5])) >= MEMMODEL_LAST)
> +	    if (tree_fits_uhwi_p (args[5])
> +		&& memmodel_base (tree_to_uhwi (args[5])) >= MEMMODEL_LAST)
>  	      return;
>  	    update_gimple_call (gsi, decl, 5, args[0], args[1], args[2],
>  				args[4], args[5]);
> @@ -642,8 +642,8 @@ instrument_builtin_call (gimple_stmt_ite
>  		  return;
>  	      }
>  	    last_arg = gimple_call_arg (stmt, num - 1);
> -	    if (!tree_fits_uhwi_p (last_arg)
> -		|| memmodel_base (tree_to_uhwi (last_arg)) >= MEMMODEL_LAST)
> +	    if (tree_fits_uhwi_p (last_arg)
> +		&& memmodel_base (tree_to_uhwi (last_arg)) >= MEMMODEL_LAST)
>  	      return;
>  	    t = TYPE_ARG_TYPES (TREE_TYPE (decl));
>  	    t = TREE_VALUE (TREE_CHAIN (t));
> 
> 	Jakub
> 
>

Patch hide | download patch | download mbox

--- gcc/tsan.c.jj	2017-01-01 12:45:38.000000000 +0100
+++ gcc/tsan.c	2017-03-20 17:55:25.509294018 +0100
@@ -499,8 +499,8 @@  instrument_builtin_call (gimple_stmt_ite
 	  case check_last:
 	  case fetch_op:
 	    last_arg = gimple_call_arg (stmt, num - 1);
-	    if (!tree_fits_uhwi_p (last_arg)
-		|| memmodel_base (tree_to_uhwi (last_arg)) >= MEMMODEL_LAST)
+	    if (tree_fits_uhwi_p (last_arg)
+		&& memmodel_base (tree_to_uhwi (last_arg)) >= MEMMODEL_LAST)
 	      return;
 	    gimple_call_set_fndecl (stmt, decl);
 	    update_stmt (stmt);
@@ -564,11 +564,11 @@  instrument_builtin_call (gimple_stmt_ite
 	    gcc_assert (num == 6);
 	    for (j = 0; j < 6; j++)
 	      args[j] = gimple_call_arg (stmt, j);
-	    if (!tree_fits_uhwi_p (args[4])
-		|| memmodel_base (tree_to_uhwi (args[4])) >= MEMMODEL_LAST)
+	    if (tree_fits_uhwi_p (args[4])
+		&& memmodel_base (tree_to_uhwi (args[4])) >= MEMMODEL_LAST)
 	      return;
-	    if (!tree_fits_uhwi_p (args[5])
-		|| memmodel_base (tree_to_uhwi (args[5])) >= MEMMODEL_LAST)
+	    if (tree_fits_uhwi_p (args[5])
+		&& memmodel_base (tree_to_uhwi (args[5])) >= MEMMODEL_LAST)
 	      return;
 	    update_gimple_call (gsi, decl, 5, args[0], args[1], args[2],
 				args[4], args[5]);
@@ -642,8 +642,8 @@  instrument_builtin_call (gimple_stmt_ite
 		  return;
 	      }
 	    last_arg = gimple_call_arg (stmt, num - 1);
-	    if (!tree_fits_uhwi_p (last_arg)
-		|| memmodel_base (tree_to_uhwi (last_arg)) >= MEMMODEL_LAST)
+	    if (tree_fits_uhwi_p (last_arg)
+		&& memmodel_base (tree_to_uhwi (last_arg)) >= MEMMODEL_LAST)
 	      return;
 	    t = TYPE_ARG_TYPES (TREE_TYPE (decl));
 	    t = TREE_VALUE (TREE_CHAIN (t));