From 0b478cddf9e95406cd865c94bf99705ec8acddde Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Fri, 18 Oct 2019 19:03:19 +0000 Subject: [PATCH] [arm] Add alternative canonicalizations for subtract-with-carry + shift This patch adds a couple of alternative canonicalizations to allow combine to match a subtract-with-carry operation when one of the operands is shifted first. The most common case of this is when combining a sign-extend of one operand with a long-long value during subtraction. The RSC variant is only enabled for Arm, the SBC variant for any 32-bit compilation. * config/arm/arm.md (subsi3_carryin_shift_alt): New pattern. (rsbsi3_carryin_shift_alt): Likewise. From-SVN: r277176 --- gcc/ChangeLog | 5 +++++ gcc/config/arm/arm.md | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4d2812a0893..393fcbdcfff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-10-18 Richard Earnshaw + + * config/arm/arm.md (subsi3_carryin_shift_alt): New pattern. + (rsbsi3_carryin_shift_alt): Likewise. + 2019-10-18 Richard Earnshaw * config/arm/arm.md (negscc_borrow): New pattern. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 74f417fbe4b..613f50ae5f0 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1048,6 +1048,23 @@ (const_string "alu_shift_reg")))] ) +(define_insn "*subsi3_carryin_shift_alt" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (minus:SI (minus:SI + (match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 5 "arm_borrow_operation" "")) + (match_operator:SI 2 "shift_operator" + [(match_operand:SI 3 "s_register_operand" "r") + (match_operand:SI 4 "reg_or_int_operand" "rM")])))] + "TARGET_32BIT" + "sbc%?\\t%0, %1, %3%S2" + [(set_attr "conds" "use") + (set_attr "predicable" "yes") + (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") + (const_string "alu_shift_imm") + (const_string "alu_shift_reg")))] +) + (define_insn "*rsbsi3_carryin_shift" [(set (match_operand:SI 0 "s_register_operand" "=r") (minus:SI (minus:SI @@ -1065,6 +1082,23 @@ (const_string "alu_shift_reg")))] ) +(define_insn "*rsbsi3_carryin_shift_alt" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (minus:SI (minus:SI + (match_operator:SI 2 "shift_operator" + [(match_operand:SI 3 "s_register_operand" "r") + (match_operand:SI 4 "reg_or_int_operand" "rM")]) + (match_operand:SI 5 "arm_borrow_operation" "")) + (match_operand:SI 1 "s_register_operand" "r")))] + "TARGET_ARM" + "rsc%?\\t%0, %1, %3%S2" + [(set_attr "conds" "use") + (set_attr "predicable" "yes") + (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") + (const_string "alu_shift_imm") + (const_string "alu_shift_reg")))] +) + ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant. (define_split [(set (match_operand:SI 0 "s_register_operand" "") -- 2.30.2