arm: Low overhead loop handle long range branches [PR98931]
authorAndrea Corallo <andrea.corallo@arm.com>
Wed, 3 Feb 2021 14:21:54 +0000 (15:21 +0100)
committerAndrea Corallo <andrea.corallo@arm.com>
Thu, 11 Feb 2021 15:20:59 +0000 (16:20 +0100)
gcc/
PR target/98931
* config/arm/thumb2.md (*doloop_end_internal): Generate
alternative sequence to handle long range branches.

gcc/testsuite/
PR target/98931
* gcc.target/arm/pr98931.c: New testcase.

gcc/config/arm/thumb2.md
gcc/testsuite/gcc.target/arm/pr98931.c [new file with mode: 0644]

index bd53bf320de806f1dd6d6c34d3aa5a59912f9717..d7fd96c270eba40f906687b297af20cfdd317bab 100644 (file)
 
 ;; Originally expanded by 'doloop_end'.
 (define_insn "*doloop_end_internal"
-  [(parallel [(set (pc)
-                   (if_then_else
-                       (ne (reg:SI LR_REGNUM) (const_int 1))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))
-              (set (reg:SI LR_REGNUM)
-                   (plus:SI (reg:SI LR_REGNUM) (const_int -1)))])]
+  [(set (pc)
+        (if_then_else
+            (ne (reg:SI LR_REGNUM) (const_int 1))
+          (label_ref (match_operand 0 "" ""))
+          (pc)))
+   (set (reg:SI LR_REGNUM)
+        (plus:SI (reg:SI LR_REGNUM) (const_int -1)))
+   (clobber (reg:CC CC_REGNUM))]
   "TARGET_32BIT && TARGET_HAVE_LOB"
-  "le\t%|lr, %l0")
+  {
+    if (get_attr_length (insn) == 4)
+      return "le\t%|lr, %l0";
+    else
+      return "subs\t%|lr, #1;bne\t%l0";
+  }
+  [(set (attr "length")
+        (if_then_else
+            (ltu (minus (pc) (match_dup 0)) (const_int 1024))
+           (const_int 4)
+           (const_int 6)))
+   (set_attr "type" "branch")])
 
 (define_expand "doloop_begin"
   [(match_operand 0 "" "")
diff --git a/gcc/testsuite/gcc.target/arm/pr98931.c b/gcc/testsuite/gcc.target/arm/pr98931.c
new file mode 100644 (file)
index 0000000..313876a
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do assemble } */
+/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" "-mcpu=*" } } */
+/* { dg-options "-march=armv8.1-m.main -O3 --param=max-completely-peeled-insns=1300 --save-temps" } */
+
+extern long long a[][20][26][26][22];
+
+void
+foo ()
+{
+  for (short d = 0; d + 1; d++)
+    for (unsigned e = 0; e < 25; e += 4)
+      for (unsigned f = 0; f < 25; f += 4)
+        for (int g = 0; g < 21; g += 4)
+          a[4][d][e][f][g] = 0;
+}
+
+/* { dg-final { scan-assembler-not {le\slr,\s\S*} } } */