In testing I actually found the overhead to be pretty similar for having
a fixup block verses duplicating the entire body of the loop. Then as
you say, using the fixup block allows multiple FFR regions (which this
patch series implements, see ex 2) and it requires less code overall, so
I strongly prefer this.
Ah, interesting! Thanks for running the numbers.
However, if I'm reading the above assembly correctly, it looks like:
next_mask_ffr_81 = next_mask_79 & next_mask_ffr_80;
ends up using the RDFFR result even for the "good" path. Is:
# next_mask_ffr_80 = PHI <{ -1, ... }(3), _84(15)>
getting optimised to _84 based on:
if (ffr_mask_83 == { -1, ... })
? That would be a legitimate optimisation as far as gimple is concerned,
but my understanding is that it would be harmful for performance.
I think this is actually my mistake and the example I gave is missing
bits and misleading. If you see example 1 and 2 you can hopefully see in
the "good" full load case, we do not depend on the value from FFR in the
loop body.
Hmm, example 1 still seems similar to the original quote. I.e.:
.arch armv8.2-a+crc+sve
.file "example1.c"
.text
.align 2
.p2align 5,,15
.global foo
.type foo, %function
foo:
.LFB13:
.cfi_startproc
cntb x4
sub x4, x4, #1
setffr
and x4, x1, x4
mov w3, 0
ptrue p15.s, all
and x2, x4, 17179869180
ubfx x4, x4, 2, 32
sub x0, x0, x2
whilelo p14.s, xzr, x4
sub x1, x1, x2
mov w2, 10000
add x4, x4, x2
whilelo p7.s, xzr, x4
not p7.b, p7/z, p14.b
b .L4
.p2align 2,,3
.L11:
add x3, x3, x2
whilelo p7.s, x3, x4
add x0, x0, x2, lsl 2
and p7.b, p7/z, p14.b, p14.b
This is executed for both paths after the block at L2. It uses p14.
add x1, x1, x2, lsl 2
ptest p15, p7.b
b.none .L9
.L4:
ldff1w z30.s, p7/z, [x0]
ldff1w z31.s, p7/z, [x1]
cntw x2
rdffr p14.b
RDFFR sets p14 here.
nots p13.b, p15/z, p14.b
b.any .L10
.L2:
For this "good" fallthrough case, p14 is still the RDFFR result.
cmpeq p7.s, p7/z, z30.s, z31.s
b.none .L11
mov w0, 1
ret
.p2align 2,,3
.L9:
mov w0, 0
ret
.L10:
and p7.b, p7/z, p14.b, p14.b
mov w2, 0
setffr
mov p14.b, p13.b
p14 is set up to the NOTS result here, for the faulting case.
Am I reading it wrongly?