Hi all, As part of patch 3/3 I want to expand to an if_then_else form of a conditional negate operation. It seems we already have patterns for that, but they are ancient and only enabled for TARGET_ARM. Doing a bit of archaeology I see that they were added in 1997 before Thumb and before define_insn_and_split. A commit in 2000 that introduced Thumb mode restricted them to only TARGET_ARM.
This patch modernises the patterns by converting them to define_insn_and_splits, removes the redundant alternatives that can be expressed using constraints and splits them into a cond_exec of a negate operation after reload (when we're allowed to generate cond_exec rtxes). This way, we can enable both patterns for TARGET_32BIT i.e. both ARM and Thumb2 states. I did two bootstraps, one in arm mode, one in Thumb2 mode. Both were fine. Tested on arm too. Ok for trunk? Thanks, Kyrill 2015-07-24 Kyrylo Tkachov <kyrylo.tkac...@arm.com> * config/arm/arm.md (*if_neg_move): Convert to insn_and_split. Enable for TARGET_32BIT. (*if_move_neg): Likewise.
commit 1b495b6cb68c77f628e1c1d672c06dcdf5ccf79b Author: Kyrylo Tkachov <kyrylo.tkac...@arm.com> Date: Thu Jul 23 09:20:41 2015 +0100 [ARM] Make if_neg_move and if_move_neg into insn_and_split diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 0be70a8..f341109 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -10064,21 +10064,24 @@ (define_insn "*ifcompare_neg_move" (set_attr "type" "multiple")] ) -(define_insn "*if_neg_move" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") +(define_insn_and_split "*if_neg_move" + [(set (match_operand:SI 0 "s_register_operand" "=l,r") (if_then_else:SI (match_operator 4 "arm_comparison_operator" [(match_operand 3 "cc_register" "") (const_int 0)]) - (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r")) - (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] - "TARGET_ARM" - "@ - rsb%d4\\t%0, %2, #0 - mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0 - mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0" + (neg:SI (match_operand:SI 2 "s_register_operand" "l,r")) + (match_operand:SI 1 "arm_not_operand" "0,0")))] + "TARGET_32BIT" + "#" + "&& reload_completed" + [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)]) + (set (match_dup 0) (neg:SI (match_dup 2))))] + "" [(set_attr "conds" "use") - (set_attr "length" "4,8,8") - (set_attr "type" "logic_shift_imm,multiple,multiple")] + (set_attr "length" "4") + (set_attr "arch" "t2,32") + (set_attr "enabled_for_depr_it" "yes,no") + (set_attr "type" "logic_shift_imm")] ) (define_insn "*ifcompare_move_neg" @@ -10097,21 +10100,34 @@ (define_insn "*ifcompare_move_neg" (set_attr "type" "multiple")] ) -(define_insn "*if_move_neg" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") +(define_insn_and_split "*if_move_neg" + [(set (match_operand:SI 0 "s_register_operand" "=l,r") (if_then_else:SI (match_operator 4 "arm_comparison_operator" [(match_operand 3 "cc_register" "") (const_int 0)]) - (match_operand:SI 1 "arm_not_operand" "0,?rI,K") - (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))] - "TARGET_ARM" - "@ - rsb%D4\\t%0, %2, #0 - mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0 - mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0" + (match_operand:SI 1 "arm_not_operand" "0,0") + (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))] + "TARGET_32BIT" + "#" + "&& reload_completed" + [(cond_exec (match_dup 5) + (set (match_dup 0) (neg:SI (match_dup 2))))] + { + machine_mode mode = GET_MODE (operands[3]); + rtx_code rc = GET_CODE (operands[4]); + + if (mode == CCFPmode || mode == CCFPEmode) + rc = reverse_condition_maybe_unordered (rc); + else + rc = reverse_condition (rc); + + operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx); + } [(set_attr "conds" "use") - (set_attr "length" "4,8,8") - (set_attr "type" "logic_shift_imm,multiple,multiple")] + (set_attr "length" "4") + (set_attr "arch" "t2,32") + (set_attr "enabled_for_depr_it" "yes,no") + (set_attr "type" "logic_shift_imm")] ) (define_insn "*arith_adjacentmem"