Hi!

Please find attached the patch to fix bug in branches with offsets over 1MiB.
There has been an attempt to fix this issue in commit
050af05b9761f1979f11c151519e7244d5becd7c

However, the far_branch attribute defined in above patch used
insn_length - which computes incorrect offset. Hence, eliminated the
attribute completely, and computed the offset from insn_addresses
instead.

Ok for trunk?

gcc/Changelog

2018-02-13 Sameera Deshpande <sameera.deshpa...@linaro.org>
        * config/aarch64/aarch64.md (far_branch): Remove attribute. Eliminate
        all the dependencies on the attribute from RTL patterns.

-- 
- Thanks and regards,
  Sameera D.
Index: gcc/config/aarch64/aarch64.md
===================================================================
--- gcc/config/aarch64/aarch64.md	(revision 257620)
+++ gcc/config/aarch64/aarch64.md	(working copy)
@@ -244,13 +244,6 @@
 	    (const_string "no")
 	] (const_string "yes")))
 
-;; Attribute that specifies whether we are dealing with a branch to a
-;; label that is far away, i.e. further away than the maximum/minimum
-;; representable in a signed 21-bits number.
-;; 0 :=: no
-;; 1 :=: yes
-(define_attr "far_branch" "" (const_int 0))
-
 ;; Strictly for compatibility with AArch32 in pipeline models, since AArch64 has
 ;; no predicated insns.
 (define_attr "predicated" "yes,no" (const_string "no"))
@@ -448,12 +441,7 @@
 	(if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
 			   (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
 		      (const_int 4)
-		      (const_int 8)))
-   (set (attr "far_branch")
-	(if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
-			   (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
-		      (const_int 0)
-		      (const_int 1)))]
+		      (const_int 8)))]
 )
 
 ;; For a 24-bit immediate CST we can optimize the compare for equality
@@ -670,12 +658,7 @@
 	(if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -1048576))
 			   (lt (minus (match_dup 1) (pc)) (const_int 1048572)))
 		      (const_int 4)
-		      (const_int 8)))
-   (set (attr "far_branch")
-	(if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
-			   (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
-		      (const_int 0)
-		      (const_int 1)))]
+		      (const_int 8)))]
 )
 
 (define_insn "*tb<optab><mode>1"
@@ -692,7 +675,11 @@
   {
     if (get_attr_length (insn) == 8)
       {
-	if (get_attr_far_branch (insn) == 1)
+	long long int offset;
+	offset = INSN_ADDRESSES (INSN_UID (XEXP (operands[2], 0)))
+		  - INSN_ADDRESSES (INSN_UID (insn));
+
+	if (offset <= -1048576 || offset >= 1048572)
 	  return aarch64_gen_far_branch (operands, 2, "Ltb",
 					 "<inv_tb>\\t%<w>0, %1, ");
 	else
@@ -709,12 +696,7 @@
 	(if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
 			   (lt (minus (match_dup 2) (pc)) (const_int 32764)))
 		      (const_int 4)
-		      (const_int 8)))
-   (set (attr "far_branch")
-	(if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
-			   (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
-		      (const_int 0)
-		      (const_int 1)))]
+		      (const_int 8)))]
 
 )
 
@@ -727,8 +709,12 @@
   ""
   {
     if (get_attr_length (insn) == 8)
-      {
-	if (get_attr_far_branch (insn) == 1)
+       {
+        long long int offset;
+        offset = INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
+		 - INSN_ADDRESSES (INSN_UID (insn));
+
+	if (offset <= -1048576 || offset >= 1048572)
 	  return aarch64_gen_far_branch (operands, 1, "Ltb",
 					 "<inv_tb>\\t%<w>0, <sizem1>, ");
 	else
@@ -740,7 +726,7 @@
 	    output_asm_insn (buf, operands);
 	    return "<bcond>\t%l1";
 	  }
-      }
+       }
     else
       return "<tbz>\t%<w>0, <sizem1>, %l1";
   }
@@ -749,12 +735,7 @@
 	(if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
 			   (lt (minus (match_dup 1) (pc)) (const_int 32764)))
 		      (const_int 4)
-		      (const_int 8)))
-   (set (attr "far_branch")
-	(if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -1048576))
-			   (lt (minus (match_dup 1) (pc)) (const_int 1048572)))
-		      (const_int 0)
-		      (const_int 1)))]
+		      (const_int 8)))]
 )
 
 ;; -------------------------------------------------------------------

Reply via email to