On 23/06/2026 15:05, Richard Sandiford wrote:
Alfie Richards <[email protected]> writes:
The first (question A) is versioning the whole body of the loop (as you
call the "classical idea") vs a "fixup block" like I suggest. The fixup
block keeps one loop body, but with the addition of the branch to the
fixup block to calculate anything required to deal with a partial load
(such as AND of ffr and the loop mask).

The branch would be needed for both approaches.  I think the question is
more how much code the fixup block duplicates (ranging from "none" with
your approach to "everything up to the latch test" with the classical
approach.)
Yes agreed.


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?
Ah no you are completely correct, thank you for pointing it out.

My mistake I was looking at the complete wrong place. I was looking at the mask for the current loop and not even thinking about the next mask. Sorry about that.

That's interesting that its optimising that I guess that makes total sense. Not-ideal to say the least :)

I think to avoid this I could generate the .FAULT_DETECTED at vectorization, which would obscure from the gimple optimizations where this happens? (as ISEL would be too late to prevent this)

Does that sound reasonable?

Thanks,
Richard

        b       .L2
        .cfi_endproc
.LFE13:
        .size   foo, .-foo
        .ident  "GCC: (GNU) 17.0.0 20260622 (experimental)"
        .section        .note.GNU-stack,"",@progbits

Thanks,
Alfie

Reply via email to