From patchwork Mon Feb 22 13:37:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleg Endo X-Patchwork-Id: 586167 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 A4148140BAC for ; Tue, 23 Feb 2016 00:37:30 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=IgNsRPZP; 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 :message-id:subject:from:to:date:content-type:mime-version; q= dns; s=default; b=RdDa2v2DIs9tNWbdoob69OQMtrlRQA/iXhEhyvUT7jYbLH i+b7Kz1EC3IZTlQQmOw+MT6iO91bLrtAAdSkhtLaej1ZMitz8pfF8N1JSp/tqSUk /9aACW/pHTfv/3FPoB/b5jGOdtNufqVsy5Av3IDOJA1pZFkK4s17sS6ZoYgfg= 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:subject:from:to:date:content-type:mime-version; s= default; bh=TMlq1x6wQi7U0F/l6DBCDsHLhRQ=; b=IgNsRPZPrycakjQZhejH mc2dNfkgP0dfcykR6Di9Zxk0vJjs6wwEC52S890fX5/u57kIb+ojG7Dkd+hGiKr4 iaVpmG90cRLCvjK7eTwVbH1VQ/ZOuWr2n1YVcDTcgcLawfsyx3o58bMyMUsYNMdh kLv0Vyut2cqsYkgyrLCcsxA= Received: (qmail 130706 invoked by alias); 22 Feb 2016 13:37:23 -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 130696 invoked by uid 89); 22 Feb 2016 13:37:22 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.5 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD autolearn=no version=3.3.2 spammy=sequences, H*MI:online, holds, Hx-languages-length:6725 X-HELO: mailout07.t-online.de Received: from mailout07.t-online.de (HELO mailout07.t-online.de) (194.25.134.83) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 22 Feb 2016 13:37:20 +0000 Received: from fwd13.aul.t-online.de (fwd13.aul.t-online.de [172.20.27.62]) by mailout07.t-online.de (Postfix) with SMTP id 5412B4C6C4A for ; Mon, 22 Feb 2016 14:37:15 +0100 (CET) Received: from [192.168.0.16] (ZGW31oZCQhMOkQYsgLA94q074Ab3skiPL1aiK3zYJR2eXcySdZ6H7c4hK0LKpEnQJm@[115.165.93.200]) by fwd13.t-online.de with (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 encrypted) esmtp id 1aXqff-2JykgC0; Mon, 22 Feb 2016 14:37:03 +0100 Message-ID: <1456148220.14977.11.camel@t-online.de> Subject: [SH][committed] Fix PR 69806 From: Oleg Endo To: gcc-patches Date: Mon, 22 Feb 2016 22:37:00 +0900 Mime-Version: 1.0 X-IsSubscribed: yes Hi, The attached patch fixes PR 69806. Tested on sh-elf with make -k check RUNTESTFLAGS="--target_board=sh-sim\{-m2/-ml,-m2/-mb, -m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}" Committed as r233601. Cheers, Oleg gcc/ChangeLog PR target/69806 PR target/54089 * config/sh/sh.c (sh_lshrsi_clobbers_t_reg_p, sh_dynamicalize_shift_p): Handle negative shift counts. * config/sh/sh.md (ashlsi3, lshrsi3_n, lshrsi3_n_clobbers_t): Don't use force_reg on the shift constant. (lshrsi3): Likewise. Expand into lshrsi3_n* instead of lshrsi3_d. (lshrsi3_d): Handle negative shift counts. gcc/testsuite/ChangeLog PR target/69806 PR target/54089 * gcc.target/sh/pr54089-10.c: New. Index: gcc/config/sh/sh.c =================================================================== --- gcc/config/sh/sh.c (revision 233581) +++ gcc/config/sh/sh.c (working copy) @@ -3259,7 +3259,8 @@ { gcc_assert (CONST_INT_P (shift_amount)); - const int shift_amount_i = INTVAL (shift_amount) & 31; + /* For right shifts the constant might be negative. */ + const int shift_amount_i = std::abs (INTVAL (shift_amount)) & 31; /* Special case for shift count of 31: use shll-movt sequence. */ if (shift_amount_i == 31) @@ -3278,7 +3279,8 @@ { gcc_assert (CONST_INT_P (count)); - const int shift_amount_i = INTVAL (count) & 31; + /* For right shifts the constant might be negative. */ + const int shift_amount_i = std::abs (INTVAL (count)) & 31; int insn_count; /* For left and right shifts, there are shorter 2 insn sequences for Index: gcc/config/sh/sh.md =================================================================== --- gcc/config/sh/sh.md (revision 233581) +++ gcc/config/sh/sh.md (working copy) @@ -5011,7 +5011,10 @@ } if (TARGET_DYNSHIFT && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2])) - operands[2] = force_reg (SImode, operands[2]); + { + /* Don't force the constant into a reg yet. Some other optimizations + might not see through the reg that holds the shift count. */ + } /* If the ashlsi3_* insn is going to clobber the T_REG it must be expanded here. */ @@ -5567,9 +5570,12 @@ if (TARGET_DYNSHIFT && CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2])) { - rtx neg_count = force_reg (SImode, - gen_int_mode (- INTVAL (operands[2]), SImode)); - emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count)); + /* Don't force the constant into a reg yet. Some other optimizations + might not see through the reg that holds the shift count. */ + if (sh_lshrsi_clobbers_t_reg_p (operands[2])) + emit_insn (gen_lshrsi3_n_clobbers_t (operands[0], operands[1], operands[2])); + else + emit_insn (gen_lshrsi3_n (operands[0], operands[1], operands[2])); DONE; } @@ -5621,6 +5627,10 @@ && ! sh_lshrsi_clobbers_t_reg_p (operands[2])" [(const_int 0)] { + /* The shift count const_int is a negative value for all dynamic + right shift insns. */ + operands[2] = GEN_INT (- INTVAL (operands[2])); + if (satisfies_constraint_P27 (operands[2])) { /* This will not be done for a shift amount of 1, because it would @@ -5679,8 +5689,7 @@ { /* If this pattern was picked and dynamic shifts are supported, switch to dynamic shift pattern before reload. */ - operands[2] = force_reg (SImode, - gen_int_mode (- INTVAL (operands[2]), SImode)); + operands[2] = GEN_INT (- INTVAL (operands[2])); emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2])); } else @@ -5711,8 +5720,7 @@ { /* If this pattern was picked and dynamic shifts are supported, switch to dynamic shift pattern before reload. */ - operands[2] = force_reg (SImode, - gen_int_mode (- INTVAL (operands[2]), SImode)); + operands[2] = GEN_INT (- INTVAL (operands[2])); emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2])); } else Index: gcc/testsuite/gcc.target/sh/pr54089-10.c =================================================================== --- gcc/testsuite/gcc.target/sh/pr54089-10.c (revision 0) +++ gcc/testsuite/gcc.target/sh/pr54089-10.c (working copy) @@ -0,0 +1,153 @@ +/* Check that there are no redundant zero extensions around logical right + shifts. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-final { scan-assembler-times "extu" 20 } } */ + +/* { dg-final { scan-assembler-times "shll" 2 { target { "! sh2a" && has_dyn_shift } } } } */ +/* { dg-final { scan-assembler-times "shll" 3 { target { "! sh2a" && "! has_dyn_shift" } } } } */ +/* { dg-final { scan-assembler-times "movt" 2 { target { ! sh2a } } } } */ + +/* { dg-final { scan-assembler-times "bld" 1 { target { sh2a } } } } */ +/* { dg-final { scan-assembler-times "movt" 1 { target { sh2a } } } } */ +/* { dg-final { scan-assembler-times "movrt" 1 { target { sh2a } } } } */ +/* { dg-final { scan-assembler-times "cmp/pz" 1 { target { sh2a } } } } */ + +/* { dg-final { scan-assembler-times "shld" 9 { target { has_dyn_shift } } } } */ + +void +test_0 (unsigned char* x, unsigned int* y) +{ + y[0] = x[1] >> 1; +} + +void +test_1 (unsigned char* x, unsigned int* y) +{ + y[0] = x[1] >> 2; +} + +void +test_2 (unsigned char* x, unsigned int* y) +{ + y[0] = x[1] >> 3; +} + +void +test_3 (unsigned char* x, unsigned int* y) +{ + y[0] = x[1] >> 4; +} + +void +test_4 (unsigned char* x, unsigned int* y) +{ + y[0] = x[1] >> 5; +} + +void +test_5 (unsigned char* x, unsigned int* y) +{ + y[0] = x[1] >> 6; +} + +void +test_6 (unsigned char* x, unsigned int* y) +{ + /* non-SH2A: shll, movt + SH2A: bld, movt */ + y[0] = x[1] >> 7; +} + + +void +test_100 (unsigned short* x, unsigned int* y) +{ + y[0] = x[1] >> 1; +} + +void +test_101 (unsigned short* x, unsigned int* y) +{ + y[0] = x[1] >> 2; +} + +void +test_102 (unsigned short* x, unsigned int* y) +{ + y[0] = x[1] >> 3; +} + +void +test_103 (unsigned short* x, unsigned int* y) +{ + y[0] = x[1] >> 4; +} + +void +test_104 (unsigned short* x, unsigned int* y) +{ + y[0] = x[1] >> 5; +} + +void +test_105 (unsigned short* x, unsigned int* y) +{ + y[0] = x[1] >> 6; +} + +void +test_106 (unsigned short* x, unsigned int* y) +{ + y[0] = x[1] >> 7; +} + +void +test_107 (unsigned short* x, unsigned int* y) +{ + y[0] = x[1] >> 8; +} + +void +test_108 (unsigned short* x, unsigned int* y) +{ + y[0] = x[1] >> 9; +} + +void +test_109 (unsigned short* x, unsigned int* y) +{ + y[0] = x[1] >> 10; +} + +void +test_110 (unsigned short* x, unsigned int* y) +{ + y[0] = x[1] >> 11; +} + +void +test_111 (unsigned short* x, unsigned int* y) +{ + y[0] = x[1] >> 12; +} + +void +test_112 (unsigned short* x, unsigned int* y) +{ + y[0] = x[1] >> 13; +} + +void +test_113 (unsigned short* x, unsigned int* y) +{ + y[0] = x[1] >> 14; +} + +void +test_114 (unsigned short* x, unsigned int* y) +{ + /* non-SH2A: shll, movt + SH2A: cmp/pz, movrt */ + y[0] = x[1] >> 15; +}