Clang should vectorise using the fact that std::reduce does not assume that the binary_op does not commute
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
In the following I assume x86-64 / trunk / -march=sapphirerapids -O3 -std=c++26 . (https://godbolt.org/z/rEqjTv6oP)
When summing a range of floats (eg std::array) using std::accumulate, the generated assembly is entirely sequential (eg vaddss). That should be optimal.
When summing a range of ints (eg std::array) using std::accumulate or std::reduce, the generated assembly uses packed additions (eg vpaddd). That should be optimal, and legal as integer addition is associative and commutes.
When summing a range of floats (eg std::array) using std::accumulate or std::reduce, with "-fassociative-math -fno-signed-zeros" the generated assembly uses packed additions (eg vaddps). That is legal because we explicitly lift the constraint that fp addition isn't associative and doesn't commute.
Finally, when summing a range of floats (eg std::array) using std::reduce, the generated assembly uses vectorisation such that fp non-associativity is given up but fp non-commutativity is maintained. This should not be required, as std::reduce assumes that the binary_op is associative and commutes (https://eel.is/c++draft/reduce#9). Therefore, I think it would be correct and faster to vectorise without assuming non-commutativity, yielding the same code as with "-fassociative-math -fno-signed-zeros".
Contributor guide
Assessment
This issue has not been assessed yet.