[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