From patchwork Fri Feb 9 16:08:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 871466 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-472957-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="lkb9Ili+"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zdKjz60mgz9s7g for ; Sat, 10 Feb 2018 03:08:38 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; q=dns; s=default; b=lm/nupvbCUh2 XRdJdThpHcR7bJKnpk9SY8LwgPlPh72mrJsgHBZG4dJ3BfqY+KAFxs+JBJ9f3YZB iEUIjYMHlTWQQHbVAhCcLnD7NFBJFIi/R96BM8M4wM/89wlsSWILwoPN0IzUsVHa lwRFAsaUekhuDNDJIUKm6qcKyXRpHQo= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; s=default; bh=wBg+wo0b752/b66OCG pUx2TFwbQ=; b=lkb9Ili+/2DIaMeCFp2fxX00h6xJI1eh8PCZgBw4Rd8u4sYaEw 175oiP4RrPJYmNMKjXIcLpj4CUmOhxu/2sn7jGjQTkEMpBc/A+LA5cR2I+vDz4Gq Rk03ipl9ACUnQ74McLWn4pqsRZrqjgBshnlgKq+cF1Lr94qNp69mNqAoA= Received: (qmail 48961 invoked by alias); 9 Feb 2018 16:08:32 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 48946 invoked by uid 89); 9 Feb 2018 16:08:31 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=9066 X-HELO: mail-wm0-f66.google.com Received: from mail-wm0-f66.google.com (HELO mail-wm0-f66.google.com) (74.125.82.66) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 09 Feb 2018 16:08:29 +0000 Received: by mail-wm0-f66.google.com with SMTP id v123so17226201wmd.5 for ; Fri, 09 Feb 2018 08:08:29 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=mxjsF5ONLa8gs/OdxpdyCK4pWwqGZTESK1t1xWCDjKo=; b=PrYNllRtgXi+sEnGvwcKz2rY48gbXudJU0goBZ7LBcS8pedQwtjEuI6pGkdys40XS6 cuydZGVgFFgR12iphRy1g2+C06HSjsrnRMo3cPqyKlFbyR8SSu6F56lTVCq2CqHpkhAE 7A/udDaCfdvbKYTk96BlPsp+uKx38jHz6Brv9uOSyezVXp9RRySsQoncSL9VUGK2Uo8K f9JwxPAM0yTW3pfV71D3Nj96hZeSFyHFT6rVgVoIkzITWlYrmf/4vJglmCAYjE6g0HJb ohCXBdRfIDti3SUOYHJExSRz/wBwaixZ2pP92Q1b+ilnc9mR7MWid4yG4SeVIPpVQX7+ yigA== X-Gm-Message-State: APf1xPDMYW75tmOaFHtdYXe/tMQw6G+UhFsh7pOZNY6uVyIJMAEoEUiC h9WXhsZmiHP7hgM+q0+D5ujwUBCz X-Google-Smtp-Source: AH8x224h8W/90jj5M9yc1xmJi9ZRqfayFRNYYse/BPgL7S0trDAlf97Fagq8VLuQfLlg5lMi6rwpLg== X-Received: by 10.28.54.26 with SMTP id d26mr2312375wma.59.1518192507247; Fri, 09 Feb 2018 08:08:27 -0800 (PST) Received: from 640k.lan ([82.84.102.245]) by smtp.gmail.com with ESMTPSA id q18sm2726037wrc.36.2018.02.09.08.08.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 09 Feb 2018 08:08:26 -0800 (PST) From: Paolo Bonzini To: gcc-patches@gcc.gnu.org Cc: marcandre.lureau@redhat.com, jakub@redhat.com, mliska@suse.cz Subject: [PATCH] Improve dead code elimination with -fsanitize=address (PR84307) Date: Fri, 9 Feb 2018 17:08:24 +0100 Message-Id: <1518192504-49084-1-git-send-email-bonzini@gnu.org> Hi all, in this PR, a dead reference to a function pointer cannot be optimized out by the compiler because some ASAN_MARK UNPOISON calls, which are placed before the store, cause the containing struct to escape. (Without -fsanitize=address, the dead code is eliminated by the first DSE pass). The fix, which works at least for this testcase, is to copy part of the sanopt dead code elimination pass early, so that the compiler can see fewer UNPOISON calls. I am not sure this is general enough, due to the very limited data flow analysis done by sanitize_asan_mark_unpoison. Another possibility which I considered but did not implement is to mark the UNPOISON calls so that they do not cause the parameter to escape. Any suggestions on how to proceed here (or approval is welcome too :))? Paolo 2018-02-09 Paolo Bonzini * passes.def: add pass_sandce before first DSE pass. * sanopt.c (pass_data_sandce, pass_sandce, make_pass_sandce): New. * tree-pass.h (make_pass_sandce): Declare it. testsuite: 2018-02-09 Paolo Bonzini PR sanitizer/84307 * gcc.dg/asan/pr84307.c: New test. diff --git a/gcc/passes.def b/gcc/passes.def index 9802f08..180df50 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -244,6 +244,7 @@ along with GCC; see the file COPYING3. If not see only examines PHIs to discover const/copy propagation opportunities. */ NEXT_PASS (pass_phi_only_cprop); + NEXT_PASS (pass_sandce); NEXT_PASS (pass_dse); NEXT_PASS (pass_reassoc, true /* insert_powi_p */); NEXT_PASS (pass_dce); diff --git a/gcc/sanopt.c b/gcc/sanopt.c index cd94638..23b8e6e 100644 --- a/gcc/sanopt.c +++ b/gcc/sanopt.c @@ -906,6 +906,32 @@ sanopt_optimize (function *fun, bool *contains_asan_mark) namespace { +const pass_data pass_data_sandce = +{ + GIMPLE_PASS, /* type */ + "sandce", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + TV_NONE, /* tv_id */ + ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_update_ssa, /* todo_flags_finish */ +}; + +class pass_sandce : public gimple_opt_pass +{ +public: + pass_sandce (gcc::context *ctxt) + : gimple_opt_pass (pass_data_sandce, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) { return flag_sanitize & SANITIZE_ADDRESS; } + virtual unsigned int execute (function *); + +}; // class pass_sanopt + const pass_data pass_data_sanopt = { GIMPLE_PASS, /* type */ @@ -1244,6 +1270,31 @@ sanitize_rewrite_addressable_params (function *fun) } unsigned int +pass_sandce::execute (function *fun) +{ + basic_block bb; + bool contains_asan_mark = false; + + /* Try to remove redundant unpoisoning. */ + gimple_stmt_iterator gsi; + FOR_EACH_BB_FN (bb, fun) + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple *stmt = gsi_stmt (gsi); + if (gimple_call_internal_p (stmt, IFN_ASAN_MARK)) + { + contains_asan_mark = true; + break; + } + } + + if (contains_asan_mark) + sanitize_asan_mark_unpoison (); + + return 0; +} + +unsigned int pass_sanopt::execute (function *fun) { basic_block bb; @@ -1367,6 +1418,12 @@ pass_sanopt::execute (function *fun) } // anon namespace gimple_opt_pass * +make_pass_sandce (gcc::context *ctxt) +{ + return new pass_sandce (ctxt); +} + +gimple_opt_pass * make_pass_sanopt (gcc::context *ctxt) { return new pass_sanopt (ctxt); diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 93a6a99..d5eb055 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -350,6 +350,7 @@ extern gimple_opt_pass *make_pass_tsan (gcc::context *ctxt); extern gimple_opt_pass *make_pass_tsan_O0 (gcc::context *ctxt); extern gimple_opt_pass *make_pass_sancov (gcc::context *ctxt); extern gimple_opt_pass *make_pass_sancov_O0 (gcc::context *ctxt); +extern gimple_opt_pass *make_pass_sandce (gcc::context *ctxt); extern gimple_opt_pass *make_pass_lower_cf (gcc::context *ctxt); extern gimple_opt_pass *make_pass_refactor_eh (gcc::context *ctxt); extern gimple_opt_pass *make_pass_lower_eh (gcc::context *ctxt); diff --git a/gcc/testsuite/gcc.dg/asan/pr84307.c b/gcc/testsuite/gcc.dg/asan/pr84307.c new file mode 100644 index 0000000..6e1a197 --- /dev/null +++ b/gcc/testsuite/gcc.dg/asan/pr84307.c @@ -0,0 +1,21 @@ +/* PR middle-end/83185 */ +/* { dg-do link } */ +/* { dg-options "-O1" } */ + +struct f { + void (*func)(void); +}; + +extern void link_error(void); +extern int printf(const char *f, ...); + +static inline struct f *gimme_null(struct f *result) +{ + return 0; +} + +int main(int argc, char **argv) +{ + struct f *x = gimme_null(&(struct f) { .func = link_error }); + printf("%p", x); +}