From patchwork Fri Jul 28 11:26:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 794806 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-459252-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="MuWiZZ+Y"; 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 3xJml36sGnz9s5L for ; Fri, 28 Jul 2017 21:26:38 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; q=dns; s=default; b=ITzfXCdmeqqJcldj Ch8vsxcV0RWXD5UahqXVH4X6oc5+6gmDh9PWLBoRpQtMuZ5QtPqDe6AhTzTUkLpt 78dg/YRgKBsIbJtNZnipJ+uUZ7IdPMi0a4IjejQbEEiv01Iib49DEGX9bdHt/jxo rgCLN4Jgn9cPGn6TshCJ4NcaVQA= 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:date :from:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; s=default; bh=vjS262vJ+kdMcPI3tz46W3 R3USE=; b=MuWiZZ+YX6Kp0gXGOaTNdQYx22EdlkM/y53KQJ/0/cuO+gS3pQGAvP 6TnNGP3A1s/OT3bUlRo12a0SEGUZwa6FU+52eAusLW8swoFXVUZlZd6AaG4Wqpox N1KIp10VYHSBI8NRHSWRz3QMjDfrZMsKJGspyI1iR5UjldFzjLweo= Received: (qmail 127303 invoked by alias); 28 Jul 2017 11:26:24 -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 126793 invoked by uid 89); 28 Jul 2017 11:26:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=36927 X-HELO: mx1.suse.de Received: from mx2.suse.de (HELO mx1.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 28 Jul 2017 11:26:21 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 5F238ABBF; Fri, 28 Jul 2017 11:26:19 +0000 (UTC) Date: Fri, 28 Jul 2017 13:26:19 +0200 (CEST) From: Richard Biener To: Andrew Pinski cc: GCC Patches Subject: Re: [PATCH][2/2] Fix PR81502 In-Reply-To: Message-ID: References: User-Agent: Alpine 2.20 (LSU 67 2015-01-07) MIME-Version: 1.0 On Thu, 27 Jul 2017, Andrew Pinski wrote: > On Thu, Jul 27, 2017 at 6:50 AM, Richard Biener wrote: > > > > I am testing the following additional pattern for match.pd to fix > > PR81502 resulting in the desired optimization to > > > > bar: > > .LFB526: > > .cfi_startproc > > movl %edi, %eax > > ret > > > > the pattern optimizes a BIT_FIELD_REF on a BIT_INSERT_EXPR by > > either extracting from the destination or the inserted value. > > Note this optimization pattern was on my list to implement for > bit-field optimizations after lowering. Had to do some adjustments and ended up enforcing bitsizetype operands for BIT_INSERT_EXPR and BIT_FIELD_REF. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2017-07-28 Richard Biener PR tree-optimization/81502 * match.pd: Add pattern combining BIT_INSERT_EXPR with BIT_FIELD_REF. * tree-cfg.c (verify_expr): Verify types of BIT_FIELD_REF size/pos operands. (verify_gimple_assign_ternary): Likewise for BIT_INSERT_EXPR pos. * gimple-fold.c (maybe_canonicalize_mem_ref_addr): Use bitsizetype for BIT_FIELD_REF args. * fold-const.c (make_bit_field_ref): Likewise. * tree-vect-stmts.c (vectorizable_simd_clone_call): Likewise. * gcc.target/i386/pr81502.c: New testcase. Index: gcc/testsuite/gcc.target/i386/pr81502.c =================================================================== *** gcc/testsuite/gcc.target/i386/pr81502.c (nonexistent) --- gcc/testsuite/gcc.target/i386/pr81502.c (working copy) *************** *** 0 **** --- 1,34 ---- + /* { dg-do compile { target lp64 } } */ + /* { dg-options "-O2 -msse2" } */ + + #include + + #define SIZE (sizeof (void *)) + + static int foo(unsigned char (*foo)[SIZE]) + { + __m128i acc = _mm_set_epi32(0, 0, 0, 0); + size_t i = 0; + for(; i + sizeof(__m128i) <= SIZE; i += sizeof(__m128i)) { + __m128i word; + __builtin_memcpy(&word, foo + i, sizeof(__m128i)); + acc = _mm_add_epi32(word, acc); + } + if (i != SIZE) { + __m128i word = _mm_set_epi32(0, 0, 0, 0); + __builtin_memcpy(&word, foo + i, SIZE - i); // (1) + acc = _mm_add_epi32(word, acc); + } + int res; + __builtin_memcpy(&res, &acc, sizeof(res)); + return res; + } + + int bar(void *ptr) + { + unsigned char buf[SIZE]; + __builtin_memcpy(buf, &ptr, SIZE); + return foo((unsigned char(*)[SIZE])buf); + } + + /* { dg-final { scan-assembler-times "mov" 1 } } */ Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 250625) +++ gcc/match.pd (working copy) @@ -4178,3 +4178,25 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) { CONSTRUCTOR_ELT (ctor, idx / k)->value; }) (BIT_FIELD_REF { CONSTRUCTOR_ELT (ctor, idx / k)->value; } @1 { bitsize_int ((idx % k) * width); }))))))))) + +/* Simplify a bit extraction from a bit insertion for the cases with + the inserted element fully covering the extraction or the insertion + not touching the extraction. */ +(simplify + (BIT_FIELD_REF (bit_insert @0 @1 @ipos) @rsize @rpos) + (with + { + unsigned HOST_WIDE_INT isize; + if (INTEGRAL_TYPE_P (TREE_TYPE (@1))) + isize = TYPE_PRECISION (TREE_TYPE (@1)); + else + isize = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (@1))); + } + (switch + (if (wi::leu_p (@ipos, @rpos) + && wi::leu_p (wi::add (@rpos, @rsize), wi::add (@ipos, isize))) + (BIT_FIELD_REF @1 @rsize { wide_int_to_tree (bitsizetype, + wi::sub (@rpos, @ipos)); })) + (if (wi::geu_p (@ipos, wi::add (@rpos, @rsize)) + || wi::geu_p (@rpos, wi::add (@ipos, isize))) + (BIT_FIELD_REF @0 @rsize @rpos))))) Index: gcc/gimple-fold.c =================================================================== --- gcc/gimple-fold.c (revision 250620) +++ gcc/gimple-fold.c (working copy) @@ -4245,7 +4245,7 @@ maybe_canonicalize_mem_ref_addr (tree *t TREE_TYPE (*t), TREE_OPERAND (TREE_OPERAND (*t, 0), 0), TYPE_SIZE (TREE_TYPE (*t)), - wide_int_to_tree (sizetype, idx)); + wide_int_to_tree (bitsizetype, idx)); res = true; } } Index: gcc/tree-cfg.c =================================================================== --- gcc/tree-cfg.c (revision 250620) +++ gcc/tree-cfg.c (working copy) @@ -3053,7 +3053,9 @@ verify_expr (tree *tp, int *walk_subtree tree t1 = TREE_OPERAND (t, 1); tree t2 = TREE_OPERAND (t, 2); if (!tree_fits_uhwi_p (t1) - || !tree_fits_uhwi_p (t2)) + || !tree_fits_uhwi_p (t2) + || !types_compatible_p (bitsizetype, TREE_TYPE (t1)) + || !types_compatible_p (bitsizetype, TREE_TYPE (t2))) { error ("invalid position or size operand to BIT_FIELD_REF"); return t; @@ -4247,6 +4249,7 @@ verify_gimple_assign_ternary (gassign *s return true; } if (! tree_fits_uhwi_p (rhs3) + || ! types_compatible_p (bitsizetype, TREE_TYPE (rhs3)) || ! tree_fits_uhwi_p (TYPE_SIZE (rhs2_type))) { error ("invalid position or size in BIT_INSERT_EXPR"); Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 250625) +++ gcc/fold-const.c (working copy) @@ -3936,7 +3936,7 @@ make_bit_field_ref (location_t loc, tree bftype = build_nonstandard_integer_type (bitsize, 0); result = build3_loc (loc, BIT_FIELD_REF, bftype, inner, - size_int (bitsize), bitsize_int (bitpos)); + bitsize_int (bitsize), bitsize_int (bitpos)); REF_REVERSE_STORAGE_ORDER (result) = reversep; if (bftype != type) Index: gcc/tree-vect-stmts.c =================================================================== --- gcc/tree-vect-stmts.c (revision 250625) +++ gcc/tree-vect-stmts.c (working copy) @@ -3531,7 +3531,7 @@ vectorizable_simd_clone_call (gimple *st arginfo[i].op = vec_oprnd0; vec_oprnd0 = build3 (BIT_FIELD_REF, atype, vec_oprnd0, - size_int (prec), + bitsize_int (prec), bitsize_int ((m & (k - 1)) * prec)); new_stmt = gimple_build_assign (make_ssa_name (atype), @@ -3692,7 +3692,7 @@ vectorizable_simd_clone_call (gimple *st } else t = build3 (BIT_FIELD_REF, vectype, new_temp, - size_int (prec), bitsize_int (l * prec)); + bitsize_int (prec), bitsize_int (l * prec)); new_stmt = gimple_build_assign (make_ssa_name (vectype), t); vect_finish_stmt_generation (stmt, new_stmt, gsi);