[llvm] Exploit xxeval instruction for operations of the form ternary(A, X, NOR(B,C)), ternary(A, X, EQV(B,C)), ternary(A, X, NAND(B,C)), ternary(A, X, NOT(B)) and ternary(A, X, NOT(C)) (PR #158096)
Tony Varghese via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 11 08:11:13 PDT 2025
https://github.com/tonykuttai created https://github.com/llvm/llvm-project/pull/158096
Adds support for ternary equivalent operations of the form `ternary(A, X, nor(B,C))`, `ternary(A, X, eqv(B,C))`, `ternary(A, X, nand(B,C))`, `ternary(A, X, not(B))` and `ternary(A, X, not(C))` where `X=[xor(B,C)| nor(B,C)| eqv(B,C)| not(B)| not(C)| and(B,C)| nand(B,C)]`.
This adds support for `v4i32, v2i64, v16i8, v8i16` operand types for the following patterns.
List of xxeval equivalent ternary operations added and the corresponding imm value required:
```
ternary(A, and(B,C), nor(B,C)) 129
ternary(A, B, nor(B,C)) 131
ternary(A, C, nor(B,C)) 133
ternary(A, xor(B,C), nor(B,C)) 134
ternary(A, not(C), nor(B,C)) 138
ternary(A, not(B), nor(B,C)) 140
ternary(A, nand(B,C), nor(B,C)) 142
ternary(A, or(B,C), eqv(B,C)) 151
ternary(A, nor(B,C), eqv(B,C)) 152
ternary(A, not(C), eqv(B,C)) 154
ternary(A, nand(B,C), eqv(B,C)) 158
ternary(A, and(B,C), not(C)) 161
ternary(A, B, not(C)) 163
ternary(A, xor(B,C), not(C)) 166
ternary(A, or(B,C), not(C)) 167
ternary(A, not(B), not(C)) 172
ternary(A, nand(B,C), not(C)) 174
ternary(A, and(B,C), not(B)) 193
ternary(A, xor(B,C), not(B)) 198
ternary(A, or(B,C), not(B)) 199
ternary(A, nand(B,C), not(B)) 206
ternary(A, B, nand(B,C)) 227
ternary(A, C, nand(B,C)) 229
ternary(A, xor(B,C), nand(B,C)) 230
ternary(A, or(B,C), nand(B,C)) 231
ternary(A, eqv(B,C), nand(B,C)) 233
```
eg. `xxeval XT, XA, XB, XC, 129`
performs the ternary operation: `XA ? and(XB, XC) : nor(XB, XC)` and places the result in `XT`.
This is the continuation of:
- [[PowerPC] Exploit xxeval instruction for ternary patterns - ternary(A, X, and(B,C))](https://github.com/llvm/llvm-project/pull/141733#top)
- [[PowerPC] Exploit xxeval instruction for operations of the form ternary(A,X,B) and ternary(A,X,C).](https://github.com/llvm/llvm-project/pull/152956#top)
- [[PowerPC] Exploit xxeval instruction for operations of the form ternary(A,X, XOR(B,C)) and ternary(A,X, OR(B,C))](https://github.com/llvm/llvm-project/pull/157909#top)
>From a37d8b8917d4f2b417e9a913b984a1cb5cb9a587 Mon Sep 17 00:00:00 2001
From: Tony Varghese <tony.varghese at ibm.com>
Date: Thu, 11 Sep 2025 14:46:55 +0000
Subject: [PATCH] Exploit xxeval instruction for operations of the form
ternary(A, X, NOR(B,C)), ternary(A, X, EQV(B,C)), ternary(A, X, NAND(B,C)),
ternary(A, X, NOT(B)) and ternary(A, X, NOT(C))
---
llvm/lib/Target/PowerPC/PPCInstrP10.td | 191 ++++++-
.../CodeGen/PowerPC/xxeval-vselect-x-eqv.ll | 295 +++++++++++
.../CodeGen/PowerPC/xxeval-vselect-x-nand.ll | 352 +++++++++++++
.../CodeGen/PowerPC/xxeval-vselect-x-nor.ll | 490 ++++++++++++++++++
.../CodeGen/PowerPC/xxeval-vselect-x-not-b.ll | 275 ++++++++++
.../CodeGen/PowerPC/xxeval-vselect-x-not-c.ll | 401 ++++++++++++++
6 files changed, 2003 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/PowerPC/xxeval-vselect-x-eqv.ll
create mode 100644 llvm/test/CodeGen/PowerPC/xxeval-vselect-x-nand.ll
create mode 100644 llvm/test/CodeGen/PowerPC/xxeval-vselect-x-nor.ll
create mode 100644 llvm/test/CodeGen/PowerPC/xxeval-vselect-x-not-b.ll
create mode 100644 llvm/test/CodeGen/PowerPC/xxeval-vselect-x-not-c.ll
diff --git a/llvm/lib/Target/PowerPC/PPCInstrP10.td b/llvm/lib/Target/PowerPC/PPCInstrP10.td
index 149a44ddfc10c..0135eef76d997 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrP10.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrP10.td
@@ -2326,6 +2326,190 @@ multiclass XXEvalTernarySelectC<ValueType Vt>{
def : XXEvalPattern<Vt, (vselect Vt:$vA, (VNand Vt:$vB, Vt:$vC), Vt:$vC), 94>;
}
+// =============================================================================
+// XXEVAL Ternary Pattern Multiclass: XXEvalTernarySelectNor
+// This class matches the equivalent Ternary Operation: A ? f(B,C) : NOR(B,C)
+// and emit the corresponding xxeval instruction with the imm value.
+//
+// The patterns implement xxeval vector select operations where:
+// - A is the selector vector
+// - f(B,C) is the "true" case op in set {B, C, AND(B,C), XOR(B,C), NOT(C),
+// NOT(B), NAND(B,C)}
+// - C is the "false" case op NOR(B,C)
+// =============================================================================
+multiclass XXEvalTernarySelectNor<ValueType Vt>{
+ // Pattern: (A ? AND(B,C) : NOR(B,C)) XXEVAL immediate value: 129
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VAnd Vt:$vB, Vt:$vC), (VNor Vt:$vB, Vt:$vC)),
+ 129>;
+
+ // Pattern: (A ? B : NOR(B,C)) XXEVAL immediate value: 131
+ def : XXEvalPattern<Vt, (vselect Vt:$vA, Vt:$vB, (VNor Vt:$vB, Vt:$vC)),131>;
+
+ // Pattern: (A ? C : NOR(B,C)) XXEVAL immediate value: 133
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, Vt:$vC, (VNor Vt:$vB, Vt:$vC)),
+ 133>;
+
+ // Pattern: (A ? XOR(B,C) : NOR(B,C)) XXEVAL immediate value: 134
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VXor Vt:$vB, Vt:$vC), (VNor Vt:$vB, Vt:$vC)),
+ 134>;
+
+ // Pattern: (A ? NOT(C) : NOR(B,C)) XXEVAL immediate value: 138
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VNot Vt:$vC), (VNor Vt:$vB, Vt:$vC)),
+ 138>;
+
+ // Pattern: (A ? NOT(B) : NOR(B,C)) XXEVAL immediate value: 140
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VNot Vt:$vB), (VNor Vt:$vB, Vt:$vC)),
+ 140>;
+
+ // Pattern: (A ? NAND(B,C) : NOR(B,C)) XXEVAL immediate value: 142
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VNand Vt:$vB, Vt:$vC), (VNor Vt:$vB, Vt:$vC)),
+ 142>;
+}
+
+// =============================================================================
+// XXEVAL Ternary Pattern Multiclass: XXEvalTernarySelectEqv
+// This class matches the equivalent Ternary Operation: A ? f(B,C) : EQV(B,C)
+// and emit the corresponding xxeval instruction with the imm value.
+//
+// The patterns implement xxeval vector select operations where:
+// - A is the selector vector
+// - f(B,C) is the "true" case op in set {OR(B,C), NOR(B,C), NAND(B,C), NOT(B),
+// NOT(C)}
+// - C is the "false" case op EQV(B,C)
+// =============================================================================
+multiclass XXEvalTernarySelectEqv<ValueType Vt>{
+ // Pattern: (A ? OR(B,C) : EQV(B,C)) XXEVAL immediate value: 151
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VOr Vt:$vB, Vt:$vC), (VEqv Vt:$vB, Vt:$vC)),
+ 151>;
+
+ // Pattern: (A ? NOR(B,C) : EQV(B,C)) XXEVAL immediate value: 152
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VNor Vt:$vB, Vt:$vC), (VEqv Vt:$vB, Vt:$vC)),
+ 152>;
+
+ // Pattern: (A ? NOT(C) : EQV(B,C)) XXEVAL immediate value: 154
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VNot Vt:$vC), (VEqv Vt:$vB, Vt:$vC)),
+ 154>;
+
+ // Pattern: (A ? NAND(B,C) : EQV(B,C)) XXEVAL immediate value: 158
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VNand Vt:$vB, Vt:$vC), (VEqv Vt:$vB, Vt:$vC)),
+ 158>;
+}
+
+// =============================================================================
+// XXEVAL Ternary Pattern Multiclass: XXEvalTernarySelectNotC
+// This class matches the equivalent Ternary Operation: A ? f(B,C) : NOT(C)
+// and emit the corresponding xxeval instruction with the imm value.
+//
+// The patterns implement xxeval vector select operations where:
+// - A is the selector vector
+// - f(B,C) is the "true" case op in set {AND(B,C), OR(B,C), XOR(B,C), NAND(B,C),
+// B, NOT(B)}
+// - C is the "false" case op NOT(C)
+// =============================================================================
+multiclass XXEvalTernarySelectNotC<ValueType Vt>{
+ // Pattern: (A ? AND(B,C) : NOT(C)) XXEVAL immediate value: 161
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VAnd Vt:$vB, Vt:$vC), (VNot Vt:$vC)), 161>;
+
+ // Pattern: (A ? B : NOT(C)) XXEVAL immediate value: 163
+ def : XXEvalPattern<Vt, (vselect Vt:$vA, Vt:$vB, (VNot Vt:$vC)), 163>;
+
+ // Pattern: (A ? XOR(B,C) : NOT(C)) XXEVAL immediate value: 166
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VXor Vt:$vB, Vt:$vC), (VNot Vt:$vC)), 166>;
+
+ // Pattern: (A ? OR(B,C) : NOT(C)) XXEVAL immediate value: 167
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VOr Vt:$vB, Vt:$vC), (VNot Vt:$vC)), 167>;
+
+ // Pattern: (A ? NOT(B) : NOT(C)) XXEVAL immediate value: 172
+ def : XXEvalPattern<Vt, (vselect Vt:$vA, (VNot Vt:$vB), (VNot Vt:$vC)), 172>;
+
+ // Pattern: (A ? NAND(B,C) : NOT(C)) XXEVAL immediate value: 174
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VNand Vt:$vB, Vt:$vC), (VNot Vt:$vC)), 174>;
+}
+
+// =============================================================================
+// XXEVAL Ternary Pattern Multiclass: XXEvalTernarySelectNotB
+// This class matches the equivalent Ternary Operation: A ? f(B,C) : NOT(B)
+// and emit the corresponding xxeval instruction with the imm value.
+//
+// The patterns implement xxeval vector select operations where:
+// - A is the selector vector
+// - f(B,C) is the "true" case op in set {AND(B,C), OR(B,C), XOR(B,C), NAND(B,C),
+// C, NOT(B)}
+// - C is the "false" case op NOT(B)
+// =============================================================================
+multiclass XXEvalTernarySelectNotB<ValueType Vt>{
+ // Pattern: (A ? AND(B,C) : NOT(B)) XXEVAL immediate value: 193
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VAnd Vt:$vB, Vt:$vC), (VNot Vt:$vB)), 193>;
+
+ // Pattern: (A ? C : NOT(B)) XXEVAL immediate value: 197
+ def : XXEvalPattern<Vt, (vselect Vt:$vA, Vt:$vC, (VNot Vt:$vB)), 197>;
+
+ // Pattern: (A ? XOR(B,C) : NOT(B)) XXEVAL immediate value: 198
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VXor Vt:$vB, Vt:$vC), (VNot Vt:$vB)), 198>;
+
+ // Pattern: (A ? OR(B,C) : NOT(B)) XXEVAL immediate value: 199
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VOr Vt:$vB, Vt:$vC), (VNot Vt:$vB)), 199>;
+
+ // Pattern: (A ? NOT(C) : NOT(B)) XXEVAL immediate value: 202
+ def : XXEvalPattern<Vt, (vselect Vt:$vA, (VNot Vt:$vC), (VNot Vt:$vB)), 202>;
+
+ // Pattern: (A ? NAND(B,C) : NOT(B)) XXEVAL immediate value: 206
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VNand Vt:$vB, Vt:$vC), (VNot Vt:$vB)), 206>;
+}
+
+// =============================================================================
+// XXEVAL Ternary Pattern Multiclass: XXEvalTernarySelectNand
+// This class matches the equivalent Ternary Operation: A ? f(B,C) : NAND(B,C)
+// and emit the corresponding xxeval instruction with the imm value.
+//
+// The patterns implement xxeval vector select operations where:
+// - A is the selector vector
+// - f(B,C) is the "true" case op in set {B, C, XOR(B,C), OR(B,C), EQV(B,C)}
+// - C is the "false" case op NAND(B,C)
+// =============================================================================
+multiclass XXEvalTernarySelectNand<ValueType Vt>{
+ // Pattern: (A ? B : NAND(B,C)) XXEVAL immediate value: 227
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, Vt:$vB, (VNand Vt:$vB, Vt:$vC)), 227>;
+
+ // Pattern: (A ? C : NAND(B,C)) XXEVAL immediate value: 229
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, Vt:$vC, (VNand Vt:$vB, Vt:$vC)), 229>;
+
+ // Pattern: (A ? XOR(B,C) : NAND(B,C)) XXEVAL immediate value: 230
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VXor Vt:$vB, Vt:$vC), (VNand Vt:$vB, Vt:$vC)),
+ 230>;
+
+ // Pattern: (A ? OR(B,C) : NAND(B,C)) XXEVAL immediate value: 231
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VOr Vt:$vB, Vt:$vC), (VNand Vt:$vB, Vt:$vC)),
+ 231>;
+
+ // Pattern: (A ? EQV(B,C) : NAND(B,C)) XXEVAL immediate value: 233
+ def : XXEvalPattern<
+ Vt, (vselect Vt:$vA, (VEqv Vt:$vB, Vt:$vC), (VNand Vt:$vB, Vt:$vC)),
+ 233>;
+}
+
let Predicates = [PrefixInstrs, HasP10Vector] in {
let AddedComplexity = 400 in {
def : Pat<(v4i32 (build_vector i32immNonAllOneNonZero:$A,
@@ -2438,7 +2622,12 @@ let Predicates = [PrefixInstrs, HasP10Vector] in {
foreach Ty = [v4i32, v2i64, v8i16, v16i8] in {
defm : XXEvalTernarySelectAnd<Ty>;
defm : XXEvalTernarySelectB<Ty>;
- defm : XXEvalTernarySelectC<Ty>;
+ defm : XXEvalTernarySelectC<Ty>;
+ defm : XXEvalTernarySelectNor<Ty>;
+ defm : XXEvalTernarySelectEqv<Ty>;
+ defm : XXEvalTernarySelectNotC<Ty>;
+ defm : XXEvalTernarySelectNotB<Ty>;
+ defm : XXEvalTernarySelectNand<Ty>;
}
// Anonymous patterns to select prefixed VSX loads and stores.
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-eqv.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-eqv.ll
new file mode 100644
index 0000000000000..ba7680b27cc17
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-eqv.ll
@@ -0,0 +1,295 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; Test file to verify the emission of Vector Evaluate 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, or(B, C), eqv(B, C)) for <4 x i32>
+define <4 x i32> @ternary_A_or_BC_eqv_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_or_BC_eqv_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 151
+; CHECK-NEXT: blr
+entry:
+ %or = or <4 x i32> %B, %C
+ %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> %or, <4 x i32> %eqv
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, or(B, C), eqv(B, C)) for <2 x i64>
+define <2 x i64> @ternary_A_or_BC_eqv_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_or_BC_eqv_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 151
+; CHECK-NEXT: blr
+entry:
+ %or = or <2 x i64> %B, %C
+ %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> %or, <2 x i64> %eqv
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, or(B, C), eqv(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_or_BC_eqv_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_or_BC_eqv_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 151
+; CHECK-NEXT: blr
+entry:
+ %or = or <16 x i8> %B, %C
+ %xor = xor <16 x i8> %B, %C
+ %eqv = xor <16 x i8> %xor, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector eqv operation
+ %res = select <16 x i1> %A, <16 x i8> %or, <16 x i8> %eqv
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, or(B, C), eqv(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_or_BC_eqv_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_or_BC_eqv_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 151
+; CHECK-NEXT: blr
+entry:
+ %or = or <8 x i16> %B, %C
+ %xor = xor <8 x i16> %B, %C
+ %eqv = xor <8 x i16> %xor, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector eqv operation
+ %res = select <8 x i1> %A, <8 x i16> %or, <8 x i16> %eqv
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, nor(B, C), eqv(B, C)) for <4 x i32>
+define <4 x i32> @ternary_A_nor_BC_eqv_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_nor_BC_eqv_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 152
+; CHECK-NEXT: blr
+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
+ %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> %nor, <4 x i32> %eqv
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nor(B, C), eqv(B, C)) for <2 x i64>
+define <2 x i64> @ternary_A_nor_BC_eqv_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_nor_BC_eqv_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 152
+; CHECK-NEXT: blr
+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
+ %eqv = xor <2 x i64> %xor, <i64 -1, i64 -1> ; Vector eqv operation
+ %res = select <2 x i1> %A, <2 x i64> %nor, <2 x i64> %eqv
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nor(B, C), eqv(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_nor_BC_eqv_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_nor_BC_eqv_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 152
+; CHECK-NEXT: blr
+entry:
+ %or = or <16 x i8> %B, %C
+ %nor = xor <16 x i8> %or, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector NOR operation
+ %xor = xor <16 x i8> %B, %C
+ %eqv = xor <16 x i8> %xor, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector eqv operation
+ %res = select <16 x i1> %A, <16 x i8> %nor, <16 x i8> %eqv
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, nor(B, C), eqv(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_nor_BC_eqv_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_nor_BC_eqv_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 152
+; CHECK-NEXT: blr
+entry:
+ %or = or <8 x i16> %B, %C
+ %nor = xor <8 x i16> %or, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector NOR operation
+ %xor = xor <8 x i16> %B, %C
+ %eqv = xor <8 x i16> %xor, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector eqv operation
+ %res = select <8 x i1> %A, <8 x i16> %nor, <8 x i16> %eqv
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, not(C), eqv(B, C)) for <4 x i32>
+define <4 x i32> @ternary_A_not_C_eqv_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_not_C_eqv_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 154
+; CHECK-NEXT: blr
+entry:
+ %not = xor <4 x i32> %C, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
+ %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> %not, <4 x i32> %eqv
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, not(C), eqv(B, C)) for <2 x i64>
+define <2 x i64> @ternary_A_not_C_eqv_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_not_C_eqv_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 154
+; CHECK-NEXT: blr
+entry:
+ %not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
+ %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> %not, <2 x i64> %eqv
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, not(C), eqv(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_not_C_eqv_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_not_C_eqv_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 154
+; CHECK-NEXT: blr
+entry:
+ %not = xor <16 x i8> %C, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector not operation
+ %xor = xor <16 x i8> %B, %C
+ %eqv = xor <16 x i8> %xor, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector eqv operation
+ %res = select <16 x i1> %A, <16 x i8> %not, <16 x i8> %eqv
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, not(C), eqv(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_not_C_eqv_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_not_C_eqv_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 154
+; CHECK-NEXT: blr
+entry:
+ %not = xor <8 x i16> %C, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector not operation
+ %xor = xor <8 x i16> %B, %C
+ %eqv = xor <8 x i16> %xor, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector eqv operation
+ %res = select <8 x i1> %A, <8 x i16> %not, <8 x i16> %eqv
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, nand(B, C), eqv(B, C)) for <4 x i32>
+define <4 x i32> @ternary_A_nand_BC_eqv_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_eqv_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 158
+; CHECK-NEXT: blr
+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
+ %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> %nand, <4 x i32> %eqv
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nand(B, C), eqv(B, C)) for <2 x i64>
+define <2 x i64> @ternary_A_nand_BC_eqv_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_eqv_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 158
+; CHECK-NEXT: blr
+entry:
+ %and = and <2 x i64> %B, %C
+ %nand = xor <2 x i64> %and, <i64 -1, i64 -1> ; Vector nand operation
+ %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> %nand, <2 x i64> %eqv
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nand(B, C), eqv(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_nand_BC_eqv_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_eqv_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 158
+; CHECK-NEXT: blr
+entry:
+ %and = and <16 x i8> %B, %C
+ %nand = xor <16 x i8> %and, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector nand operation
+ %xor = xor <16 x i8> %B, %C
+ %eqv = xor <16 x i8> %xor, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector eqv operation
+ %res = select <16 x i1> %A, <16 x i8> %nand, <16 x i8> %eqv
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, nand(B, C), eqv(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_nand_BC_eqv_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_eqv_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 158
+; CHECK-NEXT: blr
+entry:
+ %and = and <8 x i16> %B, %C
+ %nand = xor <8 x i16> %and, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector nand operation
+ %xor = xor <8 x i16> %B, %C
+ %eqv = xor <8 x i16> %xor, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector eqv operation
+ %res = select <8 x i1> %A, <8 x i16> %nand, <8 x i16> %eqv
+ ret <8 x i16> %res
+}
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-nand.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-nand.ll
new file mode 100644
index 0000000000000..067b089e7ec93
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-nand.ll
@@ -0,0 +1,352 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; Test file to verify the emission of Vector Evaluate 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, B, nand(B, C)) for <4 x i32>
+define <4 x i32> @ternary_A_B_nand_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_B_nand_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 227
+; CHECK-NEXT: blr
+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> %B, <4 x i32> %nand
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, B, nand(B, C)) for <2 x i64>
+define <2 x i64> @ternary_A_B_nand_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_B_nand_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 227
+; CHECK-NEXT: blr
+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> %B, <2 x i64> %nand
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, B, nand(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_B_nand_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_B_nand_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 227
+; CHECK-NEXT: blr
+entry:
+ %and = and <16 x i8> %B, %C
+ %nand = xor <16 x i8> %and, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector nand operation
+ %res = select <16 x i1> %A, <16 x i8> %B, <16 x i8> %nand
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, B, nand(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_B_nand_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_B_nand_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 227
+; CHECK-NEXT: blr
+entry:
+ %and = and <8 x i16> %B, %C
+ %nand = xor <8 x i16> %and, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector nand operation
+ %res = select <8 x i1> %A, <8 x i16> %B, <8 x i16> %nand
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, C, nand(B, C)) for <4 x i32>
+define <4 x i32> @ternary_A_C_nand_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_C_nand_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 229
+; CHECK-NEXT: blr
+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> %C, <4 x i32> %nand
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, C, nand(B, C)) for <2 x i64>
+define <2 x i64> @ternary_A_C_nand_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_C_nand_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 229
+; CHECK-NEXT: blr
+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> %C, <2 x i64> %nand
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, C, nand(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_C_nand_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_C_nand_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 229
+; CHECK-NEXT: blr
+entry:
+ %and = and <16 x i8> %B, %C
+ %nand = xor <16 x i8> %and, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector nand operation
+ %res = select <16 x i1> %A, <16 x i8> %C, <16 x i8> %nand
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, C, nand(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_C_nand_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_C_nand_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 229
+; CHECK-NEXT: blr
+entry:
+ %and = and <8 x i16> %B, %C
+ %nand = xor <8 x i16> %and, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector nand operation
+ %res = select <8 x i1> %A, <8 x i16> %C, <8 x i16> %nand
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, xor(B, C), nand(B, C)) for <4 x i32>
+define <4 x i32> @ternary_A_xor_BC_nand_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_nand_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 230
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <4 x i32> %B, %C
+ %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> %xor, <4 x i32> %nand
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, xor(B, C), nand(B, C)) for <2 x i64>
+define <2 x i64> @ternary_A_xor_BC_nand_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_nand_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 230
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <2 x i64> %B, %C
+ %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> %xor, <2 x i64> %nand
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, xor(B, C), nand(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_xor_BC_nand_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_nand_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 230
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <16 x i8> %B, %C
+ %and = and <16 x i8> %B, %C
+ %nand = xor <16 x i8> %and, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector nand operation
+ %res = select <16 x i1> %A, <16 x i8> %xor, <16 x i8> %nand
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, xor(B, C), nand(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_xor_BC_nand_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_nand_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 230
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <8 x i16> %B, %C
+ %and = and <8 x i16> %B, %C
+ %nand = xor <8 x i16> %and, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector nand operation
+ %res = select <8 x i1> %A, <8 x i16> %xor, <8 x i16> %nand
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, or(B, C), nand(B, C)) for <4 x i32>
+define <4 x i32> @ternary_A_or_BC_nand_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_or_BC_nand_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 231
+; CHECK-NEXT: blr
+entry:
+ %or = or <4 x i32> %B, %C
+ %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> %or, <4 x i32> %nand
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, or(B, C), nand(B, C)) for <2 x i64>
+define <2 x i64> @ternary_A_or_BC_nand_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_or_BC_nand_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 231
+; CHECK-NEXT: blr
+entry:
+ %or = or <2 x i64> %B, %C
+ %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> %or, <2 x i64> %nand
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, or(B, C), nand(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_or_BC_nand_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_or_BC_nand_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 231
+; CHECK-NEXT: blr
+entry:
+ %or = or <16 x i8> %B, %C
+ %and = and <16 x i8> %B, %C
+ %nand = xor <16 x i8> %and, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector nand operation
+ %res = select <16 x i1> %A, <16 x i8> %or, <16 x i8> %nand
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, or(B, C), nand(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_or_BC_nand_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_or_BC_nand_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 231
+; CHECK-NEXT: blr
+entry:
+ %or = or <8 x i16> %B, %C
+ %and = and <8 x i16> %B, %C
+ %nand = xor <8 x i16> %and, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector nand operation
+ %res = select <8 x i1> %A, <8 x i16> %or, <8 x i16> %nand
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, eqv(B, C), nand(B, C)) for <4 x i32>
+define <4 x i32> @ternary_A_eqv_BC_nand_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_eqv_BC_nand_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 233
+; CHECK-NEXT: blr
+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
+ %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> %eqv, <4 x i32> %nand
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, eqv(B, C), nand(B, C)) for <2 x i64>
+define <2 x i64> @ternary_A_eqv_BC_nand_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_eqv_BC_nand_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 233
+; CHECK-NEXT: blr
+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
+ %nand = xor <2 x i64> %and, <i64 -1, i64 -1> ; Vector nand operation
+ %res = select <2 x i1> %A, <2 x i64> %eqv, <2 x i64> %nand
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, eqv(B, C), nand(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_eqv_BC_nand_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_eqv_BC_nand_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 233
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <16 x i8> %B, %C
+ %eqv = xor <16 x i8> %xor, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector eqv operation
+ %and = and <16 x i8> %B, %C
+ %nand = xor <16 x i8> %and, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector nand operation
+ %res = select <16 x i1> %A, <16 x i8> %eqv, <16 x i8> %nand
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, eqv(B, C), nand(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_eqv_BC_nand_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_eqv_BC_nand_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 233
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <8 x i16> %B, %C
+ %eqv = xor <8 x i16> %xor, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector eqv operation
+ %and = and <8 x i16> %B, %C
+ %nand = xor <8 x i16> %and, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector nand operation
+ %res = select <8 x i1> %A, <8 x i16> %eqv, <8 x i16> %nand
+ ret <8 x i16> %res
+}
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-nor.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-nor.ll
new file mode 100644
index 0000000000000..369587454a7c1
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-nor.ll
@@ -0,0 +1,490 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; Test file to verify the emission of Vector selection 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), nor(B,C)) for <4 x i32>
+define <4 x i32> @ternary_A_and_BC_nor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_and_BC_nor_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 129
+; CHECK-NEXT: blr
+entry:
+ %and = and <4 x i32> %B, %C
+ %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> %and, <4 x i32> %nor
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, and(B, C), nor(B,C)) for <2 x i64>
+define <2 x i64> @ternary_A_and_BC_nor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_and_BC_nor_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 129
+; CHECK-NEXT: blr
+entry:
+ %and = and <2 x i64> %B, %C
+ %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> %and, <2 x i64> %nor
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, and(B, C), nor(B,C)) for <16 x i8>
+define <16 x i8> @ternary_A_and_BC_nor_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_and_BC_nor_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 129
+; CHECK-NEXT: blr
+entry:
+ %and = and <16 x i8> %B, %C
+ %or = or <16 x i8> %B, %C
+ %nor = xor <16 x i8> %or, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector NOR operation
+ %res = select <16 x i1> %A, <16 x i8> %and, <16 x i8> %nor
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, and(B, C), nor(B,C)) for <8 x i16>
+define <8 x i16> @ternary_A_and_BC_nor_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_and_BC_nor_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 129
+; CHECK-NEXT: blr
+entry:
+ %and = and <8 x i16> %B, %C
+ %or = or <8 x i16> %B, %C
+ %nor = xor <8 x i16> %or, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector NOR operation
+ %res = select <8 x i1> %A, <8 x i16> %and, <8 x i16> %nor
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, B, nor(B,C)) for <4 x i32>
+define <4 x i32> @ternary_A_B_nor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_B_nor_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 131
+; CHECK-NEXT: blr
+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> %B, <4 x i32> %nor
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, B, nor(B,C)) for <2 x i64>
+define <2 x i64> @ternary_A_B_nor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_B_nor_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 131
+; CHECK-NEXT: blr
+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> %B, <2 x i64> %nor
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, B, nor(B,C)) for <16 x i8>
+define <16 x i8> @ternary_A_B_nor_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_B_nor_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 131
+; CHECK-NEXT: blr
+entry:
+ %or = or <16 x i8> %B, %C
+ %nor = xor <16 x i8> %or, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector NOR operation
+ %res = select <16 x i1> %A, <16 x i8> %B, <16 x i8> %nor
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, B, nor(B,C)) for <8 x i16>
+define <8 x i16> @ternary_A_B_nor_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_B_nor_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 131
+; CHECK-NEXT: blr
+entry:
+ %or = or <8 x i16> %B, %C
+ %nor = xor <8 x i16> %or, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector NOR operation
+ %res = select <8 x i1> %A, <8 x i16> %B, <8 x i16> %nor
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, C, nor(B,C)) for <4 x i32>
+define <4 x i32> @ternary_A_C_nor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_C_nor_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 133
+; CHECK-NEXT: blr
+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> %C, <4 x i32> %nor
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, C, nor(B,C)) for <2 x i64>
+define <2 x i64> @ternary_A_C_nor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_C_nor_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 133
+; CHECK-NEXT: blr
+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> %C, <2 x i64> %nor
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, C, nor(B,C)) for <16 x i8>
+define <16 x i8> @ternary_A_C_nor_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_C_nor_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 133
+; CHECK-NEXT: blr
+entry:
+ %or = or <16 x i8> %B, %C
+ %nor = xor <16 x i8> %or, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector NOR operation
+ %res = select <16 x i1> %A, <16 x i8> %C, <16 x i8> %nor
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, C, nor(B,C)) for <8 x i16>
+define <8 x i16> @ternary_A_C_nor_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_C_nor_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 133
+; CHECK-NEXT: blr
+entry:
+ %or = or <8 x i16> %B, %C
+ %nor = xor <8 x i16> %or, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector NOR operation
+ %res = select <8 x i1> %A, <8 x i16> %C, <8 x i16> %nor
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, xor(B,C), nor(B,C)) for <4 x i32>
+define <4 x i32> @ternary_A_xor_BC_nor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_nor_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 134
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <4 x i32> %B, %C
+ %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> %xor, <4 x i32> %nor
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, xor(B,C), nor(B,C)) for <2 x i64>
+define <2 x i64> @ternary_A_xor_BC_nor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_nor_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 134
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <2 x i64> %B, %C
+ %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> %xor, <2 x i64> %nor
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, xor(B,C), nor(B,C)) for <16 x i8>
+define <16 x i8> @ternary_A_xor_BC_nor_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_nor_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 134
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <16 x i8> %B, %C
+ %or = or <16 x i8> %B, %C
+ %nor = xor <16 x i8> %or, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector NOR operation
+ %res = select <16 x i1> %A, <16 x i8> %xor, <16 x i8> %nor
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, xor(B,C), nor(B,C)) for <8 x i16>
+define <8 x i16> @ternary_A_xor_BC_nor_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_nor_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 134
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <8 x i16> %B, %C
+ %or = or <8 x i16> %B, %C
+ %nor = xor <8 x i16> %or, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector NOR operation
+ %res = select <8 x i1> %A, <8 x i16> %xor, <8 x i16> %nor
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, not(C), nor(B,C)) for <4 x i32>
+define <4 x i32> @ternary_A_not_C_nor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_not_C_nor_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 138
+; CHECK-NEXT: blr
+entry:
+ %not = xor <4 x i32> %C, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
+ %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> %not, <4 x i32> %nor
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, not(C), nor(B,C)) for <2 x i64>
+define <2 x i64> @ternary_A_not_C_nor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_not_C_nor_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 138
+; CHECK-NEXT: blr
+entry:
+ %not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
+ %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> %not, <2 x i64> %nor
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, not(C), nor(B,C)) for <16 x i8>
+define <16 x i8> @ternary_A_not_C_nor_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_not_C_nor_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 138
+; CHECK-NEXT: blr
+entry:
+ %not = xor <16 x i8> %C, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector not operation
+ %or = or <16 x i8> %B, %C
+ %nor = xor <16 x i8> %or, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector NOR operation
+ %res = select <16 x i1> %A, <16 x i8> %not, <16 x i8> %nor
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, not(C), nor(B,C)) for <8 x i16>
+define <8 x i16> @ternary_A_not_C_nor_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_not_C_nor_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 138
+; CHECK-NEXT: blr
+entry:
+ %not = xor <8 x i16> %C, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector not operation
+ %or = or <8 x i16> %B, %C
+ %nor = xor <8 x i16> %or, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector NOR operation
+ %res = select <8 x i1> %A, <8 x i16> %not, <8 x i16> %nor
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, not(B), nor(B,C)) for <4 x i32>
+define <4 x i32> @ternary_A_not_B_nor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_not_B_nor_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 140
+; CHECK-NEXT: blr
+entry:
+ %not = xor <4 x i32> %B, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
+ %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> %not, <4 x i32> %nor
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, not(B), nor(B,C)) for <2 x i64>
+define <2 x i64> @ternary_A_not_B_nor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_not_B_nor_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 140
+; CHECK-NEXT: blr
+entry:
+ %not = xor <2 x i64> %B, <i64 -1, i64 -1> ; Vector not operation
+ %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> %not, <2 x i64> %nor
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, not(B), nor(B,C)) for <16 x i8>
+define <16 x i8> @ternary_A_not_B_nor_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_not_B_nor_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 140
+; CHECK-NEXT: blr
+entry:
+ %not = xor <16 x i8> %B, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector not operation
+ %or = or <16 x i8> %B, %C
+ %nor = xor <16 x i8> %or, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector NOR operation
+ %res = select <16 x i1> %A, <16 x i8> %not, <16 x i8> %nor
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, not(B), nor(B,C)) for <8 x i16>
+define <8 x i16> @ternary_A_not_B_nor_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_not_B_nor_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 140
+; CHECK-NEXT: blr
+entry:
+ %not = xor <8 x i16> %B, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector not operation
+ %or = or <8 x i16> %B, %C
+ %nor = xor <8 x i16> %or, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector NOR operation
+ %res = select <8 x i1> %A, <8 x i16> %not, <8 x i16> %nor
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, nand(B,C), nor(B,C)) for <4 x i32>
+define <4 x i32> @ternary_A_nand_BC_nor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_nor_BC_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 142
+; CHECK-NEXT: blr
+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
+ %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> %nand, <4 x i32> %nor
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nand(B,C), nor(B,C)) for <2 x i64>
+define <2 x i64> @ternary_A_nand_BC_nor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_nor_BC_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 142
+; CHECK-NEXT: blr
+entry:
+ %and = and <2 x i64> %B, %C
+ %nand = xor <2 x i64> %and, <i64 -1, i64 -1> ; Vector nand operation
+ %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> %nand, <2 x i64> %nor
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nand(B,C), nor(B,C)) for <16 x i8>
+define <16 x i8> @ternary_A_nand_BC_nor_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_nor_BC_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 142
+; CHECK-NEXT: blr
+entry:
+ %and = and <16 x i8> %B, %C
+ %nand = xor <16 x i8> %and, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector nand operation
+ %or = or <16 x i8> %B, %C
+ %nor = xor <16 x i8> %or, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector NOR operation
+ %res = select <16 x i1> %A, <16 x i8> %nand, <16 x i8> %nor
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, nand(B,C), nor(B,C)) for <8 x i16>
+define <8 x i16> @ternary_A_nand_BC_nor_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_nor_BC_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 142
+; CHECK-NEXT: blr
+entry:
+ %and = and <8 x i16> %B, %C
+ %nand = xor <8 x i16> %and, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector nand operation
+ %or = or <8 x i16> %B, %C
+ %nor = xor <8 x i16> %or, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector NOR operation
+ %res = select <8 x i1> %A, <8 x i16> %nand, <8 x i16> %nor
+ ret <8 x i16> %res
+}
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-not-b.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-not-b.ll
new file mode 100644
index 0000000000000..a67d9cf91ac09
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-not-b.ll
@@ -0,0 +1,275 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; Test file to verify the emission of Vector Evaluate 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), not(B)) for <4 x i32>
+define <4 x i32> @ternary_A_and_BC_not_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_and_BC_not_B_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 193
+; CHECK-NEXT: blr
+entry:
+ %and = and <4 x i32> %B, %C
+ %not = xor <4 x i32> %B, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
+ %res = select <4 x i1> %A, <4 x i32> %and, <4 x i32> %not
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, and(B, C), not(B)) for <2 x i64>
+define <2 x i64> @ternary_A_and_BC_not_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_and_BC_not_B_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 193
+; CHECK-NEXT: blr
+entry:
+ %and = and <2 x i64> %B, %C
+ %not = xor <2 x i64> %B, <i64 -1, i64 -1> ; Vector not operation
+ %res = select <2 x i1> %A, <2 x i64> %and, <2 x i64> %not
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, and(B, C), not(B)) for <16 x i8>
+define <16 x i8> @ternary_A_and_BC_not_B_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_and_BC_not_B_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 193
+; CHECK-NEXT: blr
+entry:
+ %and = and <16 x i8> %B, %C
+ %not = xor <16 x i8> %B, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector not operation
+ %res = select <16 x i1> %A, <16 x i8> %and, <16 x i8> %not
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, and(B, C), not(B)) for <8 x i16>
+define <8 x i16> @ternary_A_and_BC_not_B_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_and_BC_not_B_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 193
+; CHECK-NEXT: blr
+entry:
+ %and = and <8 x i16> %B, %C
+ %not = xor <8 x i16> %B, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector not operation
+ %res = select <8 x i1> %A, <8 x i16> %and, <8 x i16> %not
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, xor(B, C), not(B)) for <4 x i32>
+define <4 x i32> @ternary_A_xor_BC_not_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_not_B_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 198
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <4 x i32> %B, %C
+ %not = xor <4 x i32> %B, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
+ %res = select <4 x i1> %A, <4 x i32> %xor, <4 x i32> %not
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, xor(B, C), not(B)) for <2 x i64>
+define <2 x i64> @ternary_A_xor_BC_not_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_not_B_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 198
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <2 x i64> %B, %C
+ %not = xor <2 x i64> %B, <i64 -1, i64 -1> ; Vector not operation
+ %res = select <2 x i1> %A, <2 x i64> %xor, <2 x i64> %not
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, xor(B, C), not(B)) for <16 x i8>
+define <16 x i8> @ternary_A_xor_BC_not_B_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_not_B_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 198
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <16 x i8> %B, %C
+ %not = xor <16 x i8> %B, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector not operation
+ %res = select <16 x i1> %A, <16 x i8> %xor, <16 x i8> %not
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, xor(B, C), not(B)) for <8 x i16>
+define <8 x i16> @ternary_A_xor_BC_not_B_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_not_B_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 198
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <8 x i16> %B, %C
+ %not = xor <8 x i16> %B, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector not operation
+ %res = select <8 x i1> %A, <8 x i16> %xor, <8 x i16> %not
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, or(B, C), not(B)) for <4 x i32>
+define <4 x i32> @ternary_A_or_BC_not_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_or_BC_not_B_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 199
+; CHECK-NEXT: blr
+entry:
+ %or = or <4 x i32> %B, %C
+ %not = xor <4 x i32> %B, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
+ %res = select <4 x i1> %A, <4 x i32> %or, <4 x i32> %not
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, or(B, C), not(B)) for <2 x i64>
+define <2 x i64> @ternary_A_or_BC_not_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_or_BC_not_B_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 199
+; CHECK-NEXT: blr
+entry:
+ %or = or <2 x i64> %B, %C
+ %not = xor <2 x i64> %B, <i64 -1, i64 -1> ; Vector not operation
+ %res = select <2 x i1> %A, <2 x i64> %or, <2 x i64> %not
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, or(B, C), not(B)) for <16 x i8>
+define <16 x i8> @ternary_A_or_BC_not_B_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_or_BC_not_B_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 199
+; CHECK-NEXT: blr
+entry:
+ %or = or <16 x i8> %B, %C
+ %not = xor <16 x i8> %B, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector not operation
+ %res = select <16 x i1> %A, <16 x i8> %or, <16 x i8> %not
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, or(B, C), not(B)) for <8 x i16>
+define <8 x i16> @ternary_A_or_BC_not_B_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_or_BC_not_B_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 199
+; CHECK-NEXT: blr
+entry:
+ %or = or <8 x i16> %B, %C
+ %not = xor <8 x i16> %B, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector not operation
+ %res = select <8 x i1> %A, <8 x i16> %or, <8 x i16> %not
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, nand(B, C), not(B)) for <4 x i32>
+define <4 x i32> @ternary_A_nand_BC_not_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_not_B_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 206
+; CHECK-NEXT: blr
+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
+ %not = xor <4 x i32> %B, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
+ %res = select <4 x i1> %A, <4 x i32> %nand, <4 x i32> %not
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nand(B, C), not(B)) for <2 x i64>
+define <2 x i64> @ternary_A_nand_BC_not_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_not_B_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 206
+; CHECK-NEXT: blr
+entry:
+ %and = and <2 x i64> %B, %C
+ %nand = xor <2 x i64> %and, <i64 -1, i64 -1> ; Vector nand operation
+ %not = xor <2 x i64> %B, <i64 -1, i64 -1> ; Vector not operation
+ %res = select <2 x i1> %A, <2 x i64> %nand, <2 x i64> %not
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nand(B, C), not(B)) for <16 x i8>
+define <16 x i8> @ternary_A_nand_BC_not_B_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_not_B_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 206
+; CHECK-NEXT: blr
+entry:
+ %and = and <16 x i8> %B, %C
+ %nand = xor <16 x i8> %and, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector nand operation
+ %not = xor <16 x i8> %B, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector not operation
+ %res = select <16 x i1> %A, <16 x i8> %nand, <16 x i8> %not
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, nand(B, C), not(B)) for <8 x i16>
+define <8 x i16> @ternary_A_nand_BC_not_B_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_not_B_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 206
+; CHECK-NEXT: blr
+entry:
+ %and = and <8 x i16> %B, %C
+ %nand = xor <8 x i16> %and, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector nand operation
+ %not = xor <8 x i16> %B, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector not operation
+ %res = select <8 x i1> %A, <8 x i16> %nand, <8 x i16> %not
+ ret <8 x i16> %res
+}
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-not-c.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-not-c.ll
new file mode 100644
index 0000000000000..98c1f28d49d8e
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-not-c.ll
@@ -0,0 +1,401 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; Test file to verify the emission of Vector Evaluate 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), not(C)) for <4 x i32>
+define <4 x i32> @ternary_A_and_BC_not_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_and_BC_not_C_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 161
+; CHECK-NEXT: blr
+entry:
+ %and = and <4 x i32> %B, %C
+ %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> %and, <4 x i32> %not
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, and(B, C), not(C)) for <2 x i64>
+define <2 x i64> @ternary_A_and_BC_not_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_and_BC_not_C_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 161
+; CHECK-NEXT: blr
+entry:
+ %and = and <2 x i64> %B, %C
+ %not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
+ %res = select <2 x i1> %A, <2 x i64> %and, <2 x i64> %not
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, and(B, C), not(C)) for <16 x i8>
+define <16 x i8> @ternary_A_and_BC_not_C_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_and_BC_not_C_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 161
+; CHECK-NEXT: blr
+entry:
+ %and = and <16 x i8> %B, %C
+ %not = xor <16 x i8> %C, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector not operation
+ %res = select <16 x i1> %A, <16 x i8> %and, <16 x i8> %not
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, and(B, C), not(C)) for <8 x i16>
+define <8 x i16> @ternary_A_and_BC_not_C_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_and_BC_not_C_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 161
+; CHECK-NEXT: blr
+entry:
+ %and = and <8 x i16> %B, %C
+ %not = xor <8 x i16> %C, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector not operation
+ %res = select <8 x i1> %A, <8 x i16> %and, <8 x i16> %not
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, B, not(C)) for <4 x i32>
+define <4 x i32> @ternary_A_B_not_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_B_not_C_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 163
+; CHECK-NEXT: blr
+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> %B, <4 x i32> %not
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, B, not(C)) for <2 x i64>
+define <2 x i64> @ternary_A_B_not_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_B_not_C_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 163
+; CHECK-NEXT: blr
+entry:
+ %not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
+ %res = select <2 x i1> %A, <2 x i64> %B, <2 x i64> %not
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, B, not(C)) for <16 x i8>
+define <16 x i8> @ternary_A_B_not_C_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_B_not_C_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 163
+; CHECK-NEXT: blr
+entry:
+ %not = xor <16 x i8> %C, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector not operation
+ %res = select <16 x i1> %A, <16 x i8> %B, <16 x i8> %not
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, B, not(C)) for <8 x i16>
+define <8 x i16> @ternary_A_B_not_C_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_B_not_C_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 163
+; CHECK-NEXT: blr
+entry:
+ %not = xor <8 x i16> %C, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector not operation
+ %res = select <8 x i1> %A, <8 x i16> %B, <8 x i16> %not
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, xor(B, C), not(C)) for <4 x i32>
+define <4 x i32> @ternary_A_xor_BC_not_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_not_C_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 166
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <4 x i32> %B, %C
+ %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> %xor, <4 x i32> %not
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, xor(B, C), not(C)) for <2 x i64>
+define <2 x i64> @ternary_A_xor_BC_not_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_not_C_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 166
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <2 x i64> %B, %C
+ %not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
+ %res = select <2 x i1> %A, <2 x i64> %xor, <2 x i64> %not
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, xor(B, C), not(C)) for <16 x i8>
+define <16 x i8> @ternary_A_xor_BC_not_C_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_not_C_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 166
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <16 x i8> %B, %C
+ %not = xor <16 x i8> %C, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector not operation
+ %res = select <16 x i1> %A, <16 x i8> %xor, <16 x i8> %not
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, xor(B, C), not(C)) for <8 x i16>
+define <8 x i16> @ternary_A_xor_BC_not_C_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_not_C_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 166
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <8 x i16> %B, %C
+ %not = xor <8 x i16> %C, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector not operation
+ %res = select <8 x i1> %A, <8 x i16> %xor, <8 x i16> %not
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, or(B, C), not(C)) for <4 x i32>
+define <4 x i32> @ternary_A_or_BC_not_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_or_BC_not_C_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 167
+; CHECK-NEXT: blr
+entry:
+ %or = or <4 x i32> %B, %C
+ %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> %or, <4 x i32> %not
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, or(B, C), not(C)) for <2 x i64>
+define <2 x i64> @ternary_A_or_BC_not_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_or_BC_not_C_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 167
+; CHECK-NEXT: blr
+entry:
+ %or = or <2 x i64> %B, %C
+ %not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
+ %res = select <2 x i1> %A, <2 x i64> %or, <2 x i64> %not
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, or(B, C), not(C)) for <16 x i8>
+define <16 x i8> @ternary_A_or_BC_not_C_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_or_BC_not_C_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 167
+; CHECK-NEXT: blr
+entry:
+ %or = or <16 x i8> %B, %C
+ %not = xor <16 x i8> %C, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector not operation
+ %res = select <16 x i1> %A, <16 x i8> %or, <16 x i8> %not
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, or(B, C), not(C)) for <8 x i16>
+define <8 x i16> @ternary_A_or_BC_not_C_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_or_BC_not_C_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 167
+; CHECK-NEXT: blr
+entry:
+ %or = or <8 x i16> %B, %C
+ %not = xor <8 x i16> %C, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector not operation
+ %res = select <8 x i1> %A, <8 x i16> %or, <8 x i16> %not
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, not(B), not(C)) for <4 x i32>
+define <4 x i32> @ternary_A_not_B_not_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_not_B_not_C_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 172
+; CHECK-NEXT: blr
+entry:
+ %not_b = xor <4 x i32> %B, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
+ %not_c = 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_b, <4 x i32> %not_c
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, not(B), not(C)) for <2 x i64>
+define <2 x i64> @ternary_A_not_B_not_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_not_B_not_C_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 172
+; CHECK-NEXT: blr
+entry:
+ %not_b = xor <2 x i64> %B, <i64 -1, i64 -1> ; Vector not operation
+ %not_c = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
+ %res = select <2 x i1> %A, <2 x i64> %not_b, <2 x i64> %not_c
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, not(B), not(C)) for <16 x i8>
+define <16 x i8> @ternary_A_not_B_not_C_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_not_B_not_C_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 172
+; CHECK-NEXT: blr
+entry:
+ %not_b = xor <16 x i8> %B, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector not operation
+ %not_c = xor <16 x i8> %C, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector not operation
+ %res = select <16 x i1> %A, <16 x i8> %not_b, <16 x i8> %not_c
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, not(B), not(C)) for <8 x i16>
+define <8 x i16> @ternary_A_not_B_not_C_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_not_B_not_C_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 172
+; CHECK-NEXT: blr
+entry:
+ %not_b = xor <8 x i16> %B, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector not operation
+ %not_c = xor <8 x i16> %C, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector not operation
+ %res = select <8 x i1> %A, <8 x i16> %not_b, <8 x i16> %not_c
+ ret <8 x i16> %res
+}
+
+; Function to test ternary(A, nand(B, C), not(C)) for <4 x i32>
+define <4 x i32> @ternary_A_nand_BC_not_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_not_C_4x32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxleqv v5, v5, v5
+; CHECK-NEXT: vslw v2, v2, v5
+; CHECK-NEXT: vsraw v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 174
+; CHECK-NEXT: blr
+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
+ %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> %nand, <4 x i32> %not
+ ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nand(B, C), not(C)) for <2 x i64>
+define <2 x i64> @ternary_A_nand_BC_not_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_not_C_2x64:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: 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, 174
+; CHECK-NEXT: blr
+entry:
+ %and = and <2 x i64> %B, %C
+ %nand = xor <2 x i64> %and, <i64 -1, i64 -1> ; Vector nand operation
+ %not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
+ %res = select <2 x i1> %A, <2 x i64> %nand, <2 x i64> %not
+ ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nand(B, C), not(C)) for <16 x i8>
+define <16 x i8> @ternary_A_nand_BC_not_C_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_not_C_16x8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltib v5, 7
+; CHECK-NEXT: vslb v2, v2, v5
+; CHECK-NEXT: vsrab v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 174
+; CHECK-NEXT: blr
+entry:
+ %and = and <16 x i8> %B, %C
+ %nand = xor <16 x i8> %and, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector nand operation
+ %not = xor <16 x i8> %C, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> ; Vector not operation
+ %res = select <16 x i1> %A, <16 x i8> %nand, <16 x i8> %not
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, nand(B, C), not(C)) for <8 x i16>
+define <8 x i16> @ternary_A_nand_BC_not_C_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_not_C_8x16:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxspltiw v5, 983055
+; CHECK-NEXT: vslh v2, v2, v5
+; CHECK-NEXT: vsrah v2, v2, v5
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 174
+; CHECK-NEXT: blr
+entry:
+ %and = and <8 x i16> %B, %C
+ %nand = xor <8 x i16> %and, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector nand operation
+ %not = xor <8 x i16> %C, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> ; Vector not operation
+ %res = select <8 x i1> %A, <8 x i16> %nand, <8 x i16> %not
+ ret <8 x i16> %res
+}
More information about the llvm-commits
mailing list