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: 8854 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 9355F23F0A for ; Tue, 22 May 2012 09:07:13 +0000 (UTC) Received: from mail-gh0-f180.google.com (mail-gh0-f180.google.com [209.85.160.180]) by fiordland.canonical.com (Postfix) with ESMTP id 47D9FA183CD for ; Tue, 22 May 2012 09:07:13 +0000 (UTC) Received: by ghbz12 with SMTP id z12so906410ghb.11 for ; Tue, 22 May 2012 02:07:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf :mime-version:date:message-id:subject:from:to:cc:content-type :x-gm-message-state; bh=ULKKNrLNeuEszO9PxkFjCwuwF7t79P95hb7WPsNlNKU=; b=Qcgypz4XZ1buffJl7L5NT3h+ebUj+WwR7Rt0CiUwqAu0sOyP3yFyO+yjRgEbucjl6+ kew7ylvMGU1QUIJ/TKb9CazM+tEodS6iT+T7WRW7tz6FTydQC9S61KN3HHEZ52973vbT S9K5slpE/dcXm84H0u7jmOtEMezFVOTeFVttAgyiUtKPioPfE7Ar97VVNX9jT1JLX9az 3KSOQDMYhSC3xgARD2RDk0KiyizBmqFr12UoLfA/nL0RvfckAPk4zgDIxqIVBhd+Eqqb WCCfRFAVAb0M9xRxUvD8YGTTrKtobjAK/lAbP3bFXpitq2ciFFD6SzdM4wbYjkWcS3Rd a38A== Received: by 10.42.56.80 with SMTP id y16mr4812317icg.48.1337677632318; Tue, 22 May 2012 02:07:12 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.35.72 with SMTP id o8csp350367ibd; Tue, 22 May 2012 02:07:11 -0700 (PDT) Received: by 10.229.111.74 with SMTP id r10mr11709863qcp.122.1337677630788; Tue, 22 May 2012 02:07:10 -0700 (PDT) Received: from mail-qc0-f178.google.com (mail-qc0-f178.google.com [209.85.216.178]) by mx.google.com with ESMTPS id gx8si20966928qab.24.2012.05.22.02.07.10 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 22 May 2012 02:07:10 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.216.178 is neither permitted nor denied by best guess record for domain of ramana.radhakrishnan@linaro.org) client-ip=209.85.216.178; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.216.178 is neither permitted nor denied by best guess record for domain of ramana.radhakrishnan@linaro.org) smtp.mail=ramana.radhakrishnan@linaro.org Received: by qcse1 with SMTP id e1so4755245qcs.37 for ; Tue, 22 May 2012 02:07:10 -0700 (PDT) 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: ALoCoQldqI+lrpj3OUHQFquesEKKrAnjpHEXdGfM4K9VezA/rBHVda+SSD91iPQ7Jd1eTHn6cNDx 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);