[llvm] [PowerPC] Exploit xxeval instruction for ternary patterns - part 1 (PR #141733)
Tony Varghese via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 23 00:55:44 PDT 2025
tonykuttai wrote:
Do we need to add a clang test for this?
Input file `t.cpp`
```
#include <altivec.h>
// Function to test ternary(A, xor(B, C), and(B, C)) for <16 x i8>
vector unsigned char ternary_A_xor_BC_and_BC_16x8(vector bool char a, vector unsigned char b, vector unsigned char c) {
// Use Clang's ternary operator on vectors - this should generate vselect
vector unsigned char xor_bc = vec_xor(b, c);
vector unsigned char and_bc = vec_and(b, c);
// Convert bool vector to mask and use ternary operator
return a ? and_bc : xor_bc;
}
```
`$LLVM_BUILD/bin/clang++ -mcpu=pwr10 -maltivec t.cpp -O3 -S -o t.s`
Can generate our desired asm code:
```
.abiversion 2
.file "xor-and.cpp"
.text
.globl _Z28ternary_A_xor_BC_and_BC_16x8Dv16_bDv16_hS0_ # -- Begin function _Z28ternary_A_xor_BC_and_BC_16x8Dv16_bDv16_hS0_
.p2align 4
.type _Z28ternary_A_xor_BC_and_BC_16x8Dv16_bDv16_hS0_, at function
_Z28ternary_A_xor_BC_and_BC_16x8Dv16_bDv16_hS0_: # @_Z28ternary_A_xor_BC_and_BC_16x8Dv16_bDv16_hS0_
.Lfunc_begin0:
.cfi_startproc
# %bb.0: # %entry
xxlxor 37, 37, 37
vcmpequb 2, 2, 5
xxeval 34, 34, 36, 35, 22 ==============> xxeval matching the ternary operation
blr
.long 0
.quad 0
.Lfunc_end0:
.size _Z28ternary_A_xor_BC_and_BC_16x8Dv16_bDv16_hS0_, .Lfunc_end0-.Lfunc_begin0
.cfi_endproc
# -- End function
.ident "clang version 21.0.0git"
.section ".note.GNU-stack","", at progbits
.addrsig
```
Note:
- `return a ? and_bc : xor_bc;` is inverted as opposed to the expected `a ? xor_bc : and_bc;` which this change supports.
- It is because I was getting the inverted logic in the IR for `return a ? xor_bc : and_bc;` as shown:
```
define dso_local noundef <16 x i8> @_Z28ternary_A_xor_BC_and_BC_16x8Dv16_bDv16_hS0_(<16 x i8> noundef %a, <16 x i8> noundef %b, <16 x i8> noundef %c) local_unnamed_addr #0 {
entry:
%xor.i = xor <16 x i8> %c, %b
%and.i = and <16 x i8> %c, %b
%vector_cond.not = icmp eq <16 x i8> %a, zeroinitializer
%vector_select = select <16 x i1> %vector_cond.not, <16 x i8> %and.i, <16 x i8> %xor.i
ret <16 x i8> %vector_select
}
```
https://github.com/llvm/llvm-project/pull/141733
More information about the llvm-commits
mailing list