From patchwork Tue May 22 09:07:10 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ramana Radhakrishnan X-Patchwork-Id: 160570 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]) by ozlabs.org (Postfix) with SMTP id EA121B6EE6 for ; Tue, 22 May 2012 19:07:37 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1338282458; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:Received:Date:Message-ID:Subject:From:To: Cc:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=t7QoJ74 YEjNMZilij3UVs99xnig=; b=YndJeuMhwuB2ZHSJC1IqhxrG8z+NmEnAxFcTNRC y8pGsVHkRhkaq2jtazzYJhrgVk0lnSHfVFT+qIZmIUiRh7JbDuM3e9+5NyqatzVS BWxi6naDhlVVylMpjs/HBIQoIiCO5jXmF2DE3TIF/hj1sKv1PIYAZ1Me0krpA0pj sf6A= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:X-Google-DKIM-Signature:MIME-Version:Received:Received:Date:Message-ID:Subject:From:To:Cc:Content-Type:X-Gm-Message-State:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=HSeB4ZaY1O2UdQbZulv8Jj3yGQToslwh2bFbmZIEOi75EDUoi3QGussZPgaOtW fcCl6C4sLIXSWXg4B/tIHi19kS7Pz7mVRkM0QuoSqHFJddrNqF4suT6SsjAXo3eu dC7Raveo0l3rpmkQfUP/wRZasv0x6MtBd5pNDoms7oOVI=; Received: (qmail 25315 invoked by alias); 22 May 2012 09:07:27 -0000 Received: (qmail 25298 invoked by uid 22791); 22 May 2012 09:07:25 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE X-Spam-Check-By: sourceware.org Received: from mail-qc0-f175.google.com (HELO mail-qc0-f175.google.com) (209.85.216.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 22 May 2012 09:07:11 +0000 Received: by qcso7 with SMTP id o7so3993095qcs.20 for ; Tue, 22 May 2012 02:07:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:date:message-id:subject:from:to:cc:content-type :x-gm-message-state; bh=ULKKNrLNeuEszO9PxkFjCwuwF7t79P95hb7WPsNlNKU=; b=HPmO6YHTY71S5VKr6e+pSy/AflDCST7SZk/yECi4qDkbDCAcTvMEkCQkv/FLjf3CSn SDDy8QP/NvFDGw2sFtpOaJCWpDSW37wSCSd2v73gWZSXK1a75wumaMSnOZnT7jOg76fB Ofdo1roIS+AWyRFzMx2gxaKEdNhFldELl8cfy/RlacWQa3xRM3s9urW+SDsuO3lFo5kw aYhymogzeszX089BDJF1k7SP0KTQamzJTAg8KQWwh44jBIJPO0rcIwp250BEDPfCp7NV QggD9x1tnTM4jVIWJdYGAMZhjnDPOkQu4bB5D7On7++o87WUAGg/1Uc248u1KsOKQl8Q t4Jw== MIME-Version: 1.0 Received: by 10.229.111.208 with SMTP id t16mr11586635qcp.108.1337677630343; Tue, 22 May 2012 02:07:10 -0700 (PDT) Received: by 10.224.137.73 with HTTP; Tue, 22 May 2012 02:07:10 -0700 (PDT) Date: Tue, 22 May 2012 10:07:10 +0100 Message-ID: Subject: [Patch ARM] Fix PR target/53334 From: Ramana Radhakrishnan To: gcc-patches Cc: Patch Tracking X-Gm-Message-State: ALoCoQnz8ZWkhGK1LbNNGagCnUu8J9i3H+9SQu1aGE8B5Hiihu2JLa3XGlJgsGvPhI9mhVsFntec X-IsSubscribed: yes 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 Hi, This appears to fix the problem with PR53334 and deals with the fallout of not validating properly operands to movsicc. In addition I took the opportunity of merging all the other places where we validized such transforms into a single function and dealt with the fallout accordingly. It also helps some of the tests in the testsuite which were previously ICE'ing as a result of the previous patch to now get fixed up. Tested cross with trunk for arm-linux-gnueabi with armv7-a (arm/thumb), armv5t multilibs for C,C++, Committed. regards. Ramana 2012-05-22 Ramana Radhakrishnan PR target/53334 * config/arm/arm-protos.h (arm_validize_comparison): Declare. * config/arm/arm.c (arm_validize_comparison): Define. * config/arm/arm.md ("cbranchsi4"): Cleanup expansion and use arm_validize_comparison. ("cbranchdi4"): Likewise. ("cstoredi4"): Likewise. ("movsicc"): Likewise. ("movsfcc"): Likewise. ("movdfcc"): Likewise. Index: gcc/config/arm/arm.c =================================================================== --- gcc/config/arm/arm.c (revision 187760) +++ gcc/config/arm/arm.c (working copy) @@ -26185,4 +26185,54 @@ #undef BRANCH } + +/* Returns true if a valid comparison operation and makes + the operands in a form that is valid. */ +bool +arm_validize_comparison (rtx *comparison, rtx * op1, rtx * op2) +{ + enum rtx_code code = GET_CODE (*comparison); + enum rtx_code canonical_code; + enum machine_mode mode = (GET_MODE (*op1) == VOIDmode) + ? GET_MODE (*op2) : GET_MODE (*op1); + + gcc_assert (GET_MODE (*op1) != VOIDmode || GET_MODE (*op2) != VOIDmode); + + if (code == UNEQ || code == LTGT) + return false; + + canonical_code = arm_canonicalize_comparison (code, op1, op2); + PUT_CODE (*comparison, canonical_code); + + switch (mode) + { + case SImode: + if (!arm_add_operand (*op1, mode)) + *op1 = force_reg (mode, *op1); + if (!arm_add_operand (*op2, mode)) + *op2 = force_reg (mode, *op2); + return true; + + case DImode: + if (!cmpdi_operand (*op1, mode)) + *op1 = force_reg (mode, *op1); + if (!cmpdi_operand (*op2, mode)) + *op2 = force_reg (mode, *op2); + return true; + + case SFmode: + case DFmode: + if (!arm_float_compare_operand (*op1, mode)) + *op1 = force_reg (mode, *op1); + if (!arm_float_compare_operand (*op2, mode)) + *op2 = force_reg (mode, *op2); + return true; + default: + break; + } + + return false; + +} + #include "gt-arm.h" Index: gcc/config/arm/arm-protos.h =================================================================== --- gcc/config/arm/arm-protos.h (revision 187760) +++ gcc/config/arm/arm-protos.h (working copy) @@ -248,6 +248,7 @@ extern void arm_emit_coreregs_64bit_shift (enum rtx_code, rtx, rtx, rtx, rtx, rtx); +extern bool arm_validize_comparison (rtx *, rtx *, rtx *); #endif /* RTX_CODE */ extern void arm_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel); Index: gcc/config/arm/arm.md =================================================================== --- gcc/config/arm/arm.md (revision 187760) +++ gcc/config/arm/arm.md (working copy) @@ -6977,12 +6977,12 @@ (match_operand:SI 2 "nonmemory_operand" "")]) (label_ref (match_operand 3 "" "")) (pc)))] - "TARGET_THUMB1 || TARGET_32BIT" + "TARGET_EITHER" " if (!TARGET_THUMB1) { - if (!arm_add_operand (operands[2], SImode)) - operands[2] = force_reg (SImode, operands[2]); + if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2])) + FAIL; emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], operands[3])); DONE; @@ -7054,33 +7054,13 @@ (pc)))] "TARGET_32BIT" "{ - rtx swap = NULL_RTX; - enum rtx_code code = GET_CODE (operands[0]); - /* We should not have two constants. */ gcc_assert (GET_MODE (operands[1]) == DImode || GET_MODE (operands[2]) == DImode); - /* Flip unimplemented DImode comparisons to a form that - arm_gen_compare_reg can handle. */ - switch (code) - { - case GT: - swap = gen_rtx_LT (VOIDmode, operands[2], operands[1]); break; - case LE: - swap = gen_rtx_GE (VOIDmode, operands[2], operands[1]); break; - case GTU: - swap = gen_rtx_LTU (VOIDmode, operands[2], operands[1]); break; - case LEU: - swap = gen_rtx_GEU (VOIDmode, operands[2], operands[1]); break; - default: - break; - } - if (swap) - emit_jump_insn (gen_cbranch_cc (swap, operands[2], operands[1], - operands[3])); - else - emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], + if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2])) + FAIL; + emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], operands[3])); DONE; }" @@ -8065,33 +8045,15 @@ (match_operand:DI 3 "cmpdi_operand" "")]))] "TARGET_32BIT" "{ - rtx swap = NULL_RTX; - enum rtx_code code = GET_CODE (operands[1]); - /* We should not have two constants. */ gcc_assert (GET_MODE (operands[2]) == DImode || GET_MODE (operands[3]) == DImode); - /* Flip unimplemented DImode comparisons to a form that - arm_gen_compare_reg can handle. */ - switch (code) - { - case GT: - swap = gen_rtx_LT (VOIDmode, operands[3], operands[2]); break; - case LE: - swap = gen_rtx_GE (VOIDmode, operands[3], operands[2]); break; - case GTU: - swap = gen_rtx_LTU (VOIDmode, operands[3], operands[2]); break; - case LEU: - swap = gen_rtx_GEU (VOIDmode, operands[3], operands[2]); break; - default: - break; - } - if (swap) - emit_insn (gen_cstore_cc (operands[0], swap, operands[3], - operands[2])); - else - emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2], + if (!arm_validize_comparison (&operands[1], + &operands[2], + &operands[3])) + FAIL; + emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2], operands[3])); DONE; }" @@ -8186,12 +8148,14 @@ "TARGET_32BIT" " { - enum rtx_code code = GET_CODE (operands[1]); + enum rtx_code code; rtx ccreg; - if (code == UNEQ || code == LTGT) + if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), + &XEXP (operands[1], 1))) FAIL; - + + code = GET_CODE (operands[1]); ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), XEXP (operands[1], 1), NULL_RTX); operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); @@ -8202,22 +8166,18 @@ [(set (match_operand:SF 0 "s_register_operand" "") (if_then_else:SF (match_operand 1 "expandable_comparison_operator" "") (match_operand:SF 2 "s_register_operand" "") - (match_operand:SF 3 "nonmemory_operand" "")))] + (match_operand:SF 3 "arm_float_add_operand" "")))] "TARGET_32BIT && TARGET_HARD_FLOAT" " { enum rtx_code code = GET_CODE (operands[1]); rtx ccreg; - if (code == UNEQ || code == LTGT) - FAIL; + if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), + &XEXP (operands[1], 1))) + FAIL; - /* When compiling for SOFT_FLOAT, ensure both arms are in registers. - Otherwise, ensure it is a valid FP add operand */ - if ((!(TARGET_HARD_FLOAT && TARGET_FPA)) - || (!arm_float_add_operand (operands[3], SFmode))) - operands[3] = force_reg (SFmode, operands[3]); - + code = GET_CODE (operands[1]); ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), XEXP (operands[1], 1), NULL_RTX); operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); @@ -8235,9 +8195,10 @@ enum rtx_code code = GET_CODE (operands[1]); rtx ccreg; - if (code == UNEQ || code == LTGT) - FAIL; - + if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), + &XEXP (operands[1], 1))) + FAIL; + code = GET_CODE (operands[1]); ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), XEXP (operands[1], 1), NULL_RTX); operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);