diff options
author | Ramana Radhakrishnan <ramana@gcc.gnu.org> | 2012-05-22 09:06:55 +0000 |
---|---|---|
committer | Ramana Radhakrishnan <ramana@gcc.gnu.org> | 2012-05-22 09:06:55 +0000 |
commit | 95ffee1fce520423f8a3725649c659e247ccfe12 (patch) | |
tree | de16055277b7b505489b96f8ea473e055fc1ec5f | |
parent | 7c2dbbdc486d717a674a7ec693236b91aff280cd (diff) | |
download | gcc-95ffee1fce520423f8a3725649c659e247ccfe12.zip gcc-95ffee1fce520423f8a3725649c659e247ccfe12.tar.gz gcc-95ffee1fce520423f8a3725649c659e247ccfe12.tar.bz2 |
re PR target/53334 (ICE in extract_insn, at recog.c:2131)
Fix PR target/53334
2012-05-22 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
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.
From-SVN: r187761
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/config/arm/arm-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 50 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 89 |
4 files changed, 90 insertions, 65 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3ff410a..496bb5f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,7 +1,20 @@ +2012-05-22 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org> + + 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. + 2012-05-22 Dimitrios Apostolou <jimis@gmx.net> * df-scan.c (df_scan_alloc): Round up allocation pools size, reduce - the mw_reg_pool size. + the mw_reg_pool size. 2012-05-22 Paolo Bonzini <bonzini@gnu.org> diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index b338470..4e6d7bb 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -248,6 +248,7 @@ extern int vfp3_const_double_for_fract_bits (rtx); 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); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 3ad4c75..7a98197 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -26185,4 +26185,54 @@ arm_emit_coreregs_64bit_shift (enum rtx_code code, rtx out, rtx in, #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" diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index bc97a4a..bbf6380 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -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; - - /* 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]); + 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); @@ -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); |