Commit 18e8200f by Bernd Schmidt Committed by Bernd Schmidt

re PR rtl-optimization/42835 (Missed merging common code sequence at the end of two basic blocks)

	PR target/42835
	* config/arm/arm-modes.def (CC_NOTB): New mode.
	* config/arm/arm.c (get_arm_condition_code): Handle it.
	* config/arm/thumb2.md (thumb2_compare_scc): Delete pattern.
	* config/arm/arm.md (subsi3_compare0_c): New pattern.
	(compare_scc): Now a define_and_split.  Add a number of extra
	splitters before it.

testsuite/
	PR target/42835
	* gcc.target/arm/pr42835.c: New test.

From-SVN: r161725
parent faeb4ee3
2010-07-02 Bernd Schmidt <bernds@codesourcery.com>
PR target/42835
* config/arm/arm-modes.def (CC_NOTB): New mode.
* config/arm/arm.c (get_arm_condition_code): Handle it.
* config/arm/thumb2.md (thumb2_compare_scc): Delete pattern.
* config/arm/arm.md (subsi3_compare0_c): New pattern.
(compare_scc): Now a define_and_split. Add a number of extra
splitters before it.
2010-07-02 Sandra Loosemore <sandra@codesourcery.com> 2010-07-02 Sandra Loosemore <sandra@codesourcery.com>
* config/arm/arm.c (neon_vdup_constant): Expand into canonical RTL * config/arm/arm.c (neon_vdup_constant): Expand into canonical RTL
......
...@@ -34,6 +34,10 @@ ADJUST_FLOAT_FORMAT (HF, ((arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE) ...@@ -34,6 +34,10 @@ ADJUST_FLOAT_FORMAT (HF, ((arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
CCFPmode should be used with floating equalities. CCFPmode should be used with floating equalities.
CC_NOOVmode should be used with SImode integer equalities. CC_NOOVmode should be used with SImode integer equalities.
CC_Zmode should be used if only the Z flag is set correctly CC_Zmode should be used if only the Z flag is set correctly
CC_Cmode should be used if only the C flag is set correctly, after an
addition.
CC_NOTBmode should be used if only the C flag is set as a not-borrow
flag, after a subtraction.
CC_Nmode should be used if only the N (sign) flag is set correctly CC_Nmode should be used if only the N (sign) flag is set correctly
CCmode should be used otherwise. */ CCmode should be used otherwise. */
...@@ -53,6 +57,7 @@ CC_MODE (CC_DLTU); ...@@ -53,6 +57,7 @@ CC_MODE (CC_DLTU);
CC_MODE (CC_DGEU); CC_MODE (CC_DGEU);
CC_MODE (CC_DGTU); CC_MODE (CC_DGTU);
CC_MODE (CC_C); CC_MODE (CC_C);
CC_MODE (CC_NOTB);
CC_MODE (CC_N); CC_MODE (CC_N);
/* Vector modes. */ /* Vector modes. */
......
...@@ -16129,11 +16129,19 @@ get_arm_condition_code (rtx comparison) ...@@ -16129,11 +16129,19 @@ get_arm_condition_code (rtx comparison)
case CC_Cmode: case CC_Cmode:
switch (comp_code) switch (comp_code)
{ {
case LTU: return ARM_CS; case LTU: return ARM_CS;
case GEU: return ARM_CC; case GEU: return ARM_CC;
default: gcc_unreachable (); default: gcc_unreachable ();
} }
case CC_NOTBmode:
switch (comp_code)
{
case LTU: return ARM_CC;
case GEU: return ARM_CS;
default: gcc_unreachable ();
}
case CCmode: case CCmode:
switch (comp_code) switch (comp_code)
......
...@@ -1149,6 +1149,19 @@ ...@@ -1149,6 +1149,19 @@
[(set_attr "conds" "set")] [(set_attr "conds" "set")]
) )
(define_insn "*subsi3_compare0_c"
[(set (reg:CC_NOTB CC_REGNUM)
(compare:CC_NOTB (match_operand:SI 1 "arm_rhs_operand" "r,I")
(match_operand:SI 2 "arm_rhs_operand" "rI,r")))
(set (match_operand:SI 0 "s_register_operand" "=r,r")
(minus:SI (match_dup 1) (match_dup 2)))]
"TARGET_32BIT"
"@
sub%.\\t%0, %1, %2
rsb%.\\t%0, %2, %1"
[(set_attr "conds" "set")]
)
(define_expand "decscc" (define_expand "decscc"
[(set (match_operand:SI 0 "s_register_operand" "=r,r") [(set (match_operand:SI 0 "s_register_operand" "=r,r")
(minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
...@@ -9304,41 +9317,96 @@ ...@@ -9304,41 +9317,96 @@
(set_attr "length" "4,8")] (set_attr "length" "4,8")]
) )
(define_insn "*compare_scc" ; A series of splitters for the compare_scc pattern below. Note that
; order is important.
(define_split
[(set (match_operand:SI 0 "s_register_operand" "")
(lt:SI (match_operand:SI 1 "s_register_operand" "")
(const_int 0)))
(clobber (reg:CC CC_REGNUM))]
"TARGET_32BIT && reload_completed"
[(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
(define_split
[(set (match_operand:SI 0 "s_register_operand" "")
(ge:SI (match_operand:SI 1 "s_register_operand" "")
(const_int 0)))
(clobber (reg:CC CC_REGNUM))]
"TARGET_32BIT && reload_completed"
[(set (match_dup 0) (not:SI (match_dup 1)))
(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
(define_split
[(set (match_operand:SI 0 "s_register_operand" "")
(eq:SI (match_operand:SI 1 "s_register_operand" "")
(const_int 0)))
(clobber (reg:CC CC_REGNUM))]
"TARGET_32BIT && reload_completed"
[(parallel
[(set (reg:CC_NOTB CC_REGNUM)
(compare:CC_NOTB (const_int 1) (match_dup 1)))
(set (match_dup 0)
(minus:SI (const_int 1) (match_dup 1)))])
(cond_exec (ltu:CC_NOTB (reg:CC_NOTB CC_REGNUM) (const_int 0))
(set (match_dup 0) (const_int 0)))])
(define_split
[(set (match_operand:SI 0 "s_register_operand" "")
(ne:SI (match_operand:SI 1 "s_register_operand" "")
(match_operand:SI 2 "const_int_operand" "")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_32BIT && reload_completed"
[(parallel
[(set (reg:CC CC_REGNUM)
(compare:CC (match_dup 1) (match_dup 2)))
(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
(cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
(set (match_dup 0) (const_int 1)))]
{
operands[3] = GEN_INT (-INTVAL (operands[2]));
})
(define_split
[(set (match_operand:SI 0 "s_register_operand" "")
(ne:SI (match_operand:SI 1 "s_register_operand" "")
(match_operand:SI 2 "arm_add_operand" "")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_32BIT && reload_completed"
[(parallel
[(set (reg:CC_NOOV CC_REGNUM)
(compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
(const_int 0)))
(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
(cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
(set (match_dup 0) (const_int 1)))])
(define_insn_and_split "*compare_scc"
[(set (match_operand:SI 0 "s_register_operand" "=r,r") [(set (match_operand:SI 0 "s_register_operand" "=r,r")
(match_operator:SI 1 "arm_comparison_operator" (match_operator:SI 1 "arm_comparison_operator"
[(match_operand:SI 2 "s_register_operand" "r,r") [(match_operand:SI 2 "s_register_operand" "r,r")
(match_operand:SI 3 "arm_add_operand" "rI,L")])) (match_operand:SI 3 "arm_add_operand" "rI,L")]))
(clobber (reg:CC CC_REGNUM))] (clobber (reg:CC CC_REGNUM))]
"TARGET_ARM" "TARGET_32BIT"
"* "#"
if (operands[3] == const0_rtx) "&& reload_completed"
{ [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
if (GET_CODE (operands[1]) == LT) (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
return \"mov\\t%0, %2, lsr #31\"; (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
{
if (GET_CODE (operands[1]) == GE) rtx tmp1;
return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\"; enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
operands[2], operands[3]);
if (GET_CODE (operands[1]) == EQ) enum rtx_code rc = GET_CODE (operands[1]);
return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\";
}
if (GET_CODE (operands[1]) == NE) tmp1 = gen_rtx_REG (mode, CC_REGNUM);
{
if (which_alternative == 1) operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\"; if (mode == CCFPmode || mode == CCFPEmode)
return \"subs\\t%0, %2, %3\;movne\\t%0, #1\"; rc = reverse_condition_maybe_unordered (rc);
} else
if (which_alternative == 1) rc = reverse_condition (rc);
output_asm_insn (\"cmn\\t%2, #%n3\", operands); operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
else })
output_asm_insn (\"cmp\\t%2, %3\", operands);
return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
"
[(set_attr "conds" "clob")
(set_attr "length" "12")]
)
(define_insn "*cond_move" (define_insn "*cond_move"
[(set (match_operand:SI 0 "s_register_operand" "=r,r,r") [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
......
...@@ -599,42 +599,6 @@ ...@@ -599,42 +599,6 @@
(set_attr "length" "6,10")] (set_attr "length" "6,10")]
) )
(define_insn "*thumb2_compare_scc"
[(set (match_operand:SI 0 "s_register_operand" "=r,r")
(match_operator:SI 1 "arm_comparison_operator"
[(match_operand:SI 2 "s_register_operand" "r,r")
(match_operand:SI 3 "arm_add_operand" "rI,L")]))
(clobber (reg:CC CC_REGNUM))]
"TARGET_THUMB2"
"*
if (operands[3] == const0_rtx)
{
if (GET_CODE (operands[1]) == LT)
return \"lsr\\t%0, %2, #31\";
if (GET_CODE (operands[1]) == GE)
return \"mvn\\t%0, %2\;lsr\\t%0, %0, #31\";
if (GET_CODE (operands[1]) == EQ)
return \"rsbs\\t%0, %2, #1\;it\\tcc\;movcc\\t%0, #0\";
}
if (GET_CODE (operands[1]) == NE)
{
if (which_alternative == 1)
return \"adds\\t%0, %2, #%n3\;it\\tne\;movne\\t%0, #1\";
return \"subs\\t%0, %2, %3\;it\\tne\;movne\\t%0, #1\";
}
if (which_alternative == 1)
output_asm_insn (\"cmn\\t%2, #%n3\", operands);
else
output_asm_insn (\"cmp\\t%2, %3\", operands);
return \"ite\\t%D1\;mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
"
[(set_attr "conds" "clob")
(set_attr "length" "14")]
)
(define_insn "*thumb2_cond_move" (define_insn "*thumb2_cond_move"
[(set (match_operand:SI 0 "s_register_operand" "=r,r,r") [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
(if_then_else:SI (match_operator 3 "equality_operator" (if_then_else:SI (match_operator 3 "equality_operator"
......
2010-07-02 Bernd Schmidt <bernds@codesourcery.com>
PR target/42835
* gcc.target/arm/pr42835.c: New test.
2010-07-02 Paolo Carlini <paolo.carlini@oracle.com> 2010-07-02 Paolo Carlini <paolo.carlini@oracle.com>
* g++.dg/template/crash98.C: Remove stray // from dg-error comment. * g++.dg/template/crash98.C: Remove stray // from dg-error comment.
......
/* { dg-do compile } */
/* { dg-options "-mthumb -Os" } */
/* { dg-require-effective-target arm_thumb2_ok } */
int foo(int *p, int i)
{
return( (i < 0 && *p == 1)
|| (i > 0 && *p == 2) );
}
/* { dg-final { scan-assembler-times "movne\[\\t \]*r.,\[\\t \]*#" 1 } } */
/* { dg-final { scan-assembler-times "moveq\[\\t \]*r.,\[\\t \]*#" 1 } } */
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