aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Corallo <andrea.corallo@arm.com>2021-02-03 15:21:54 +0100
committerAndrea Corallo <andrea.corallo@arm.com>2021-02-11 16:20:59 +0100
commit38c5703449c0638618ba6896f0d039c3868ad4e0 (patch)
tree848c1145e85db131379e114b139a4ee3b648912d
parent4af29981ab57ad7ef4467e371e4145cce9c16eaa (diff)
downloadgcc-38c5703449c0638618ba6896f0d039c3868ad4e0.zip
gcc-38c5703449c0638618ba6896f0d039c3868ad4e0.tar.gz
gcc-38c5703449c0638618ba6896f0d039c3868ad4e0.tar.bz2
arm: Low overhead loop handle long range branches [PR98931]
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.
-rw-r--r--gcc/config/arm/thumb2.md28
-rw-r--r--gcc/testsuite/gcc.target/arm/pr98931.c17
2 files changed, 37 insertions, 8 deletions
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index bd53bf3..d7fd96c 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -1711,15 +1711,27 @@
;; 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
index 0000000..313876a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr98931.c
@@ -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*} } } */