Patchwork [ARM] Fix for PR52294: Out-of-range branch in Thumb2 code

login
register
mail settings
Submitter Richard Earnshaw
Date Feb. 21, 2012, 3:40 p.m.
Message ID <4F43BAFD.7090704@arm.com>
Download mbox | patch
Permalink /patch/142310/
State New
Headers show

Comments

Richard Earnshaw - Feb. 21, 2012, 3:40 p.m.
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.

Patch

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)