predicated-countAn accumulator updated only on the taken arm
Reported by --explain after a verdict.
mettle explain predicated-count
Over int32 elements, if (a[i] > t) { c = c + 1; } and if (a[i] < 0) { s = s + a[i]; } both vectorize: the comparison already holds 0 or 1, so the compiler multiplies the addend by it and the body becomes straight line.
This code fires when that rewrite does not apply. Three shapes it will not take:
Float elements. There is no predicated float reduction, and the branchless form has no kernel either, so there is nothing to change in the loop.
An else arm that also writes the accumulator. That is a select on a loop-carried value, not an accumulate; there is no one addend.
A guard on a computed value. The conversion reads a comparison of a loaded element (
a[i] > t,a[i] == 0);if (a[i] & 6)is a test of an expression, and respelling it(a[i] & 6) != 0keeps it one. Add the comparison rather than branching on it and the kernel takes it, for any comparison:c = c + ((a[i] & 6) != 0);
Related
- call-in-bodyThe loop body calls a function
- extern-call-in-bodyThe loop body calls an external function
- indirect-callThe loop body calls through a function pointer
- alloc-in-bodyThe loop body allocates
- inline-asmThe loop body contains inline assembly
- control-flowThe loop body branches
- early-exitThe loop can leave before its trip count
- int16-elements16-bit integer elements have no kernel