From patchwork Tue Nov 8 12:03:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kyrill Tkachov X-Patchwork-Id: 81294 Delivered-To: patch@linaro.org Received: by 10.140.97.165 with SMTP id m34csp1506851qge; Tue, 8 Nov 2016 04:04:18 -0800 (PST) X-Received: by 10.99.218.85 with SMTP id l21mr6297604pgj.102.1478606658155; Tue, 08 Nov 2016 04:04:18 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id v17si36643621pgi.130.2016.11.08.04.04.17 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 08 Nov 2016 04:04:18 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-440733-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-440733-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-440733-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=OwjrY+6NcWkqVjre9p7CG88Jt3sD6NdPdQqL4mFb9AeEUB rybwdIP8lDarZ7LhHSM1ek0leKnKZcTnor+F8VTiIqSasjwsWCamq/gXyGnk1X+b alSHirMnWvGjLnbH0gY57xzdOFxSazpLiffWe0yfi+vgtO7R/JGGkR3QNOCto= 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 :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=uf4y3f6ZrQmMRQbIyi674EiWUpg=; b=ujI9CjS52z1XRjkjewKQ 597dU1DDKh9eEuJM/1yGJx5j1OHPg0bj3jz1g1BnXLblgDIUfC/nLgtt6lwhElxs OsAU8ej+fqwKaQg+syWz4bgdMpCdF7JiC2Wf0CMT+KGeNmkeDf1nc5rgwpJ9woYz GnFiXzBlW2J/puZka0I8dLE= Received: (qmail 49652 invoked by alias); 8 Nov 2016 12:03:36 -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 49518 invoked by uid 89); 8 Nov 2016 12:03:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.5 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, KAM_LOTSOFHASH, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=intact, 20161108 X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 08 Nov 2016 12:03:28 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 38311CF6; Tue, 8 Nov 2016 04:03:27 -0800 (PST) Received: from [10.2.207.77] (e100706-lin.cambridge.arm.com [10.2.207.77]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id DC68D3F25D for ; Tue, 8 Nov 2016 04:03:26 -0800 (PST) Message-ID: <5821BF0D.7040902@foss.arm.com> Date: Tue, 08 Nov 2016 12:03:25 +0000 From: Kyrill Tkachov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: GCC Patches Subject: [PATCH][2/2] Add store merging unit tests Hi all, This patch adds the plumbing for unit testing of the store merging pass. It also adds some initial tests of some of the helpers used in encode_tree_to_bitpos to manipulate byte arrays. They caught an off-by-one error bug that is fixed in patch [1/2]. Bootstrapped and tested on x86_64 and aarch64. Ok for trunk? Thanks, Kyrill 2016-11-08 Kyrylo Tkachov * gimple-ssa-store-merging.c: Include selftest.h (verify_array_eq): New function. (verify_shift_bytes_in_array): Likewise. (verify_shift_bytes_in_array_right): Likewise. (verify_clear_bit_region): Likewise. (verify_clear_bit_region_be): Likewise. (store_merging_c_tests): Likewise. * selftest.h (store_merging_c_tests): Declare prototype. * selftest-run-tests.c (selftest::run_tests): Run store_merging_c_tests. diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c index 46f92ba2d2f4e85c4256be11be5c8b1d40c21499..7b59f81e26423c60f8bf1c975281d3904315b306 100644 --- a/gcc/gimple-ssa-store-merging.c +++ b/gcc/gimple-ssa-store-merging.c @@ -126,6 +126,7 @@ #include "tree-eh.h" #include "target.h" #include "gimplify-me.h" +#include "selftest.h" /* The maximum size (in bits) of the stores this pass should generate. */ #define MAX_STORE_BITSIZE (BITS_PER_WORD) @@ -1499,3 +1500,141 @@ make_pass_store_merging (gcc::context *ctxt) { return new pass_store_merging (ctxt); } + +#if CHECKING_P + +namespace selftest { + +/* Selftests for store merging helpers. */ + +/* Assert that all elements of the byte arrays X and Y, both of length N + are equal. */ + +static void +verify_array_eq (unsigned char *x, unsigned char *y, unsigned int n) +{ + for (unsigned int i = 0; i < n; i++) + { + if (x[i] != y[i]) + { + fprintf (stderr, "Arrays do not match. X:\n"); + dump_char_array (stderr, x, n); + fprintf (stderr, "Y:\n"); + dump_char_array (stderr, y, n); + } + ASSERT_EQ (x[i], y[i]); + } +} + +/* Test shift_bytes_in_array and that it carries bits across between + bytes correctly. */ + +static void +verify_shift_bytes_in_array (void) +{ + /* byte 1 | byte 0 + 00011111 | 11100000. */ + unsigned char orig[2] = { 0xe0, 0x1f }; + unsigned char in[2]; + memcpy (in, orig, sizeof orig); + + unsigned char expected[2] = { 0x80, 0x7f }; + shift_bytes_in_array (in, sizeof (in), 2); + verify_array_eq (in, expected, sizeof (in)); + + memcpy (in, orig, sizeof orig); + memcpy (expected, orig, sizeof orig); + /* Check that shifting by zero doesn't change anything. */ + shift_bytes_in_array (in, sizeof (in), 0); + verify_array_eq (in, expected, sizeof (in)); + +} + +/* Test shift_bytes_in_array_right and that it carries bits across between + bytes correctly. */ + +static void +verify_shift_bytes_in_array_right (void) +{ + /* byte 1 | byte 0 + 00011111 | 11100000. */ + unsigned char orig[2] = { 0x1f, 0xe0}; + unsigned char in[2]; + memcpy (in, orig, sizeof orig); + unsigned char expected[2] = { 0x07, 0xf8}; + shift_bytes_in_array_right (in, sizeof (in), 2); + verify_array_eq (in, expected, sizeof (in)); + + memcpy (in, orig, sizeof orig); + memcpy (expected, orig, sizeof orig); + /* Check that shifting by zero doesn't change anything. */ + shift_bytes_in_array_right (in, sizeof (in), 0); + verify_array_eq (in, expected, sizeof (in)); +} + +/* Test clear_bit_region that it clears exactly the bits asked and + nothing more. */ + +static void +verify_clear_bit_region (void) +{ + /* Start with all bits set and test clearing various patterns in them. */ + unsigned char orig[3] = { 0xff, 0xff, 0xff}; + unsigned char in[3]; + unsigned char expected[3]; + memcpy (in, orig, sizeof in); + + /* Check zeroing out all the bits. */ + clear_bit_region (in, 0, 3 * BITS_PER_UNIT); + expected[0] = expected[1] = expected[2] = 0; + verify_array_eq (in, expected, sizeof in); + + memcpy (in, orig, sizeof in); + /* Leave the first and last bits intact. */ + clear_bit_region (in, 1, 3 * BITS_PER_UNIT - 2); + expected[0] = 0x1; + expected[1] = 0; + expected[2] = 0x80; + verify_array_eq (in, expected, sizeof in); +} + +/* Test verify_clear_bit_region_be that it clears exactly the bits asked and + nothing more. */ + +static void +verify_clear_bit_region_be (void) +{ + /* Start with all bits set and test clearing various patterns in them. */ + unsigned char orig[3] = { 0xff, 0xff, 0xff}; + unsigned char in[3]; + unsigned char expected[3]; + memcpy (in, orig, sizeof in); + + /* Check zeroing out all the bits. */ + clear_bit_region_be (in, BITS_PER_UNIT - 1, 3 * BITS_PER_UNIT); + expected[0] = expected[1] = expected[2] = 0; + verify_array_eq (in, expected, sizeof in); + + memcpy (in, orig, sizeof in); + /* Leave the first and last bits intact. */ + clear_bit_region_be (in, BITS_PER_UNIT - 2, 3 * BITS_PER_UNIT - 2); + expected[0] = 0x80; + expected[1] = 0; + expected[2] = 0x1; + verify_array_eq (in, expected, sizeof in); +} + + +/* Run all of the selftests within this file. */ + +void +store_merging_c_tests (void) +{ + verify_shift_bytes_in_array (); + verify_shift_bytes_in_array_right (); + verify_clear_bit_region (); + verify_clear_bit_region_be (); +} + +} // namespace selftest +#endif /* CHECKING_P. */ diff --git a/gcc/selftest-run-tests.c b/gcc/selftest-run-tests.c index 54a9b0f6c7ebc79881f9cb33b0a4c3d97c59c405..a796e07a856076c96cf97805a8ea831dd5a21045 100644 --- a/gcc/selftest-run-tests.c +++ b/gcc/selftest-run-tests.c @@ -77,6 +77,8 @@ selftest::run_tests () /* This one relies on most of the above. */ function_tests_c_tests (); + store_merging_c_tests (); + /* Run any lang-specific selftests. */ lang_hooks.run_lang_selftests (); diff --git a/gcc/selftest.h b/gcc/selftest.h index 845eb01b12511e3667e5a83dd69e5fbcd888b808..dcce474be6e1899e46f7a9c0d1560e0b7eb60369 100644 --- a/gcc/selftest.h +++ b/gcc/selftest.h @@ -179,6 +179,7 @@ extern void selftest_c_tests (); extern void spellcheck_c_tests (); extern void spellcheck_tree_c_tests (); extern void sreal_c_tests (); +extern void store_merging_c_tests (); extern void typed_splay_tree_c_tests (); extern void tree_c_tests (); extern void tree_cfg_c_tests ();