From patchwork Thu May 23 08:17:36 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Greenhalgh X-Patchwork-Id: 245837 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 41AA32C00A1 for ; Thu, 23 May 2013 18:17:56 +1000 (EST) 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:mime-version:content-type; q=dns; s=default; b=EP5sEVc2HSHA8yzCrclx4hznlgRNgVIAoWPRbQAlA6LCQA23H8 F9PkMm7XPOEau5XT42RuSHSumyFb7BNCgql/Rk8h5mMvfnq7qXakvTxdcva8qHlx n8a6+okBE9DywZPby79J8d6U8RNGwQXvRrkaaqsGZGQoMDpPZdd78Hslc= 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:mime-version:content-type; s= default; bh=I+NKHZmDswMZv0zTX4y5S8xanRE=; b=HhBbm+etO8fz1TeJ206L 4KSMDbcxrqNgpn1vHPdGdLoIO+38QwXW2H55LfcV3MUDERKospWIQal7SbOwtrk6 jh/j+O6Y3SYGwWFBkjm1j+sa4cZr4xUiG+Nf7eWz+GkMHGMg3ZW6to/W2KnirW50 NjXLLLimt5q2gJjGjBbcKPA= Received: (qmail 32697 invoked by alias); 23 May 2013 08:17:49 -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 32684 invoked by uid 89); 23 May 2013 08:17:48 -0000 X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.1 Received: from service87.mimecast.com (HELO service87.mimecast.com) (91.220.42.44) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Thu, 23 May 2013 08:17:46 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Thu, 23 May 2013 09:17:43 +0100 Received: from e106375-lin.cambridge.arm.com ([10.1.255.212]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.0); Thu, 23 May 2013 09:17:41 +0100 From: James Greenhalgh To: gcc-patches@gcc.gnu.org Cc: marcus.shawcroft@arm.com Subject: [AArch64] Fix possible wrong code generation when comparing DImode values. Date: Thu, 23 May 2013 09:17:36 +0100 Message-Id: <1369297056-11890-1-git-send-email-james.greenhalgh@arm.com> MIME-Version: 1.0 X-MC-Unique: 113052309174305701 X-Virus-Found: No Hi, With the aarch64_cmdi patterns a bug was introduced. While the unsplit versions of these patterns, which operate in the SIMD register set, do not clobber CC_REGNUM, the split versions, which operate in the general purpose register set, do clobber CC_REGNUM. This causes a problem if scheduling rearranges the unsplit version of these instructions. For example, if we have: aarch64_cmeqdi_unsplit set_cc_flags jump Then we could schedule as set_cc_flags aarch64_cmeqdi_unsplit jump Because the unsplit version does not clobber CC_REGNUM. If we now decide to split we get: set_cc_flags aarch64_cmeqdi_set_cc_flags aarch64_cmeqdi_use_cc_flags jump And the jump uses the wrong value for cc_flags. We fix this problem by adding the clobber of CC_REGNUM to the aarch64_cmdi patterns. This may restrict the scheduling opportunities available, but should prevent incorrect code generation. Tested on aarch64-none-linux-gnu, aarch64-none-elf with no regressions. The bug manifest itself in the libstdc++ testsuite, so I've double checked there to ensure that the bug has cleared. Thanks, James --- gcc/ 2013-05-17 James Greenhalgh * config/aarch64/aarch64-simd.md (aarch64_cmdi): Add clobber of CC_REGNUM to unsplit pattern. diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 9069a73..f91cf81 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -3280,7 +3280,8 @@ (COMPARISONS:DI (match_operand:DI 1 "register_operand" "w,w,r") (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,ZDz,r") - )))] + ))) + (clobber (reg:CC CC_REGNUM))] "TARGET_SIMD" "@ cm\t%d0, %d, %d @@ -3291,15 +3292,7 @@ happening in the 'w' constraint cases. */ && GP_REGNUM_P (REGNO (operands[0])) && GP_REGNUM_P (REGNO (operands[1]))" - [(set (reg:CC CC_REGNUM) - (compare:CC - (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (neg:DI - (COMPARISONS:DI - (match_operand 3 "cc_register" "") - (const_int 0))))] + [(const_int 0)] { enum machine_mode mode = SELECT_CC_MODE (, operands[1], operands[2]); rtx cc_reg = aarch64_gen_compare_reg (, operands[1], operands[2]); @@ -3332,7 +3325,8 @@ (UCOMPARISONS:DI (match_operand:DI 1 "register_operand" "w,r") (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,r") - )))] + ))) + (clobber (reg:CC CC_REGNUM))] "TARGET_SIMD" "@ cm\t%d0, %d, %d @@ -3342,17 +3336,9 @@ happening in the 'w' constraint cases. */ && GP_REGNUM_P (REGNO (operands[0])) && GP_REGNUM_P (REGNO (operands[1]))" - [(set (reg:CC CC_REGNUM) - (compare:CC - (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (neg:DI - (UCOMPARISONS:DI - (match_operand 3 "cc_register" "") - (const_int 0))))] + [(const_int 0)] { - enum machine_mode mode = SELECT_CC_MODE (, operands[1], operands[2]); + enum machine_mode mode = CCmode; rtx cc_reg = aarch64_gen_compare_reg (, operands[1], operands[2]); rtx comparison = gen_rtx_ (mode, operands[1], operands[2]); emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg)); @@ -3385,7 +3371,8 @@ (and:DI (match_operand:DI 1 "register_operand" "w,r") (match_operand:DI 2 "register_operand" "w,r")) - (const_int 0))))] + (const_int 0)))) + (clobber (reg:CC CC_REGNUM))] "TARGET_SIMD" "@ cmtst\t%d0, %d1, %d2 @@ -3395,16 +3382,7 @@ happening in the 'w' constraint cases. */ && GP_REGNUM_P (REGNO (operands[0])) && GP_REGNUM_P (REGNO (operands[1]))" - [(set (reg:CC_NZ CC_REGNUM) - (compare:CC_NZ - (and:DI (match_dup 1) - (match_dup 2)) - (const_int 0))) - (set (match_dup 0) - (neg:DI - (ne:DI - (match_operand 3 "cc_register" "") - (const_int 0))))] + [(const_int 0)] { rtx and_tree = gen_rtx_AND (DImode, operands[1], operands[2]); enum machine_mode mode = SELECT_CC_MODE (NE, and_tree, const0_rtx);