This patch deals with consequences but not the root cause though. There are 5 cases which are subjects to rewrite: case #1: mov ip, r1 add r2, ip # ip is dead here can be rewritten as: adds r2, r1
case #2: add ip, r1 mov r1, ip # ip is dead here can be rewritten as: add r1, ip case #3: mov ip, r1 add r2, ip add r3, ip # ip is dead here can be rewritten as: adds r2, r1 adds r3, r1 case #4: mov ip, r1 add ip, r2 mov r1, ip can be rewritten as: adds r1, r2 mov ip, r1 <- might be eliminated too, if ip is dead case #5 (arbitrary): mov r1, ip subs r2, r1, r2 mov ip, r2 # r1 is dead here can be rewritten as: rsbs r1, r2, #0 add ip, r1 movs r2, ip <- might be eliminated, if r2 is dead Speed profit wasn't checked but size changes are the following: libgcc: -132 bytes / -0.25% libc: -1262 bytes / -0.55% libm: -384 bytes / -0.42% libstdc++: -2258 bytes / -0.30% No tests provided because its hard to force GCC to emit HI_REGS in a small and straightforward function. Signed-off-by: Siarhei Volkau <lis8...@gmail.com> --- gcc/config/arm/thumb1.md | 93 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-) diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md index d7074b43f60..9da4af9eccd 100644 --- a/gcc/config/arm/thumb1.md +++ b/gcc/config/arm/thumb1.md @@ -2055,4 +2055,95 @@ (define_insn "thumb1_stack_protect_test_insn" (set_attr "conds" "clob") (set_attr "type" "multiple")] ) - + +;; bad code emitted when HI_REGS involved in addition +;; subtract also might happen rarely + +;; case #1: +;; mov ip, r1 +;; add r2, ip # ip is dead after that +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "register_operand" "")) + (set (match_operand:SI 2 "register_operand" "") + (plus:SI (match_dup 2) (match_dup 0)))] + "TARGET_THUMB1 + && peep2_reg_dead_p (2, operands[0]) + && REGNO_REG_CLASS (REGNO (operands[0])) == HI_REGS" + [(set (match_dup 2) + (plus:SI (match_dup 2) (match_dup 1)))] + "") + +;; case #2: +;; add ip, r1 +;; mov r1, ip # ip is dead after that +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" ""))) + (set (match_dup 1) (match_dup 0))] + "TARGET_THUMB1 + && peep2_reg_dead_p (2, operands[0]) + && REGNO_REG_CLASS (REGNO (operands[0])) == HI_REGS" + [(set (match_dup 1) + (plus:SI (match_dup 1) (match_dup 0)))] + "") + +;; case #3: +;; mov ip, r1 +;; add r2, ip +;; add r3, ip # ip is dead after that +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "register_operand" "")) + (set (match_operand:SI 2 "register_operand" "") + (plus:SI (match_dup 2) (match_dup 0))) + (set (match_operand:SI 3 "register_operand" "") + (plus:SI (match_dup 3) (match_dup 0)))] + "TARGET_THUMB1 + && peep2_reg_dead_p (3, operands[0]) + && REGNO_REG_CLASS (REGNO (operands[0])) == HI_REGS" + [(set (match_dup 2) + (plus:SI (match_dup 2) (match_dup 1))) + (set (match_dup 3) + (plus:SI (match_dup 3) (match_dup 1)))] + "") + +;; case #4: +;; mov ip, r1 +;; add ip, r2 +;; mov r1, ip +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "register_operand" "")) + (set (match_dup 0) + (plus:SI (match_dup 0) (match_operand:SI 2 "register_operand" ""))) + (set (match_dup 1) + (match_dup 0))] + "TARGET_THUMB1 + && REGNO_REG_CLASS (REGNO (operands[0])) == HI_REGS" + [(set (match_dup 1) + (plus:SI (match_dup 1) (match_dup 2))) + (set (match_dup 0) (match_dup 1))] ;; likely will be eliminated + "") + +;; case #5: +;; mov r1, ip +;; subs r2, r1, r2 +;; mov ip, r2 # r1 is dead after +(define_peephole2 + [(set (match_operand:SI 1 "register_operand" "") + (match_operand:SI 0 "register_operand" "")) + (set (match_operand:SI 2 "register_operand" "") + (minus:SI (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (match_dup 2))] + "TARGET_THUMB1 + && peep2_reg_dead_p (3, operands[1]) + && REGNO_REG_CLASS (REGNO (operands[0])) == HI_REGS" + [(set (match_dup 1) + (neg:SI (match_dup 2))) + (set (match_dup 0) + (plus:SI (match_dup 0) (match_dup 1))) + (set (match_dup 2) ;; likely will be eliminated + (match_dup 0))] + "") -- 2.45.2