aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRamana Radhakrishnan <ramana@gcc.gnu.org>2012-05-22 09:06:55 +0000
committerRamana Radhakrishnan <ramana@gcc.gnu.org>2012-05-22 09:06:55 +0000
commit95ffee1fce520423f8a3725649c659e247ccfe12 (patch)
treede16055277b7b505489b96f8ea473e055fc1ec5f
parent7c2dbbdc486d717a674a7ec693236b91aff280cd (diff)
downloadgcc-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/ChangeLog15
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c50
-rw-r--r--gcc/config/arm/arm.md89
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);