diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 60bd34758c0..39de837b326 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2020-02-10 Hans-Peter Nilsson + + Try to generate zero-based comparisons. + * config/cris/cris.c (cris_reduce_compare): New function. + * config/cris/cris-protos.h (cris_reduce_compare): Add prototype. + * config/cris/cris.md ("cbranch4", "cbranchdi4", "cstoredi4") + (cstore4"): Apply cris_reduce_compare in expanders. + 2020-02-10 Richard Earnshaw PR target/91913 diff --git a/gcc/config/cris/cris-protos.h b/gcc/config/cris/cris-protos.h index 2105256cc78..6f6d815678a 100644 --- a/gcc/config/cris/cris-protos.h +++ b/gcc/config/cris/cris-protos.h @@ -38,6 +38,7 @@ extern bool cris_constant_index_p (const_rtx); extern bool cris_base_p (const_rtx, bool); extern bool cris_base_or_autoincr_p (const_rtx, bool); extern bool cris_bdap_index_p (const_rtx, bool); +extern void cris_reduce_compare (rtx *, rtx *, rtx *); extern bool cris_biap_index_p (const_rtx, bool); extern bool cris_legitimate_address_p (machine_mode, rtx, bool); extern bool cris_store_multiple_op_p (rtx); diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index 01388b3d019..91cb63c01e7 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -3053,6 +3053,63 @@ cris_split_movdx (rtx *operands) return val; } +/* Try to change a comparison against a constant to be against zero, and + an unsigned compare against zero to be an equality test. Beware: + only valid for compares of integer-type operands. Also, note that we + don't use operand 0 at the moment. */ + +void +cris_reduce_compare (rtx *relp, rtx *, rtx *op1p) +{ + rtx op1 = *op1p; + rtx_code code = GET_CODE (*relp); + + /* Code lifted mostly from emit_store_flag_1. */ + switch (code) + { + case LT: + if (op1 == const1_rtx) + code = LE; + break; + case LE: + if (op1 == constm1_rtx) + code = LT; + break; + case GE: + if (op1 == const1_rtx) + code = GT; + break; + case GT: + if (op1 == constm1_rtx) + code = GE; + break; + case GEU: + if (op1 == const1_rtx) + code = NE; + break; + case LTU: + if (op1 == const1_rtx) + code = EQ; + break; + case GTU: + if (op1 == const0_rtx) + code = NE; + break; + case LEU: + if (op1 == const0_rtx) + code = EQ; + break; + default: + break; + } + + if (code != GET_CODE (*relp)) + { + *op1p = const0_rtx; + PUT_CODE (*relp, code); + } +} + /* The expander for the prologue pattern name. */ void diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md index b73ea8bb78e..fd8355c23a3 100644 --- a/gcc/config/cris/cris.md +++ b/gcc/config/cris/cris.md @@ -3539,7 +3539,7 @@ (label_ref (match_operand 3 "" "")) (pc)))] "" - "") + "cris_reduce_compare (&operands[0], &operands[1], &operands[2]);") (define_expand "cbranchdi4" [(set (cc0) @@ -3552,6 +3552,7 @@ (pc)))] "" { + cris_reduce_compare (&operands[0], &operands[1], &operands[2]); if (TARGET_V32 && !REG_P (operands[1])) operands[1] = force_reg (DImode, operands[1]); if (TARGET_V32 && MEM_P (operands[2])) @@ -3652,6 +3653,7 @@ [(cc0) (const_int 0)]))] "" { + cris_reduce_compare (&operands[1], &operands[2], &operands[3]); if (TARGET_V32 && !REG_P (operands[2])) operands[2] = force_reg (DImode, operands[2]); if (TARGET_V32 && MEM_P (operands[3])) @@ -3666,7 +3668,7 @@ (match_operator:SI 1 "ordered_comparison_operator" [(cc0) (const_int 0)]))] "" - "") + "cris_reduce_compare (&operands[1], &operands[2], &operands[3]);") ;; Like bCC, we have to check the overflow bit for ;; signed conditions.