From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10531 invoked by alias); 8 Sep 2016 12:50:58 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 10512 invoked by uid 89); 8 Sep 2016 12:50:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.2 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 08 Sep 2016 12:50:56 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EBB35C01B154; Thu, 8 Sep 2016 12:50:54 +0000 (UTC) Received: from laptop.zalov.cz (ovpn-116-113.ams2.redhat.com [10.36.116.113]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u88Coqut014798 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 8 Sep 2016 08:50:54 -0400 Received: from laptop.zalov.cz (localhost [127.0.0.1]) by laptop.zalov.cz (8.15.2/8.15.2) with ESMTP id u88CojcT002955; Thu, 8 Sep 2016 14:50:46 +0200 Received: (from jakub@localhost) by laptop.zalov.cz (8.15.2/8.15.2/Submit) id u88CogZd002954; Thu, 8 Sep 2016 14:50:42 +0200 Date: Thu, 08 Sep 2016 13:29:00 -0000 From: Jakub Jelinek To: Richard Biener Cc: Dodji Seketeli , gcc-patches@gcc.gnu.org Subject: [PATCH] -fsanitize=thread fixes (PR sanitizer/68260, take 2) Message-ID: <20160908125040.GD2920@laptop.zalov.cz> Reply-To: Jakub Jelinek References: <20160906203359.GN14857@tucnak.redhat.com> <20160907204020.GA21831@laptop.zalov.cz> <20160908123418.GC2920@laptop.zalov.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20160908123418.GC2920@laptop.zalov.cz> User-Agent: Mutt/1.6.1 (2016-04-27) X-IsSubscribed: yes X-SW-Source: 2016-09/txt/msg00442.txt.bz2 On Thu, Sep 08, 2016 at 02:34:18PM +0200, Jakub Jelinek wrote: > I can split the patch into two, one dealing just with the > __atomic_clear/__atomic_test_and_set instrumentation and another for the > preexisting -fnon-call-exceptions ICEs. For the latter, one possibility > would be to error out on the -fsanitize=thread -fnon-call-exceptions > combination. Here is just the hopefully non-controversial first split part. Ok for trunk? 2016-09-08 Jakub Jelinek PR sanitizer/68260 * tsan.c: Include target.h. (enum tsan_atomic_action): Add bool_clear and bool_test_and_set. (BOOL_CLEAR, BOOL_TEST_AND_SET): Define. (tsan_atomic_table): Add BUILT_IN_ATOMIC_CLEAR and BUILT_IN_ATOMIC_TEST_AND_SET entries. (instrument_builtin_call): Handle bool_clear and bool_test_and_set. * c-c++-common/tsan/pr68260.c: New test. --- gcc/tsan.c.jj 2016-07-22 15:55:31.591287885 +0200 +++ gcc/tsan.c 2016-09-08 14:46:08.645027959 +0200 @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. #include "tsan.h" #include "asan.h" #include "builtins.h" +#include "target.h" /* Number of instrumented memory accesses in the current function. */ @@ -240,7 +241,8 @@ instrument_expr (gimple_stmt_iterator gs enum tsan_atomic_action { check_last, add_seq_cst, add_acquire, weak_cas, strong_cas, - bool_cas, val_cas, lock_release, fetch_op, fetch_op_seq_cst + bool_cas, val_cas, lock_release, fetch_op, fetch_op_seq_cst, + bool_clear, bool_test_and_set }; /* Table how to map sync/atomic builtins to their corresponding @@ -274,6 +276,10 @@ static const struct tsan_map_atomic TRANSFORM (fcode, tsan_fcode, fetch_op, code) #define FETCH_OPS(fcode, tsan_fcode, code) \ TRANSFORM (fcode, tsan_fcode, fetch_op_seq_cst, code) +#define BOOL_CLEAR(fcode, tsan_fcode) \ + TRANSFORM (fcode, tsan_fcode, bool_clear, ERROR_MARK) +#define BOOL_TEST_AND_SET(fcode, tsan_fcode) \ + TRANSFORM (fcode, tsan_fcode, bool_test_and_set, ERROR_MARK) CHECK_LAST (ATOMIC_LOAD_1, TSAN_ATOMIC8_LOAD), CHECK_LAST (ATOMIC_LOAD_2, TSAN_ATOMIC16_LOAD), @@ -463,7 +469,11 @@ static const struct tsan_map_atomic LOCK_RELEASE (SYNC_LOCK_RELEASE_2, TSAN_ATOMIC16_STORE), LOCK_RELEASE (SYNC_LOCK_RELEASE_4, TSAN_ATOMIC32_STORE), LOCK_RELEASE (SYNC_LOCK_RELEASE_8, TSAN_ATOMIC64_STORE), - LOCK_RELEASE (SYNC_LOCK_RELEASE_16, TSAN_ATOMIC128_STORE) + LOCK_RELEASE (SYNC_LOCK_RELEASE_16, TSAN_ATOMIC128_STORE), + + BOOL_CLEAR (ATOMIC_CLEAR, TSAN_ATOMIC8_STORE), + + BOOL_TEST_AND_SET (ATOMIC_TEST_AND_SET, TSAN_ATOMIC8_EXCHANGE) }; /* Instrument an atomic builtin. */ @@ -615,6 +625,57 @@ instrument_builtin_call (gimple_stmt_ite build_int_cst (NULL_TREE, MEMMODEL_RELEASE)); return; + case bool_clear: + case bool_test_and_set: + if (BOOL_TYPE_SIZE != 8) + { + decl = NULL_TREE; + for (j = 1; j < 5; j++) + if (BOOL_TYPE_SIZE == (8 << j)) + { + enum built_in_function tsan_fcode + = (enum built_in_function) + (tsan_atomic_table[i].tsan_fcode + j); + decl = builtin_decl_implicit (tsan_fcode); + break; + } + if (decl == NULL_TREE) + 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) + return; + t = TYPE_ARG_TYPES (TREE_TYPE (decl)); + t = TREE_VALUE (TREE_CHAIN (t)); + if (tsan_atomic_table[i].action == bool_clear) + { + update_gimple_call (gsi, decl, 3, gimple_call_arg (stmt, 0), + build_int_cst (t, 0), last_arg); + return; + } + t = build_int_cst (t, targetm.atomic_test_and_set_trueval); + update_gimple_call (gsi, decl, 3, gimple_call_arg (stmt, 0), + t, last_arg); + stmt = gsi_stmt (*gsi); + lhs = gimple_call_lhs (stmt); + if (lhs == NULL_TREE) + return; + if (targetm.atomic_test_and_set_trueval != 1 + || !useless_type_conversion_p (TREE_TYPE (lhs), + TREE_TYPE (t))) + { + tree new_lhs = make_ssa_name (TREE_TYPE (t)); + gimple_call_set_lhs (stmt, new_lhs); + if (targetm.atomic_test_and_set_trueval != 1) + g = gimple_build_assign (lhs, NE_EXPR, new_lhs, + build_int_cst (TREE_TYPE (t), 0)); + else + g = gimple_build_assign (lhs, NOP_EXPR, new_lhs); + gsi_insert_after (gsi, g, GSI_NEW_STMT); + update_stmt (stmt); + } + return; default: continue; } --- gcc/testsuite/c-c++-common/tsan/pr68260.c.jj 2016-09-08 14:45:08.994860025 +0200 +++ gcc/testsuite/c-c++-common/tsan/pr68260.c 2016-09-08 14:45:08.994860025 +0200 @@ -0,0 +1,28 @@ +/* PR sanitizer/68260 */ + +#include +#include + +bool lock; +int counter; + +void * +tf (void *arg) +{ + (void) arg; + while (__atomic_test_and_set (&lock, __ATOMIC_ACQUIRE)) + ; + ++counter; + __atomic_clear (&lock, __ATOMIC_RELEASE); + return (void *) 0; +} + +int +main () +{ + pthread_t thr; + pthread_create (&thr, 0, tf, 0); + tf ((void *) 0); + pthread_join (thr, 0); + return 0; +} Jakub