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.
This commit is contained in:
Andrea Corallo 2021-02-03 15:21:54 +01:00
parent 4af29981ab
commit 38c5703449
2 changed files with 37 additions and 8 deletions

View File

@ -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 "" "")

View File

@ -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*} } } */