PR52294 is a case where we generate a cbz instruction that ends up
trying to reach too far. The reason for this is that we calculate the
size of some instructions as being 2 bytes when in reality they take 4.
The problem in this instance is that a peephole to shorten
lsl reg, reg, reg
into
lsls reg, reg, reg
Failed to observe that the first two registers have to be identical
(unlike lsls reg, reg, #const) or the result will be no shorter than the
original.
Fixed thusly:
PR target/52294
* thumb2.md (thumb2_shiftsi3_short): Split register and
immediate shifts. For register shifts tie operands 0 and 1.
(peephole2 for above): Check that register-controlled shifts
have suitably tied operands.
R.
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index ad05feb..39a2138 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -686,6 +686,7 @@
(match_operand:SI 2 "low_reg_or_int_operand" "")]))]
"TARGET_THUMB2
&& peep2_regno_dead_p(0, CC_REGNUM)
+ && (CONST_INT_P (operands[2]) || operands[1] == operands[0])
&& ((GET_CODE(operands[3]) != ROTATE && GET_CODE(operands[3]) != ROTATERT)
|| REG_P(operands[2]))"
[(parallel
@@ -698,10 +699,10 @@
)
(define_insn "*thumb2_shiftsi3_short"
- [(set (match_operand:SI 0 "low_register_operand" "=l")
+ [(set (match_operand:SI 0 "low_register_operand" "=l,l")
(match_operator:SI 3 "shift_operator"
- [(match_operand:SI 1 "low_register_operand" "l")
- (match_operand:SI 2 "low_reg_or_int_operand" "lM")]))
+ [(match_operand:SI 1 "low_register_operand" "0,l")
+ (match_operand:SI 2 "low_reg_or_int_operand" "l,M")]))
(clobber (reg:CC CC_REGNUM))]
"TARGET_THUMB2 && reload_completed
&& ((GET_CODE(operands[3]) != ROTATE && GET_CODE(operands[3]) != ROTATERT)