[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
This commit is contained in:
Richard Earnshaw 2019-10-18 19:03:19 +00:00 committed by Richard Earnshaw
parent f6ff841bc8
commit 0b478cddf9
2 changed files with 39 additions and 0 deletions

View File

@ -1,3 +1,8 @@
2019-10-18 Richard Earnshaw <rearnsha@arm.com>
* config/arm/arm.md (subsi3_carryin_shift_alt): New pattern.
(rsbsi3_carryin_shift_alt): Likewise.
2019-10-18 Richard Earnshaw <rearnsha@arm.com>
* config/arm/arm.md (negscc_borrow): New pattern.

View File

@ -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" "")