Commit 95ffee1f by Ramana Radhakrishnan

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
parent 7c2dbbdc
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> 2012-05-22 Dimitrios Apostolou <jimis@gmx.net>
* df-scan.c (df_scan_alloc): Round up allocation pools size, reduce * 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> 2012-05-22 Paolo Bonzini <bonzini@gnu.org>
......
...@@ -248,6 +248,7 @@ extern int vfp3_const_double_for_fract_bits (rtx); ...@@ -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, extern void arm_emit_coreregs_64bit_shift (enum rtx_code, rtx, rtx, rtx, rtx,
rtx); rtx);
extern bool arm_validize_comparison (rtx *, rtx *, rtx *);
#endif /* RTX_CODE */ #endif /* RTX_CODE */
extern void arm_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel); extern void arm_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
......
...@@ -26185,4 +26185,54 @@ arm_emit_coreregs_64bit_shift (enum rtx_code code, rtx out, rtx in, ...@@ -26185,4 +26185,54 @@ arm_emit_coreregs_64bit_shift (enum rtx_code code, rtx out, rtx in,
#undef BRANCH #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" #include "gt-arm.h"
...@@ -6977,12 +6977,12 @@ ...@@ -6977,12 +6977,12 @@
(match_operand:SI 2 "nonmemory_operand" "")]) (match_operand:SI 2 "nonmemory_operand" "")])
(label_ref (match_operand 3 "" "")) (label_ref (match_operand 3 "" ""))
(pc)))] (pc)))]
"TARGET_THUMB1 || TARGET_32BIT" "TARGET_EITHER"
" "
if (!TARGET_THUMB1) if (!TARGET_THUMB1)
{ {
if (!arm_add_operand (operands[2], SImode)) if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
operands[2] = force_reg (SImode, operands[2]); FAIL;
emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
operands[3])); operands[3]));
DONE; DONE;
...@@ -7054,33 +7054,13 @@ ...@@ -7054,33 +7054,13 @@
(pc)))] (pc)))]
"TARGET_32BIT" "TARGET_32BIT"
"{ "{
rtx swap = NULL_RTX;
enum rtx_code code = GET_CODE (operands[0]);
/* We should not have two constants. */ /* We should not have two constants. */
gcc_assert (GET_MODE (operands[1]) == DImode gcc_assert (GET_MODE (operands[1]) == DImode
|| GET_MODE (operands[2]) == DImode); || GET_MODE (operands[2]) == DImode);
/* Flip unimplemented DImode comparisons to a form that if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
arm_gen_compare_reg can handle. */ FAIL;
switch (code) emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
{
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],
operands[3])); operands[3]));
DONE; DONE;
}" }"
...@@ -8065,33 +8045,15 @@ ...@@ -8065,33 +8045,15 @@
(match_operand:DI 3 "cmpdi_operand" "")]))] (match_operand:DI 3 "cmpdi_operand" "")]))]
"TARGET_32BIT" "TARGET_32BIT"
"{ "{
rtx swap = NULL_RTX;
enum rtx_code code = GET_CODE (operands[1]);
/* We should not have two constants. */ /* We should not have two constants. */
gcc_assert (GET_MODE (operands[2]) == DImode gcc_assert (GET_MODE (operands[2]) == DImode
|| GET_MODE (operands[3]) == DImode); || GET_MODE (operands[3]) == DImode);
/* Flip unimplemented DImode comparisons to a form that if (!arm_validize_comparison (&operands[1],
arm_gen_compare_reg can handle. */ &operands[2],
switch (code) &operands[3]))
{ FAIL;
case GT: emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
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],
operands[3])); operands[3]));
DONE; DONE;
}" }"
...@@ -8186,12 +8148,14 @@ ...@@ -8186,12 +8148,14 @@
"TARGET_32BIT" "TARGET_32BIT"
" "
{ {
enum rtx_code code = GET_CODE (operands[1]); enum rtx_code code;
rtx ccreg; rtx ccreg;
if (code == UNEQ || code == LTGT) if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
&XEXP (operands[1], 1)))
FAIL; FAIL;
code = GET_CODE (operands[1]);
ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
XEXP (operands[1], 1), NULL_RTX); XEXP (operands[1], 1), NULL_RTX);
operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
...@@ -8202,22 +8166,18 @@ ...@@ -8202,22 +8166,18 @@
[(set (match_operand:SF 0 "s_register_operand" "") [(set (match_operand:SF 0 "s_register_operand" "")
(if_then_else:SF (match_operand 1 "expandable_comparison_operator" "") (if_then_else:SF (match_operand 1 "expandable_comparison_operator" "")
(match_operand:SF 2 "s_register_operand" "") (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" "TARGET_32BIT && TARGET_HARD_FLOAT"
" "
{ {
enum rtx_code code = GET_CODE (operands[1]); enum rtx_code code = GET_CODE (operands[1]);
rtx ccreg; rtx ccreg;
if (code == UNEQ || code == LTGT) if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
FAIL; &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), ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
XEXP (operands[1], 1), NULL_RTX); XEXP (operands[1], 1), NULL_RTX);
operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
...@@ -8235,9 +8195,10 @@ ...@@ -8235,9 +8195,10 @@
enum rtx_code code = GET_CODE (operands[1]); enum rtx_code code = GET_CODE (operands[1]);
rtx ccreg; rtx ccreg;
if (code == UNEQ || code == LTGT) if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
FAIL; &XEXP (operands[1], 1)))
FAIL;
code = GET_CODE (operands[1]);
ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
XEXP (operands[1], 1), NULL_RTX); XEXP (operands[1], 1), NULL_RTX);
operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment