PR 61208 is a wrong code bug in Thumb2 where we can generate out of
range branches due to incorrect instruction size calculations.  It's
mostly gone latent on 4.9 and trunk (though could still happen at -O0
where splitting is done during final instruction generation).

Complicating things slightly is the fact that prior to 4.9 we had a
single alternative that was emitted statically; we now use an
insn_and_split (hence the reduced impact on 4.9).  That means different
patches are needed: one for 4.9 and trunk; another for 4.8 and earlier.

I've tried to minimize the 4.8 version as much as possible to reduce the
risk.  It seems simplest to just provide a new alternative for use with
Thumb2 that has the correct length.  Consequently there are two versions
of this patch attached.  One for 4.7 and 4.8, the other for 4.9 and trunk.

        PR target/61208
        * arm.md (arm_cmpdi_unsigned): Fix length calculation for Thumb2.

Testing of the backport version on 4.8 is OK, the trunk version is
ongoing, though I've smoke tested it.

Richi, is the backport version OK to go into 4.8?


R.
Index: gcc/config/arm/arm.md
===================================================================
--- gcc/config/arm/arm.md       (revision 210617)
+++ gcc/config/arm/arm.md       (working copy)
@@ -8371,8 +8371,8 @@ (define_insn_and_split "*arm_cmpdi_insn"
 
 (define_insn_and_split "*arm_cmpdi_unsigned"
   [(set (reg:CC_CZ CC_REGNUM)
-        (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r")
-                       (match_operand:DI 1 "arm_di_operand"     "Py,r,rDi")))]
+        (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
+                       (match_operand:DI 1 "arm_di_operand"     
"Py,r,Di,rDi")))]
 
   "TARGET_32BIT"
   "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
@@ -8392,9 +8392,9 @@ (define_insn_and_split "*arm_cmpdi_unsig
     operands[1] = gen_lowpart (SImode, operands[1]);
   }
   [(set_attr "conds" "set")
-   (set_attr "enabled_for_depr_it" "yes,yes,no")
-   (set_attr "arch" "t2,t2,*")
-   (set_attr "length" "6,6,8")
+   (set_attr "enabled_for_depr_it" "yes,yes,no,*")
+   (set_attr "arch" "t2,t2,t2,a")
+   (set_attr "length" "6,6,10,8")
    (set_attr "type" "multiple")]
 )
 
--- gcc/config/arm/arm.md       (revision 210631)
+++ gcc/config/arm/arm.md       (local)
@@ -7630,12 +7630,13 @@ (define_insn "*arm_cmpdi_insn"
 
 (define_insn "*arm_cmpdi_unsigned"
   [(set (reg:CC_CZ CC_REGNUM)
-       (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "r")
-                      (match_operand:DI 1 "arm_di_operand"     "rDi")))]
+       (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "r,r")
+                      (match_operand:DI 1 "arm_di_operand"     "rDi,rDi")))]
   "TARGET_32BIT"
   "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
   [(set_attr "conds" "set")
-   (set_attr "length" "8")]
+   (set_attr "arch" "a,t2")
+   (set_attr "length" "8,10")]
 )
 
 (define_insn "*arm_cmpdi_zero"

Reply via email to