[llvm] [P10][XXEVAL] Exploit xxeval instruction for cases of the ternary(A, X, and(B, C)), ternary(A, X, B), ternary(A, X, C), ternary(A, X, xor(B, C)) forms. (PR #141733)
Tony Varghese via llvm-commits
llvm-commits at lists.llvm.org
Wed May 28 02:19:08 PDT 2025
- Previous message: [llvm] f0f666b - [LoopPeel] Add peeling tests with debug value and pointer inductions
- Next message: [llvm] [P10][XXEVAL] Exploit xxeval instruction for cases of the ternary(A, X, and(B, C)), ternary(A, X, B), ternary(A, X, C), ternary(A, X, xor(B, C)) forms. (PR #141733)
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
https://github.com/tonykuttai created https://github.com/llvm/llvm-project/pull/141733
## Description
<!--- Title/Description will be Subject/Body of commit message. -->
<!--- Please be concise and limit the subject line to 50 characters, -->
<!--- and wrap the Description at 72 characters. -->
<!--- Describe why this is required, what problem it solves. -->
`xxeval` instruction can be used for supporting the ternary patterns.
Supporting the following patterns in this change:
- `ternary(A, X, and(B,C))`
- `ternary(A, X, B)`
- `ternary(A, X, C)`
- `ternary(A, X, xor(B,C))`
This change make use of the patterns and its corresponding imm values to group the ternary operations so that appropriate tableGen multiclass were formed. The following patterns are handled:
```
Ternary Operators Imm Values
ternary(A, xor(B,C), and(B,C)) 22
ternary(A, nor(B,C), and(B,C)) 24
ternary(A, eqv(B,C), and(B,C)) 25
ternary(A, not(C), and(B,C)) 26
ternary(A, not(B), and(B,C)) 28
ternary(A, and(B,C), B) 49
ternary(A, nor(B,C), B) 56
ternary(A, eqv(B,C), B) 57
ternary(A, not(C), B) 58
ternary(A, nand(B,C), B) 62
ternary(A, and(B,C), C) 81
ternary(A, nor(B,C), C) 88
ternary(A, eqv(B,C), C) 89
ternary(A, nand(B,C), C) 94
ternary(A, and(B,C), xor(B,C)) 97
ternary(A, B, xor(B,C)) 99
ternary(A, C, xor(B,C)) 101
ternary(A, or(B,C), xor(B,C)) 103
ternary(A, nor(B,C), xor(B,C)) 104
```
`ternary(A, not(B), C) : 92` is omitted as it was a symmetrical to `ternary(A, not(C), B) : 58`
>From 75c802e2672ff48a46b7b746fff500d0e4e5f92a Mon Sep 17 00:00:00 2001
From: Tony Varghese <tony.varghese at ibm.com>
Date: Wed, 28 May 2025 06:40:25 +0000
Subject: [PATCH 1/2] [P10][xxeval] Support xxeval instructions for ternary
operations.
---
llvm/lib/Target/PowerPC/PPCInstrP10.td | 202 +++++++++++++++---
.../CodeGen/PowerPC/xxeval-vselect-x-and.ll | 164 ++++++++++++++
.../CodeGen/PowerPC/xxeval-vselect-x-b.ll | 156 ++++++++++++++
.../CodeGen/PowerPC/xxeval-vselect-x-c.ll | 128 +++++++++++
.../CodeGen/PowerPC/xxeval-vselect-x-xor.ll | 158 ++++++++++++++
5 files changed, 776 insertions(+), 32 deletions(-)
create mode 100644 llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
create mode 100644 llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
create mode 100644 llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
create mode 100644 llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
diff --git a/llvm/lib/Target/PowerPC/PPCInstrP10.td b/llvm/lib/Target/PowerPC/PPCInstrP10.td
index 39a1ab0d388a7..99f77e18e43a0 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrP10.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrP10.td
@@ -2159,8 +2159,133 @@ let AddedComplexity = 400, Predicates = [IsISA3_1, HasVSX] in {
(COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
}
-class xxevalPattern <dag pattern, bits<8> imm> :
- Pat<(v4i32 pattern), (XXEVAL $vA, $vB, $vC, imm)> {}
+class xxevalPattern <ValueType vt, dag pattern, bits<8> imm> :
+ Pat<(vt pattern), (XXEVAL $vA, $vB, $vC, imm)> {}
+
+class DagUnaryVNot<ValueType vt, string opstr>{
+ // Defines a class that returns the UnaryVNot dag for an operand string based on a value type.
+ dag res = !cond(
+ !eq(vt, v4i32) : !dag(vnot, [v4i32], [opstr]),
+ !eq(vt, v2i64) : (v2i64 (bitconvert (vnot (v4i32 !dag(bitconvert, [v2i64], [opstr])))))
+ );
+}
+
+class DagCondVNot<dag d, bit negate> {
+ // Defines a class that generates a vnot around the dag.
+ dag res = !if(!ne(negate, 0),
+ (vnot d),
+ d);
+}
+
+class XXEvalUnaryNot<ValueType vt> {
+ // Defines a wrapper class for unary NOT operations for v4i32 and v2i64 vector types.
+ // Unary NOT on operand B or C based on value type.
+ dag opB = DagUnaryVNot<vt, "vB">.res;
+ dag opC = DagUnaryVNot<vt, "vC">.res;
+}
+
+class XXEvalBinaryPattern<ValueType vt, SDPatternOperator op, bit notResult = 0> {
+ // Defines a wrapper class for binary patterns with optional NOT on result.
+ // Generate op pattern with optional NOT wrapping for result depending on "notResult".
+ dag opPat = !cond(
+ !eq(vt, v4i32) : DagCondVNot<(op v4i32:$vB, v4i32:$vC), notResult>.res,
+ !eq(vt, v2i64) : (v2i64 (bitconvert DagCondVNot<(op
+ (v4i32 (bitconvert v2i64:$vB)),
+ (v4i32 (bitconvert v2i64:$vC))), notResult>.res))
+ );
+}
+
+multiclass XXEvalVSelectWithXAnd<ValueType vt, bits<8> baseImm> {
+ // Multiclass for Ternary(A, X, and(B, C)) style patterns.
+ // Ternary(A, xor(B,C), and(B,C)) => imm: baseImm
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, xor>.opPat, XXEvalBinaryPattern<vt, and>.opPat),
+ baseImm>;
+ // Ternary(A, nor(B,C), and(B,C)) => imm: baseImm + 2
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or, 1>.opPat, XXEvalBinaryPattern<vt, and>.opPat),
+ !add(baseImm, 2)>;
+ // Ternary(A, eqv(B,C), and(B,C)) => imm: baseImm + 3
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, xor, 1>.opPat, XXEvalBinaryPattern<vt, and>.opPat),
+ !add(baseImm, 3)>;
+ // Ternary(A, not(C), and(B,C)) => imm: baseImm + 4
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalUnaryNot<vt>.opC, XXEvalBinaryPattern<vt, and>.opPat),
+ !add(baseImm, 4)>;
+ // Ternary(A, not(B), and(B,C)) => imm: baseImm + 6
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalUnaryNot<vt>.opB, XXEvalBinaryPattern<vt, and>.opPat),
+ !add(baseImm, 6)>;
+}
+
+multiclass XXEvalVSelectWithXB<ValueType vt, bits<8> baseImm>{
+ // Multiclass for Ternary(A, X, B) style patterns
+ // Ternary(A, and(B,C), B) => imm: baseImm
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and>.opPat, vt:$vB),
+ baseImm>;
+ // Ternary(A, nor(B,C), B) => imm: baseImm + 7
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or, 1>.opPat, vt:$vB),
+ !add(baseImm, 7)>;
+ // Ternary(A, eqv(B,C), B) => imm: baseImm + 8
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, xor, 1>.opPat, vt:$vB),
+ !add(baseImm, 8)>;
+ // Ternary(A, not(C), B) => imm: baseImm + 9
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalUnaryNot<vt>.opC, vt:$vB),
+ !add(baseImm, 9)>;
+ // Ternary(A, nand(B,C), B) => imm: baseImm + 13
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and, 1>.opPat, vt:$vB),
+ !add(baseImm, 13)>;
+}
+
+multiclass XXEvalVSelectWithXC<ValueType vt, bits<8> baseImm>{
+ // Multiclass for Ternary(A, X, C) style patterns
+ // Ternary(A, and(B,C), C) => imm: baseImm
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and>.opPat, vt:$vC),
+ baseImm>;
+ // Ternary(A, nor(B,C), C) => imm: baseImm + 7
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or, 1>.opPat, vt:$vC),
+ !add(baseImm, 7)>;
+ // Ternary(A, eqv(B,C), C) => imm: baseImm + 8
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, xor, 1>.opPat, vt:$vC),
+ !add(baseImm, 8)>;
+ // Ternary(A, nand(B,C), C) => imm: baseImm + 13
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and, 1>.opPat, vt:$vC),
+ !add(baseImm, 13)>;
+}
+
+multiclass XXEvalVSelectWithXXor<ValueType vt, bits<8> baseImm>{
+ // Multiclass for Ternary(A, X, xor(B,C)) style patterns
+ // Ternary(A, and(B,C), xor(B,C)) => imm: baseImm
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and>.opPat, XXEvalBinaryPattern<vt, xor>.opPat),
+ baseImm>;
+ // Ternary(A, B, xor(B,C)) => imm: baseImm + 2
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, vt:$vB, XXEvalBinaryPattern<vt, xor>.opPat),
+ !add(baseImm, 2)>;
+ // Ternary(A, C, xor(B,C)) => imm: baseImm + 4
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, vt:$vC, XXEvalBinaryPattern<vt, xor>.opPat),
+ !add(baseImm, 4)>;
+ // Ternary(A, or(B,C), xor(B,C)) => imm: baseImm + 6
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or>.opPat, XXEvalBinaryPattern<vt, xor>.opPat),
+ !add(baseImm, 6)>;
+ // Ternary(A, nor(B,C), xor(B,C)) => imm: baseImm + 7
+ def : xxevalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or, 1>.opPat, XXEvalBinaryPattern<vt, xor>.opPat),
+ !add(baseImm, 7)>;
+}
let Predicates = [PrefixInstrs, HasP10Vector] in {
let AddedComplexity = 400 in {
@@ -2192,83 +2317,96 @@ let Predicates = [PrefixInstrs, HasP10Vector] in {
// Anonymous patterns for XXEVAL
// AND
// and(A, B, C)
- def : xxevalPattern<(and v4i32:$vA, (and v4i32:$vB, v4i32:$vC)), 1>;
+ def : xxevalPattern<v4i32, (and v4i32:$vA, (and v4i32:$vB, v4i32:$vC)), 1>;
// and(A, xor(B, C))
- def : xxevalPattern<(and v4i32:$vA, (xor v4i32:$vB, v4i32:$vC)), 6>;
+ def : xxevalPattern<v4i32, (and v4i32:$vA, (xor v4i32:$vB, v4i32:$vC)), 6>;
// and(A, or(B, C))
- def : xxevalPattern<(and v4i32:$vA, (or v4i32:$vB, v4i32:$vC)), 7>;
+ def : xxevalPattern<v4i32, (and v4i32:$vA, (or v4i32:$vB, v4i32:$vC)), 7>;
// and(A, nor(B, C))
- def : xxevalPattern<(and v4i32:$vA, (vnot (or v4i32:$vB, v4i32:$vC))), 8>;
+ def : xxevalPattern<v4i32, (and v4i32:$vA, (vnot (or v4i32:$vB, v4i32:$vC))), 8>;
// and(A, eqv(B, C))
- def : xxevalPattern<(and v4i32:$vA, (vnot (xor v4i32:$vB, v4i32:$vC))), 9>;
+ def : xxevalPattern<v4i32, (and v4i32:$vA, (vnot (xor v4i32:$vB, v4i32:$vC))), 9>;
// and(A, nand(B, C))
- def : xxevalPattern<(and v4i32:$vA, (vnot (and v4i32:$vB, v4i32:$vC))), 14>;
+ def : xxevalPattern<v4i32, (and v4i32:$vA, (vnot (and v4i32:$vB, v4i32:$vC))), 14>;
// NAND
// nand(A, B, C)
- def : xxevalPattern<(vnot (and v4i32:$vA, (and v4i32:$vB, v4i32:$vC))),
+ def : xxevalPattern<v4i32, (vnot (and v4i32:$vA, (and v4i32:$vB, v4i32:$vC))),
!sub(255, 1)>;
// nand(A, xor(B, C))
- def : xxevalPattern<(vnot (and v4i32:$vA, (xor v4i32:$vB, v4i32:$vC))),
+ def : xxevalPattern<v4i32, (vnot (and v4i32:$vA, (xor v4i32:$vB, v4i32:$vC))),
!sub(255, 6)>;
// nand(A, or(B, C))
- def : xxevalPattern<(vnot (and v4i32:$vA, (or v4i32:$vB, v4i32:$vC))),
+ def : xxevalPattern<v4i32, (vnot (and v4i32:$vA, (or v4i32:$vB, v4i32:$vC))),
!sub(255, 7)>;
// nand(A, nor(B, C))
- def : xxevalPattern<(or (vnot v4i32:$vA), (or v4i32:$vB, v4i32:$vC)),
+ def : xxevalPattern<v4i32, (or (vnot v4i32:$vA), (or v4i32:$vB, v4i32:$vC)),
!sub(255, 8)>;
// nand(A, eqv(B, C))
- def : xxevalPattern<(or (vnot v4i32:$vA), (xor v4i32:$vB, v4i32:$vC)),
+ def : xxevalPattern<v4i32, (or (vnot v4i32:$vA), (xor v4i32:$vB, v4i32:$vC)),
!sub(255, 9)>;
// nand(A, nand(B, C))
- def : xxevalPattern<(or (vnot v4i32:$vA), (and v4i32:$vB, v4i32:$vC)),
+ def : xxevalPattern<v4i32, (or (vnot v4i32:$vA), (and v4i32:$vB, v4i32:$vC)),
!sub(255, 14)>;
// EQV
// (eqv A, B, C)
- def : xxevalPattern<(or (and v4i32:$vA, (and v4i32:$vB, v4i32:$vC)),
+ def : xxevalPattern<v4i32, (or (and v4i32:$vA, (and v4i32:$vB, v4i32:$vC)),
(vnot (or v4i32:$vA, (or v4i32:$vB, v4i32:$vC)))),
150>;
// (eqv A, (and B, C))
- def : xxevalPattern<(vnot (xor v4i32:$vA, (and v4i32:$vB, v4i32:$vC))), 225>;
+ def : xxevalPattern<v4i32, (vnot (xor v4i32:$vA, (and v4i32:$vB, v4i32:$vC))), 225>;
// (eqv A, (or B, C))
- def : xxevalPattern<(vnot (xor v4i32:$vA, (or v4i32:$vB, v4i32:$vC))), 135>;
+ def : xxevalPattern<v4i32, (vnot (xor v4i32:$vA, (or v4i32:$vB, v4i32:$vC))), 135>;
// NOR
// (nor A, B, C)
- def : xxevalPattern<(vnot (or v4i32:$vA, (or v4i32:$vB, v4i32:$vC))), 128>;
+ def : xxevalPattern<v4i32, (vnot (or v4i32:$vA, (or v4i32:$vB, v4i32:$vC))), 128>;
// (nor A, (and B, C))
- def : xxevalPattern<(vnot (or v4i32:$vA, (and v4i32:$vB, v4i32:$vC))), 224>;
+ def : xxevalPattern<v4i32, (vnot (or v4i32:$vA, (and v4i32:$vB, v4i32:$vC))), 224>;
// (nor A, (eqv B, C))
- def : xxevalPattern<(and (vnot v4i32:$vA), (xor v4i32:$vB, v4i32:$vC)), 96>;
+ def : xxevalPattern<v4i32, (and (vnot v4i32:$vA), (xor v4i32:$vB, v4i32:$vC)), 96>;
// (nor A, (nand B, C))
- def : xxevalPattern<(and (vnot v4i32:$vA), (and v4i32:$vB, v4i32:$vC)), 16>;
+ def : xxevalPattern<v4i32, (and (vnot v4i32:$vA), (and v4i32:$vB, v4i32:$vC)), 16>;
// (nor A, (nor B, C))
- def : xxevalPattern<(and (vnot v4i32:$vA), (or v4i32:$vB, v4i32:$vC)), 112>;
+ def : xxevalPattern<v4i32, (and (vnot v4i32:$vA), (or v4i32:$vB, v4i32:$vC)), 112>;
// (nor A, (xor B, C))
- def : xxevalPattern<(vnot (or v4i32:$vA, (xor v4i32:$vB, v4i32:$vC))), 144>;
+ def : xxevalPattern<v4i32, (vnot (or v4i32:$vA, (xor v4i32:$vB, v4i32:$vC))), 144>;
// OR
// (or A, B, C)
- def : xxevalPattern<(or v4i32:$vA, (or v4i32:$vB, v4i32:$vC)), 127>;
+ def : xxevalPattern<v4i32, (or v4i32:$vA, (or v4i32:$vB, v4i32:$vC)), 127>;
// (or A, (and B, C))
- def : xxevalPattern<(or v4i32:$vA, (and v4i32:$vB, v4i32:$vC)), 31>;
+ def : xxevalPattern<v4i32, (or v4i32:$vA, (and v4i32:$vB, v4i32:$vC)), 31>;
// (or A, (eqv B, C))
- def : xxevalPattern<(or v4i32:$vA, (vnot (xor v4i32:$vB, v4i32:$vC))), 159>;
+ def : xxevalPattern<v4i32, (or v4i32:$vA, (vnot (xor v4i32:$vB, v4i32:$vC))), 159>;
// (or A, (nand B, C))
- def : xxevalPattern<(or v4i32:$vA, (vnot (and v4i32:$vB, v4i32:$vC))), 239>;
+ def : xxevalPattern<v4i32, (or v4i32:$vA, (vnot (and v4i32:$vB, v4i32:$vC))), 239>;
// (or A, (nor B, C))
- def : xxevalPattern<(or v4i32:$vA, (vnot (or v4i32:$vB, v4i32:$vC))), 143>;
+ def : xxevalPattern<v4i32, (or v4i32:$vA, (vnot (or v4i32:$vB, v4i32:$vC))), 143>;
// (or A, (xor B, C))
- def : xxevalPattern<(or v4i32:$vA, (xor v4i32:$vB, v4i32:$vC)), 111>;
+ def : xxevalPattern<v4i32, (or v4i32:$vA, (xor v4i32:$vB, v4i32:$vC)), 111>;
// XOR
// (xor A, B, C)
- def : xxevalPattern<(xor v4i32:$vA, (xor v4i32:$vB, v4i32:$vC)), 105>;
+ def : xxevalPattern<v4i32, (xor v4i32:$vA, (xor v4i32:$vB, v4i32:$vC)), 105>;
// (xor A, (and B, C))
- def : xxevalPattern<(xor v4i32:$vA, (and v4i32:$vB, v4i32:$vC)), 30>;
+ def : xxevalPattern<v4i32, (xor v4i32:$vA, (and v4i32:$vB, v4i32:$vC)), 30>;
// (xor A, (or B, C))
- def : xxevalPattern<(xor v4i32:$vA, (or v4i32:$vB, v4i32:$vC)), 120>;
+ def : xxevalPattern<v4i32, (xor v4i32:$vA, (or v4i32:$vB, v4i32:$vC)), 120>;
+
+ // Ternary operation support with the xxeval instruction.
+ defm : XXEvalVSelectWithXAnd<v4i32, 22>;
+ defm : XXEvalVSelectWithXAnd<v2i64, 22>;
+
+ defm : XXEvalVSelectWithXB<v4i32, 49>;
+ defm : XXEvalVSelectWithXB<v2i64, 49>;
+
+ defm : XXEvalVSelectWithXC<v4i32, 81>;
+ defm : XXEvalVSelectWithXC<v2i64, 81>;
+
+ defm : XXEvalVSelectWithXXor<v4i32, 97>;
+ defm : XXEvalVSelectWithXXor<v2i64, 97>;
// Anonymous patterns to select prefixed VSX loads and stores.
// Load / Store f128
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
new file mode 100644
index 0000000000000..f666bc337b27e
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
@@ -0,0 +1,164 @@
+; Test file to verify the emission of xxeval instructions when ternary operators are used.
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc64le-unknown-unknown \
+; RUN: -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc-ibm-aix-xcoff \
+; RUN: -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc64-ibm-aix-xcoff \
+; RUN: -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; Function to test ternary(A, xor(B, C), and(B, C)) for <4 x i32>
+; CHECK-LABEL: ternary_A_xor_BC_and_BC_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 22
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_xor_BC_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %xor = xor <4 x i32> %B, %C
+ %and = and <4 x i32> %B, %C
+ %res = select <4 x i1> %A, <4 x i32> %xor, <4 x i32> %and
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, xor(B, C), and(B, C)) for <2 x i64>
+; CHECK-LABEL: ternary_A_xor_BC_and_BC_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 22
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_xor_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %xor = xor <2 x i64> %B, %C
+ %and = and <2 x i64> %B, %C
+ %res = select <2 x i1> %A, <2 x i64> %xor, <2 x i64> %and
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nor(B, C), and(B, C)) for <4 x i32>
+; CHECK-LABEL: ternary_A_nor_BC_and_BC_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 24
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_nor_BC_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %or = or <4 x i32> %B, %C
+ %nor = xor <4 x i32> %or, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector NOR operation
+ %and = and <4 x i32> %B, %C
+ %res = select <4 x i1> %A, <4 x i32> %nor, <4 x i32> %and
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nor(B, C), and(B, C)) for <2 x i64>
+; CHECK-LABEL: ternary_A_nor_BC_and_BC_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 24
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_nor_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %or = or <2 x i64> %B, %C
+ %nor = xor <2 x i64> %or, <i64 -1, i64 -1> ; Vector NOR operation
+ %and = and <2 x i64> %B, %C
+ %res = select <2 x i1> %A, <2 x i64> %nor, <2 x i64> %and
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, eqv(B, C), and(B, C)) for <4 x i32>
+; CHECK-LABEL: ternary_A_eqv_BC_and_BC_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 25
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_eqv_BC_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %xor = xor <4 x i32> %B, %C
+ %eqv = xor <4 x i32> %xor, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector eqv operation
+ %and = and <4 x i32> %B, %C
+ %res = select <4 x i1> %A, <4 x i32> %eqv, <4 x i32> %and
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, eqv(B, C), and(B, C)) for <2 x i64>
+; CHECK-LABEL: ternary_A_eqv_BC_and_BC_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 25
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_eqv_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %xor = xor <2 x i64> %B, %C
+ %eqv = xor <2 x i64> %xor, <i64 -1, i64 -1> ; Vector eqv operation
+ %and = and <2 x i64> %B, %C
+ %res = select <2 x i1> %A, <2 x i64> %eqv, <2 x i64> %and
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, not(C), and(B, C)) for <4 x i32>
+; CHECK-LABEL: ternary_A_not_C_and_BC_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 26
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_not_C_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %not = xor <4 x i32> %C, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
+ %and = and <4 x i32> %B, %C
+ %res = select <4 x i1> %A, <4 x i32> %not, <4 x i32> %and
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, not(C), and(B, C)) for <2 x i64>
+; CHECK-LABEL: ternary_A_not_C_and_BC_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 26
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_not_C_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
+ %and = and <2 x i64> %B, %C
+ %res = select <2 x i1> %A, <2 x i64> %not, <2 x i64> %and
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, not(B), and(B, C)) for <4 x i32>
+; CHECK-LABEL: ternary_A_not_B_and_BC_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 28
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_not_B_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %not = xor <4 x i32> %B, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
+ %and = and <4 x i32> %B, %C
+ %res = select <4 x i1> %A, <4 x i32> %not, <4 x i32> %and
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, not(B), and(B, C)) for <2 x i64>
+; CHECK-LABEL: ternary_A_not_B_and_BC_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 28
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_not_B_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %not = xor <2 x i64> %B, <i64 -1, i64 -1> ; Vector not operation
+ %and = and <2 x i64> %B, %C
+ %res = select <2 x i1> %A, <2 x i64> %not, <2 x i64> %and
+ ret <2 x i64> %res
+}
\ No newline at end of file
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
new file mode 100644
index 0000000000000..0c7fb97535520
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
@@ -0,0 +1,156 @@
+; Test file to verify the emission of xxeval instructions when ternary operators are used.
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc64le-unknown-unknown \
+; RUN: -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc-ibm-aix-xcoff \
+; RUN: -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc64-ibm-aix-xcoff \
+; RUN: -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; Function to test ternary(A, and(B, C), B) for <4 x i32>
+; CHECK-LABEL: ternary_A_and_BC_B_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 49
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_and_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %and = and <4 x i32> %B, %C
+ %res = select <4 x i1> %A, <4 x i32> %and, <4 x i32> %B
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, and(B, C), B) for <2 x i64>
+; CHECK-LABEL: ternary_A_and_BC_B_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 49
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_and_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %and = and <2 x i64> %B, %C
+ %res = select <2 x i1> %A, <2 x i64> %and, <2 x i64> %B
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nor(B, C), B) for <4 x i32>
+; CHECK-LABEL: ternary_A_nor_BC_B_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 56
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_nor_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %or = or <4 x i32> %B, %C
+ %nor = xor <4 x i32> %or, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector NOR operation
+ %res = select <4 x i1> %A, <4 x i32> %nor, <4 x i32> %B
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nor(B, C), B) for <2 x i64>
+; CHECK-LABEL: ternary_A_nor_BC_B_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 56
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_nor_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %or = or <2 x i64> %B, %C
+ %nor = xor <2 x i64> %or, <i64 -1, i64 -1> ; Vector NOR operation
+ %res = select <2 x i1> %A, <2 x i64> %nor, <2 x i64> %B
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, eqv(B, C), B) for <4 x i32>
+; CHECK-LABEL: ternary_A_eqv_BC_B_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 57
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_eqv_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %xor = xor <4 x i32> %B, %C
+ %eqv = xor <4 x i32> %xor, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector eqv operation
+ %res = select <4 x i1> %A, <4 x i32> %eqv, <4 x i32> %B
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, eqv(B, C), B) for <2 x i64>
+; CHECK-LABEL: ternary_A_eqv_BC_B_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 57
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_eqv_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %xor = xor <2 x i64> %B, %C
+ %eqv = xor <2 x i64> %xor, <i64 -1, i64 -1> ; Vector eqv operation
+ %res = select <2 x i1> %A, <2 x i64> %eqv, <2 x i64> %B
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, not(C), B) for <4 x i32>
+; CHECK-LABEL: ternary_A_not_BC_B_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 58
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_not_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %not = xor <4 x i32> %C, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
+ %res = select <4 x i1> %A, <4 x i32> %not, <4 x i32> %B
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, not(C), B) for <2 x i64>
+; CHECK-LABEL: ternary_A_not_BC_B_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 58
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_not_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
+ %res = select <2 x i1> %A, <2 x i64> %not, <2 x i64> %B
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nand(B, C), B) for <4 x i32>
+; CHECK-LABEL: ternary_A_nand_BC_B_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 62
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_nand_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %and = and <4 x i32> %B, %C
+ %nand = xor <4 x i32> %and, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector nand operation
+ %res = select <4 x i1> %A, <4 x i32> %nand, <4 x i32> %B
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nand(B, C), B) for <2 x i64>
+; CHECK-LABEL: ternary_A_nand_BC_B_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 62
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_nand_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %and = and <2 x i64> %B, %C
+ %nand = xor <2 x i64> %and, <i64 -1, i64 -1> ; Vector nand operation
+ %res = select <2 x i1> %A, <2 x i64> %nand, <2 x i64> %B
+ ret <2 x i64> %res
+}
\ No newline at end of file
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
new file mode 100644
index 0000000000000..b599d4358186e
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
@@ -0,0 +1,128 @@
+; Test file to verify the emission of xxeval instructions when ternary operators are used.
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc64le-unknown-unknown \
+; RUN: -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc-ibm-aix-xcoff \
+; RUN: -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc64-ibm-aix-xcoff \
+; RUN: -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; Function to test ternary(A, and(B, C), C) for <4 x i32>
+; CHECK-LABEL: ternary_A_and_BC_C_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 81
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_and_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %and = and <4 x i32> %B, %C
+ %res = select <4 x i1> %A, <4 x i32> %and, <4 x i32> %C
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, and(B, C), C) for <2 x i64>
+; CHECK-LABEL: ternary_A_and_BC_C_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 81
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_and_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %and = and <2 x i64> %B, %C
+ %res = select <2 x i1> %A, <2 x i64> %and, <2 x i64> %C
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nor(B, C), C) for <4 x i32>
+; CHECK-LABEL: ternary_A_nor_BC_C_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 88
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_nor_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %or = or <4 x i32> %B, %C
+ %nor = xor <4 x i32> %or, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector NOR operation
+ %res = select <4 x i1> %A, <4 x i32> %nor, <4 x i32> %C
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nor(B, C), C) for <2 x i64>
+; CHECK-LABEL: ternary_A_nor_BC_C_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 88
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_nor_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %or = or <2 x i64> %B, %C
+ %nor = xor <2 x i64> %or, <i64 -1, i64 -1> ; Vector NOR operation
+ %res = select <2 x i1> %A, <2 x i64> %nor, <2 x i64> %C
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, eqv(B, C), C) for <4 x i32>
+; CHECK-LABEL: ternary_A_eqv_BC_C_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 89
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_eqv_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %xor = xor <4 x i32> %B, %C
+ %eqv = xor <4 x i32> %xor, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector eqv operation
+ %res = select <4 x i1> %A, <4 x i32> %eqv, <4 x i32> %C
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, eqv(B, C), C) for <2 x i64>
+; CHECK-LABEL: ternary_A_eqv_BC_C_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 89
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_eqv_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %xor = xor <2 x i64> %B, %C
+ %eqv = xor <2 x i64> %xor, <i64 -1, i64 -1> ; Vector eqv operation
+ %res = select <2 x i1> %A, <2 x i64> %eqv, <2 x i64> %C
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nand(B, C), C) for <4 x i32>
+; CHECK-LABEL: ternary_A_nand_BC_C_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 94
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_nand_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %and = and <4 x i32> %B, %C
+ %nand = xor <4 x i32> %and, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector nand operation
+ %res = select <4 x i1> %A, <4 x i32> %nand, <4 x i32> %C
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nand(B, C), C) for <2 x i64>
+; CHECK-LABEL: ternary_A_nand_BC_C_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 94
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_nand_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %and = and <2 x i64> %B, %C
+ %nand = xor <2 x i64> %and, <i64 -1, i64 -1> ; Vector nand operation
+ %res = select <2 x i1> %A, <2 x i64> %nand, <2 x i64> %C
+ ret <2 x i64> %res
+}
\ No newline at end of file
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
new file mode 100644
index 0000000000000..a1079dab964aa
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
@@ -0,0 +1,158 @@
+; Test file to verify the emission of xxeval instructions when ternary operators are used.
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc64le-unknown-unknown \
+; RUN: -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc-ibm-aix-xcoff \
+; RUN: -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc64-ibm-aix-xcoff \
+; RUN: -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; Function to test ternary(A, and(B, C), xor(B, C)) for <4 x i32>
+; CHECK-LABEL: ternary_A_and_BC_xor_BC_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 97
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_and_BC_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %and = and <4 x i32> %B, %C
+ %xor = xor <4 x i32> %B, %C
+ %res = select <4 x i1> %A, <4 x i32> %and, <4 x i32> %xor
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, and(B, C), xor(B, C)) for <2 x i64>
+; CHECK-LABEL: ternary_A_and_BC_xor_BC_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 97
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_and_BC_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %and = and <2 x i64> %B, %C
+ %xor = xor <2 x i64> %B, %C
+ %res = select <2 x i1> %A, <2 x i64> %and, <2 x i64> %xor
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, B, xor(B, C)) for <4 x i32>
+; CHECK-LABEL: ternary_A_B_xor_BC_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 99
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_B_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %xor = xor <4 x i32> %B, %C
+ %res = select <4 x i1> %A, <4 x i32> %B, <4 x i32> %xor
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, B, xor(B, C)) for <2 x i64>
+; CHECK-LABEL: ternary_A_B_xor_BC_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 99
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_B_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %xor = xor <2 x i64> %B, %C
+ %res = select <2 x i1> %A, <2 x i64> %B, <2 x i64> %xor
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, C, xor(B, C)) for <4 x i32>
+; CHECK-LABEL: ternary_A_C_xor_BC_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 101
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_C_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %xor = xor <4 x i32> %B, %C
+ %res = select <4 x i1> %A, <4 x i32> %C, <4 x i32> %xor
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, C, xor(B, C)) for <2 x i64>
+; CHECK-LABEL: ternary_A_C_xor_BC_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 101
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_C_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %xor = xor <2 x i64> %B, %C
+ %res = select <2 x i1> %A, <2 x i64> %C, <2 x i64> %xor
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, or(B, C), xor(B, C)) for <4 x i32>
+; CHECK-LABEL: ternary_A_or_BC_xor_BC_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 103
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_or_BC_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %or = or <4 x i32> %B, %C
+ %xor = xor <4 x i32> %B, %C
+ %res = select <4 x i1> %A, <4 x i32> %or, <4 x i32> %xor
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, or(B, C), xor(B, C)) for <2 x i64>
+; CHECK-LABEL: ternary_A_or_BC_xor_BC_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 103
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_or_BC_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %or = or <2 x i64> %B, %C
+ %xor = xor <2 x i64> %B, %C
+ %res = select <2 x i1> %A, <2 x i64> %or, <2 x i64> %xor
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nor(B, C), xor(B, C)) for <4 x i32>
+; CHECK-LABEL: ternary_A_nor_BC_xor_BC_4x32
+; CHECK: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 104
+; CHECK-NEXT: blr
+define dso_local <4 x i32> @ternary_A_nor_BC_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+ %or = or <4 x i32> %B, %C
+ %nor = xor <4 x i32> %or, <i32 -1, i32 -1, i32 -1, i32 -1> ; vector nor operation
+ %xor = xor <4 x i32> %B, %C
+ %res = select <4 x i1> %A, <4 x i32> %nor, <4 x i32> %xor
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nor(B, C), xor(B, C)) for <2 x i64>
+; CHECK-LABEL: ternary_A_nor_BC_xor_BC_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: xxsplti32dx v5, 1, 63
+; CHECK-NEXT: vsld v2, v2, v5
+; CHECK-NEXT: vsrad v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 104
+; CHECK-NEXT: blr
+define dso_local <2 x i64> @ternary_A_nor_BC_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+ %or = or <2 x i64> %B, %C
+ %nor = xor <2 x i64> %or, <i64 -1, i64 -1> ; vector nor operation
+ %xor = xor <2 x i64> %B, %C
+ %res = select <2 x i1> %A, <2 x i64> %nor, <2 x i64> %xor
+ ret <2 x i64> %res
+}
>From fdc9a7cf16bce3504de9383f913b6a596c48ee8f Mon Sep 17 00:00:00 2001
From: Tony Varghese <tony.varghese at ibm.com>
Date: Wed, 28 May 2025 09:18:18 +0000
Subject: [PATCH 2/2] Modifed testcases to capture relevant instructions only
---
.../CodeGen/PowerPC/xxeval-vselect-x-and.ll | 50 ++++---------------
.../CodeGen/PowerPC/xxeval-vselect-x-b.ll | 50 ++++---------------
.../CodeGen/PowerPC/xxeval-vselect-x-c.ll | 40 +++------------
.../CodeGen/PowerPC/xxeval-vselect-x-xor.ll | 50 ++++---------------
4 files changed, 38 insertions(+), 152 deletions(-)
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
index f666bc337b27e..b30617469c901 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
@@ -11,9 +11,7 @@
; Function to test ternary(A, xor(B, C), and(B, C)) for <4 x i32>
; CHECK-LABEL: ternary_A_xor_BC_and_BC_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 22
+; CHECK: xxeval v2, v2, v3, v4, 22
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_xor_BC_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -25,11 +23,7 @@ entry:
; Function to test ternary(A, xor(B, C), and(B, C)) for <2 x i64>
; CHECK-LABEL: ternary_A_xor_BC_and_BC_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 22
+; CHECK: xxeval v2, v2, v3, v4, 22
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_xor_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
@@ -41,9 +35,7 @@ entry:
; Function to test ternary(A, nor(B, C), and(B, C)) for <4 x i32>
; CHECK-LABEL: ternary_A_nor_BC_and_BC_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 24
+; CHECK: xxeval v2, v2, v3, v4, 24
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_nor_BC_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -56,11 +48,7 @@ entry:
; Function to test ternary(A, nor(B, C), and(B, C)) for <2 x i64>
; CHECK-LABEL: ternary_A_nor_BC_and_BC_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 24
+; CHECK: xxeval v2, v2, v3, v4, 24
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_nor_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
@@ -73,9 +61,7 @@ entry:
; Function to test ternary(A, eqv(B, C), and(B, C)) for <4 x i32>
; CHECK-LABEL: ternary_A_eqv_BC_and_BC_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 25
+; CHECK: xxeval v2, v2, v3, v4, 25
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_eqv_BC_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -88,11 +74,7 @@ entry:
; Function to test ternary(A, eqv(B, C), and(B, C)) for <2 x i64>
; CHECK-LABEL: ternary_A_eqv_BC_and_BC_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 25
+; CHECK: xxeval v2, v2, v3, v4, 25
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_eqv_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
@@ -105,9 +87,7 @@ entry:
; Function to test ternary(A, not(C), and(B, C)) for <4 x i32>
; CHECK-LABEL: ternary_A_not_C_and_BC_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 26
+; CHECK: xxeval v2, v2, v3, v4, 26
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_not_C_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -119,11 +99,7 @@ entry:
; Function to test ternary(A, not(C), and(B, C)) for <2 x i64>
; CHECK-LABEL: ternary_A_not_C_and_BC_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 26
+; CHECK: xxeval v2, v2, v3, v4, 26
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_not_C_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
@@ -135,9 +111,7 @@ entry:
; Function to test ternary(A, not(B), and(B, C)) for <4 x i32>
; CHECK-LABEL: ternary_A_not_B_and_BC_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 28
+; CHECK: xxeval v2, v2, v3, v4, 28
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_not_B_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -149,11 +123,7 @@ entry:
; Function to test ternary(A, not(B), and(B, C)) for <2 x i64>
; CHECK-LABEL: ternary_A_not_B_and_BC_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 28
+; CHECK: xxeval v2, v2, v3, v4, 28
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_not_B_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
index 0c7fb97535520..7ab5fa7d62688 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
@@ -11,9 +11,7 @@
; Function to test ternary(A, and(B, C), B) for <4 x i32>
; CHECK-LABEL: ternary_A_and_BC_B_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 49
+; CHECK: xxeval v2, v2, v3, v4, 49
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_and_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -24,11 +22,7 @@ entry:
; Function to test ternary(A, and(B, C), B) for <2 x i64>
; CHECK-LABEL: ternary_A_and_BC_B_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 49
+; CHECK: xxeval v2, v2, v3, v4, 49
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_and_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
@@ -39,9 +33,7 @@ entry:
; Function to test ternary(A, nor(B, C), B) for <4 x i32>
; CHECK-LABEL: ternary_A_nor_BC_B_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 56
+; CHECK: xxeval v2, v2, v3, v4, 56
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_nor_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -53,11 +45,7 @@ entry:
; Function to test ternary(A, nor(B, C), B) for <2 x i64>
; CHECK-LABEL: ternary_A_nor_BC_B_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 56
+; CHECK: xxeval v2, v2, v3, v4, 56
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_nor_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
@@ -69,9 +57,7 @@ entry:
; Function to test ternary(A, eqv(B, C), B) for <4 x i32>
; CHECK-LABEL: ternary_A_eqv_BC_B_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 57
+; CHECK: xxeval v2, v2, v3, v4, 57
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_eqv_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -83,11 +69,7 @@ entry:
; Function to test ternary(A, eqv(B, C), B) for <2 x i64>
; CHECK-LABEL: ternary_A_eqv_BC_B_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 57
+; CHECK: xxeval v2, v2, v3, v4, 57
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_eqv_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
@@ -99,9 +81,7 @@ entry:
; Function to test ternary(A, not(C), B) for <4 x i32>
; CHECK-LABEL: ternary_A_not_BC_B_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 58
+; CHECK: xxeval v2, v2, v3, v4, 58
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_not_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -112,11 +92,7 @@ entry:
; Function to test ternary(A, not(C), B) for <2 x i64>
; CHECK-LABEL: ternary_A_not_BC_B_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 58
+; CHECK: xxeval v2, v2, v3, v4, 58
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_not_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
@@ -127,9 +103,7 @@ entry:
; Function to test ternary(A, nand(B, C), B) for <4 x i32>
; CHECK-LABEL: ternary_A_nand_BC_B_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 62
+; CHECK: xxeval v2, v2, v3, v4, 62
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_nand_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -141,11 +115,7 @@ entry:
; Function to test ternary(A, nand(B, C), B) for <2 x i64>
; CHECK-LABEL: ternary_A_nand_BC_B_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 62
+; CHECK: xxeval v2, v2, v3, v4, 62
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_nand_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
index b599d4358186e..01d6f3dde99bb 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
@@ -11,9 +11,7 @@
; Function to test ternary(A, and(B, C), C) for <4 x i32>
; CHECK-LABEL: ternary_A_and_BC_C_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 81
+; CHECK: xxeval v2, v2, v3, v4, 81
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_and_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -24,11 +22,7 @@ entry:
; Function to test ternary(A, and(B, C), C) for <2 x i64>
; CHECK-LABEL: ternary_A_and_BC_C_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 81
+; CHECK: xxeval v2, v2, v3, v4, 81
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_and_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
@@ -39,9 +33,7 @@ entry:
; Function to test ternary(A, nor(B, C), C) for <4 x i32>
; CHECK-LABEL: ternary_A_nor_BC_C_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 88
+; CHECK: xxeval v2, v2, v3, v4, 88
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_nor_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -53,11 +45,7 @@ entry:
; Function to test ternary(A, nor(B, C), C) for <2 x i64>
; CHECK-LABEL: ternary_A_nor_BC_C_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 88
+; CHECK: xxeval v2, v2, v3, v4, 88
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_nor_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
@@ -69,9 +57,7 @@ entry:
; Function to test ternary(A, eqv(B, C), C) for <4 x i32>
; CHECK-LABEL: ternary_A_eqv_BC_C_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 89
+; CHECK: xxeval v2, v2, v3, v4, 89
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_eqv_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -83,11 +69,7 @@ entry:
; Function to test ternary(A, eqv(B, C), C) for <2 x i64>
; CHECK-LABEL: ternary_A_eqv_BC_C_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 89
+; CHECK: xxeval v2, v2, v3, v4, 89
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_eqv_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
@@ -99,9 +81,7 @@ entry:
; Function to test ternary(A, nand(B, C), C) for <4 x i32>
; CHECK-LABEL: ternary_A_nand_BC_C_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 94
+; CHECK: xxeval v2, v2, v3, v4, 94
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_nand_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -113,11 +93,7 @@ entry:
; Function to test ternary(A, nand(B, C), C) for <2 x i64>
; CHECK-LABEL: ternary_A_nand_BC_C_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 94
+; CHECK: xxeval v2, v2, v3, v4, 94
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_nand_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
index a1079dab964aa..2509ea8820e02 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
@@ -11,9 +11,7 @@
; Function to test ternary(A, and(B, C), xor(B, C)) for <4 x i32>
; CHECK-LABEL: ternary_A_and_BC_xor_BC_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 97
+; CHECK: xxeval v2, v2, v3, v4, 97
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_and_BC_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -25,11 +23,7 @@ entry:
; Function to test ternary(A, and(B, C), xor(B, C)) for <2 x i64>
; CHECK-LABEL: ternary_A_and_BC_xor_BC_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 97
+; CHECK: xxeval v2, v2, v3, v4, 97
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_and_BC_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
@@ -41,9 +35,7 @@ entry:
; Function to test ternary(A, B, xor(B, C)) for <4 x i32>
; CHECK-LABEL: ternary_A_B_xor_BC_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 99
+; CHECK: xxeval v2, v2, v3, v4, 99
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_B_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -54,11 +46,7 @@ entry:
; Function to test ternary(A, B, xor(B, C)) for <2 x i64>
; CHECK-LABEL: ternary_A_B_xor_BC_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 99
+; CHECK: xxeval v2, v2, v3, v4, 99
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_B_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
@@ -69,9 +57,7 @@ entry:
; Function to test ternary(A, C, xor(B, C)) for <4 x i32>
; CHECK-LABEL: ternary_A_C_xor_BC_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 101
+; CHECK: xxeval v2, v2, v3, v4, 101
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_C_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -82,11 +68,7 @@ entry:
; Function to test ternary(A, C, xor(B, C)) for <2 x i64>
; CHECK-LABEL: ternary_A_C_xor_BC_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 101
+; CHECK: xxeval v2, v2, v3, v4, 101
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_C_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
@@ -97,9 +79,7 @@ entry:
; Function to test ternary(A, or(B, C), xor(B, C)) for <4 x i32>
; CHECK-LABEL: ternary_A_or_BC_xor_BC_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 103
+; CHECK: xxeval v2, v2, v3, v4, 103
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_or_BC_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -111,11 +91,7 @@ entry:
; Function to test ternary(A, or(B, C), xor(B, C)) for <2 x i64>
; CHECK-LABEL: ternary_A_or_BC_xor_BC_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 103
+; CHECK: xxeval v2, v2, v3, v4, 103
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_or_BC_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
@@ -127,9 +103,7 @@ entry:
; Function to test ternary(A, nor(B, C), xor(B, C)) for <4 x i32>
; CHECK-LABEL: ternary_A_nor_BC_xor_BC_4x32
-; CHECK: vslw v2, v2, v5
-; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 104
+; CHECK: xxeval v2, v2, v3, v4, 104
; CHECK-NEXT: blr
define dso_local <4 x i32> @ternary_A_nor_BC_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
entry:
@@ -142,11 +116,7 @@ entry:
; Function to test ternary(A, nor(B, C), xor(B, C)) for <2 x i64>
; CHECK-LABEL: ternary_A_nor_BC_xor_BC_2x64
-; CHECK: xxlxor v5, v5, v5
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, v3, v4, 104
+; CHECK: xxeval v2, v2, v3, v4, 104
; CHECK-NEXT: blr
define dso_local <2 x i64> @ternary_A_nor_BC_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
entry:
- Previous message: [llvm] f0f666b - [LoopPeel] Add peeling tests with debug value and pointer inductions
- Next message: [llvm] [P10][XXEVAL] Exploit xxeval instruction for cases of the ternary(A, X, and(B, C)), ternary(A, X, B), ternary(A, X, C), ternary(A, X, xor(B, C)) forms. (PR #141733)
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the llvm-commits
mailing list