From patchwork Mon Aug 8 19:56:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Edlinger X-Patchwork-Id: 656955 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3s7Sqn4m6Xz9rxl for ; Tue, 9 Aug 2016 05:57:25 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=XyOFgopW; dkim-atps=neutral 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:subject:date:message-id:content-type:mime-version; q=dns; s= default; b=XijYjzz7fGO2aYwvxj3vnA4Dun3Dkdd1KRAdigTtnD7HCFge/q46J Eoc4w6735qpW7l2HFEbZnIJIUQ7z4qoONqBPdQsCjM5MOc5hnrCjMN06Iitsrc2G 2RkskHiFYFwFOqDX/sLifROxmftdNI+KtLEr14tMAYOWzVBu8UXc8s= 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:subject:date:message-id:content-type:mime-version; s= default; bh=fSpAaiYiHHP6RxiJG3Ci06j1aM8=; b=XyOFgopWnIWjJKpVMvIb 6rtlzKZFFdTBvUbJ2Y5M1oCNlxO+eKSKODBcb0+5V1mVctm69u0C8pfVOXOb2ulu v+62Nym0+yewd6tBmiXVuwCst5rkJ+J3wGnUPNZW07Q5Sk8FsLR+uWDup3nALHtJ N6WylMCA0vYF+op3rIPy4ws= Received: (qmail 7057 invoked by alias); 8 Aug 2016 19:57:17 -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 7044 invoked by uid 89); 8 Aug 2016 19:57:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=no version=3.3.2 spammy=compensates, machine_mode, H*c:sk:HMHPRHH, accesses X-HELO: BAY004-OMC1S24.hotmail.com Received: from bay004-omc1s24.hotmail.com (HELO BAY004-OMC1S24.hotmail.com) (65.54.190.35) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA256 encrypted) ESMTPS; Mon, 08 Aug 2016 19:57:06 +0000 Received: from EUR01-VE1-obe.outbound.protection.outlook.com ([65.54.190.61]) by BAY004-OMC1S24.hotmail.com over TLS secured channel with Microsoft SMTPSVC(7.5.7601.23008); Mon, 8 Aug 2016 12:57:05 -0700 Received: from VE1EUR01FT064.eop-EUR01.prod.protection.outlook.com (10.152.2.59) by VE1EUR01HT253.eop-EUR01.prod.protection.outlook.com (10.152.3.170) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.567.7; Mon, 8 Aug 2016 19:57:04 +0000 Received: from AM4PR0701MB2162.eurprd07.prod.outlook.com (10.152.2.53) by VE1EUR01FT064.mail.protection.outlook.com (10.152.3.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.567.7 via Frontend Transport; Mon, 8 Aug 2016 19:57:04 +0000 Received: from AM4PR0701MB2162.eurprd07.prod.outlook.com ([10.167.132.147]) by AM4PR0701MB2162.eurprd07.prod.outlook.com ([10.167.132.147]) with mapi id 15.01.0549.025; Mon, 8 Aug 2016 19:56:57 +0000 From: Bernd Edlinger To: "gcc-patches@gcc.gnu.org" , Richard Biener , Jeff Law , Jakub Jelinek Subject: [PATCH] Fix unaligned access when predictive commoning (PR 71083) Date: Mon, 8 Aug 2016 19:56:57 +0000 Message-ID: authentication-results: spf=softfail (sender IP is 10.152.2.53) smtp.mailfrom=hotmail.de; gcc.gnu.org; dkim=none (message not signed) header.d=none; gcc.gnu.org; dmarc=none action=none header.from=hotmail.de; received-spf: SoftFail (protection.outlook.com: domain of transitioning hotmail.de discourages use of 10.152.2.53 as permitted sender) x-ms-exchange-messagesentrepresentingtype: 1 x-eopattributedmessage: 0 x-forefront-antispam-report: CIP:10.152.2.53; IPV:NLI; CTRY:; EFV:NLI; SFV:NSPM; SFS:(10019020)(98900003); DIR:OUT; SFP:1102; SCL:1; SRVR:VE1EUR01HT253; H:AM4PR0701MB2162.eurprd07.prod.outlook.com; FPR:; SPF:None; LANG:en; x-microsoft-exchange-diagnostics: 1; VE1EUR01HT253; 6:cAYLhtn/a6kOx7ZB89bQ2SZxyTrPE99n7FF55dpcnyGgfa3Ut/ufXvP3+aflsnO+qauYoTMNIkGFoYDPstejaq8Cw8JWk811bavoOadJpBScUwTQmJ4No2w+IZ/JR7mpw/d3/YrBdb6fIoRwDS8EmJTsO1CWUdtdvMt1PA+BIMrXaRW/Q2chNHRJS3C2LX8XEPW/0E+789aHIC31/nfVcPR79UpHRCmrkZ69hmAvDHNk5oEDsqQGgJ6E1DxM+YfX8k7GAOn2E24x3FF4rVBXd0iz1XCH+ADFfGDfRiMx0HL97pU91YqrbU0LQdlaItZ/; 5:VET+OzLHGJOnk8aJEtKbk80NWLJqWr1o2Kk1XUz9vXS5QBbbn1w40Yf7Iuf7scI0ggEa6fSzX1x/0R+t+GLFapKEQHEzGXPIWZape961CCgk6b3x77raJNiJ+Fe2xj0icqODJnz1ticln9Dl2pNHEQ==; 24:bRPmg/4ufbdfwazZZaCjM3PjaCAFpQHEtuoxeGLnfJqkI6/JVKv6qPVHBrSPwITh+aD8WPeuQiLNJl59ra2faCPE47ihIXLYRGoNvwXYGBc=; 7:AEBeg7OSnlwyfZMEPodNgHZl8zCBAqfLoI6lMUav2Qlqxniuvb6BD/oXLiREsr7+9ORNG4orgMe/ZpGY+3k8gogY9N6GxtaL176j/JkUUL6/S+CvDztxs80GVf3OrQjdfK93wZ+D6zB2WOwDsWB1apv4A7Uuw16HgsoEzW+NiiqkvqzeZZhT+0R89CmRafy07debwxl/L4ARCZqyYVNhaD6M4diUqisGM4VIaGOywMIaQJSRujRIBvIAqLnREvCX x-ms-office365-filtering-correlation-id: 02d29e5b-0ef3-4711-71b4-08d3bfc626f3 x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(1601124038)(1601125047); SRVR:VE1EUR01HT253; x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(432015012)(102415321)(82015046); SRVR:VE1EUR01HT253; BCL:0; PCL:0; RULEID:; SRVR:VE1EUR01HT253; x-forefront-prvs: 00286C0CA6 spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Aug 2016 19:56:57.7439 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Internet X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1EUR01HT253 Hi! As described in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71083 we generate unaligned accesses because tree-predcom rewrites bitfield and packed accesses in a way that looses the proper alignment information. The attached patch fixes this by re-using the gimple memory expression from the original access. I was not sure, if any non-constant array references would be valid at where the ref_at_iteration is expanded, I set these to the array-lower-bound, as the DR_OFFSET contains the folded value of all non-constant array references. The patch compensates for the constant offset from the outer reference to the inner reference, and replaces the inner reference instead of the outer reference. Boot-strapped and reg-tested on x86_64-linux-gnu. OK for trunk? Thanks Bernd. 2016-08-08 Bernd Edlinger PR tree-optimization/71083 * tree-predcom.c (ref_at_iteration): Rewrite the inner reference. testsuite: 2016-08-08 Bernd Edlinger PR tree-optimization/71083 * gcc.c-torture/execute/pr71083.c: New test. Index: gcc/tree-predcom.c =================================================================== --- gcc/tree-predcom.c (revision 239193) +++ gcc/tree-predcom.c (working copy) @@ -1364,11 +1364,33 @@ replace_ref_with (gimple *stmt, tree new_tree, boo /* Returns a memory reference to DR in the ITER-th iteration of the loop it was analyzed in. Append init stmts to STMTS. */ -static tree +static tree ref_at_iteration (data_reference_p dr, int iter, gimple_seq *stmts) { tree off = DR_OFFSET (dr); tree coff = DR_INIT (dr); + tree ref = unshare_expr (DR_REF (dr)); + tree *exp = &ref; + while (handled_component_p (*exp)) + { + switch (TREE_CODE (*exp)) + { + case ARRAY_REF: + case ARRAY_RANGE_REF: + if (!cst_and_fits_in_hwi (TREE_OPERAND (*exp, 1))) + TREE_OPERAND (*exp, 1) = array_ref_low_bound (*exp); + break; + default: + break; + } + exp = &TREE_OPERAND (*exp, 0); + } + HOST_WIDE_INT bitsize, bitpos; + tree offset; + machine_mode mode; + int unsignedp, reversep, volatilep = 0; + get_inner_reference (ref, &bitsize, &bitpos, &offset, &mode, + &unsignedp, &reversep, &volatilep); if (iter == 0) ; else if (TREE_CODE (DR_STEP (dr)) == INTEGER_CST) @@ -1377,27 +1399,16 @@ ref_at_iteration (data_reference_p dr, int iter, g else off = size_binop (PLUS_EXPR, off, size_binop (MULT_EXPR, DR_STEP (dr), ssize_int (iter))); + if (offset) + off = size_binop (MINUS_EXPR, off, offset); + if (bitpos) + coff = size_binop (MINUS_EXPR, coff, ssize_int (bitpos / BITS_PER_UNIT)); tree addr = fold_build_pointer_plus (DR_BASE_ADDRESS (dr), off); addr = force_gimple_operand_1 (unshare_expr (addr), stmts, is_gimple_mem_ref_addr, NULL_TREE); - tree alias_ptr = fold_convert (reference_alias_ptr_type (DR_REF (dr)), coff); - /* While data-ref analysis punts on bit offsets it still handles - bitfield accesses at byte boundaries. Cope with that. Note that - we cannot simply re-apply the outer COMPONENT_REF because the - byte-granular portion of it is already applied via DR_INIT and - DR_OFFSET, so simply build a BIT_FIELD_REF knowing that the bits - start at offset zero. */ - if (TREE_CODE (DR_REF (dr)) == COMPONENT_REF - && DECL_BIT_FIELD (TREE_OPERAND (DR_REF (dr), 1))) - { - tree field = TREE_OPERAND (DR_REF (dr), 1); - return build3 (BIT_FIELD_REF, TREE_TYPE (DR_REF (dr)), - build2 (MEM_REF, DECL_BIT_FIELD_TYPE (field), - addr, alias_ptr), - DECL_SIZE (field), bitsize_zero_node); - } - else - return fold_build2 (MEM_REF, TREE_TYPE (DR_REF (dr)), addr, alias_ptr); + tree alias_ptr = fold_convert (reference_alias_ptr_type (*exp), coff); + *exp = fold_build2 (MEM_REF, TREE_TYPE (*exp), addr, alias_ptr); + return ref; } /* Get the initialization expression for the INDEX-th temporary variable Index: gcc/testsuite/gcc.c-torture/execute/pr71083.c =================================================================== --- gcc/testsuite/gcc.c-torture/execute/pr71083.c (revision 0) +++ gcc/testsuite/gcc.c-torture/execute/pr71083.c (working copy) @@ -0,0 +1,43 @@ +struct lock_chain { + unsigned int irq_context: 2, + depth: 6, + base: 24; +}; + +__attribute__((noinline, noclone)) +struct lock_chain * foo (struct lock_chain *chain) +{ + int i; + for (i = 0; i < 100; i++) + { + chain[i+1].base = chain[i].base; + } + return chain; +} + +struct lock_chain1 { + char x; + unsigned short base; +} __attribute__((packed)); + +__attribute__((noinline, noclone)) +struct lock_chain1 * bar (struct lock_chain1 *chain) +{ + int i; + for (i = 0; i < 100; i++) + { + chain[i+1].base = chain[i].base; + } + return chain; +} + +struct lock_chain test [101]; +struct lock_chain1 test1 [101]; + +int +main () +{ + foo (test); + bar (test1); + return 0; +}