[llvm] [PowerPC] Exploit xxeval instruction for ternary patterns - part 1 (PR #141733)
Tony Varghese via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 2 12:08:14 PDT 2025
https://github.com/tonykuttai updated https://github.com/llvm/llvm-project/pull/141733
>From 5d515c9384afc8392d086680c4ebd2bff0f04447 Mon Sep 17 00:00:00 2001
From: Tony Varghese <tony.varghese at ibm.com>
Date: Thu, 29 May 2025 16:33:21 +0000
Subject: [PATCH 1/4] [PowerPC][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.
---
llvm/lib/Target/PowerPC/PPCInstrP10.td | 200 +++++++++++++++---
.../CodeGen/PowerPC/xxeval-vselect-x-and.ll | 42 +---
.../CodeGen/PowerPC/xxeval-vselect-x-b.ll | 32 +--
.../CodeGen/PowerPC/xxeval-vselect-x-c.ll | 26 +--
.../CodeGen/PowerPC/xxeval-vselect-x-or.ll | 28 ++-
.../CodeGen/PowerPC/xxeval-vselect-x-xor.ll | 38 +---
6 files changed, 222 insertions(+), 144 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCInstrP10.td b/llvm/lib/Target/PowerPC/PPCInstrP10.td
index d295f35fb1dd0..d0985f4a3a9bb 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrP10.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrP10.td
@@ -2159,8 +2159,131 @@ 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 DagCondVNot<dag d, bit negate> {
+ // Utility to define a vnot around the dag.
+ dag res = !if(!ne(negate, 0),
+ (vnot d),
+ d);
+}
+
+class XXEvalUnaryPattern<ValueType vt> {
+ // vnot Operand B
+ dag vnotB = !cond(
+ !eq(vt, v4i32) : (vnot v4i32:$vB),
+ !eq(vt, v2i64) : (v2i64 (bitconvert (vnot (v4i32 (bitconvert v2i64:$vB)))))
+ );
+ // vnot Operand C
+ dag vnotC = !cond(
+ !eq(vt, v4i32) : (vnot v4i32:$vC),
+ !eq(vt, v2i64) : (v2i64 (bitconvert (vnot (v4i32 (bitconvert v2i64:$vC)))))
+ );
+}
+
+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 = 22
+ 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 = 24
+ 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 = 25
+ 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 = 26
+ def : XXEvalPattern<vt,
+ (vselect vt:$vA, XXEvalUnaryPattern<vt>.vnotC, XXEvalBinaryPattern<vt, and>.opPat),
+ !add(baseImm, 4)>;
+ // Ternary(A, not(B), and(B,C)) => imm: baseImm + 6 = 28
+ def : XXEvalPattern<vt,
+ (vselect vt:$vA, XXEvalUnaryPattern<vt>.vnotB, 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 = 49
+ def : XXEvalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and>.opPat, vt:$vB),
+ baseImm>;
+ // Ternary(A, nor(B,C), B) => imm: baseImm + 7 = 56
+ 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 = 57
+ def : XXEvalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, xor, 1>.opPat, vt:$vB),
+ !add(baseImm, 8)>;
+ // Ternary(A, not(C), B) => imm: baseImm + 9 = 58
+ def : XXEvalPattern<vt,
+ (vselect vt:$vA, XXEvalUnaryPattern<vt>.vnotC, vt:$vB),
+ !add(baseImm, 9)>;
+ // Ternary(A, nand(B,C), B) => imm: baseImm + 13 = 62
+ 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 = 81
+ def : XXEvalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and>.opPat, vt:$vC),
+ baseImm>;
+ // Ternary(A, nor(B,C), C) => imm: baseImm + 7 = 88
+ 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 = 89
+ 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 = 94
+ 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 = 97
+ def : XXEvalPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and>.opPat, XXEvalBinaryPattern<vt, xor>.opPat),
+ baseImm>;
+ // Ternary(A, B, xor(B,C)) => imm: baseImm + 2 = 99
+ def : XXEvalPattern<vt,
+ (vselect vt:$vA, vt:$vB, XXEvalBinaryPattern<vt, xor>.opPat),
+ !add(baseImm, 2)>;
+ // Ternary(A, C, xor(B,C)) => imm: baseImm + 4 = 101
+ 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 = 103
+ 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 = 104
+ 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 +2315,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>;
+
+ // Utilize xxeval instruction for ternary vector expressions.
+ 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
index 2868669c52ce6..19305336f78df 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
@@ -1,5 +1,5 @@
; 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.
+; 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
@@ -15,11 +15,9 @@ define <4 x i32> @ternary_A_xor_BC_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i
; CHECK-LABEL: ternary_A_xor_BC_and_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlxor vs0, v3, v4
-; CHECK-NEXT: xxland vs1, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 22
; CHECK-NEXT: blr
entry:
%xor = xor <4 x i32> %B, %C
@@ -33,12 +31,10 @@ define <2 x i64> @ternary_A_xor_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i
; CHECK-LABEL: ternary_A_xor_BC_and_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlxor vs0, v3, v4
-; CHECK-NEXT: xxland vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 22
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -52,11 +48,9 @@ define <4 x i32> @ternary_A_nor_BC_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i
; CHECK-LABEL: ternary_A_nor_BC_and_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v4
-; CHECK-NEXT: xxland vs1, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 24
; CHECK-NEXT: blr
entry:
%or = or <4 x i32> %B, %C
@@ -71,12 +65,10 @@ define <2 x i64> @ternary_A_nor_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i
; CHECK-LABEL: ternary_A_nor_BC_and_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v4
-; CHECK-NEXT: xxland vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 24
; CHECK-NEXT: blr
entry:
%or = or <2 x i64> %B, %C
@@ -91,11 +83,9 @@ define <4 x i32> @ternary_A_eqv_BC_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i
; CHECK-LABEL: ternary_A_eqv_BC_and_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxleqv vs0, v3, v4
-; CHECK-NEXT: xxland vs1, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 25
; CHECK-NEXT: blr
entry:
%xor = xor <4 x i32> %B, %C
@@ -110,12 +100,10 @@ define <2 x i64> @ternary_A_eqv_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i
; CHECK-LABEL: ternary_A_eqv_BC_and_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxleqv vs0, v3, v4
-; CHECK-NEXT: xxland vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 25
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -130,11 +118,9 @@ define <4 x i32> @ternary_A_not_C_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i3
; CHECK-LABEL: ternary_A_not_C_and_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v4, v4
-; CHECK-NEXT: xxland vs1, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 26
; CHECK-NEXT: blr
entry:
%not = xor <4 x i32> %C, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
@@ -148,12 +134,10 @@ define <2 x i64> @ternary_A_not_C_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i6
; CHECK-LABEL: ternary_A_not_C_and_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v4, v4
-; CHECK-NEXT: xxland vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 26
; CHECK-NEXT: blr
entry:
%not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
@@ -167,11 +151,9 @@ define <4 x i32> @ternary_A_not_B_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i3
; CHECK-LABEL: ternary_A_not_B_and_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v3
-; CHECK-NEXT: xxland vs1, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 28
; CHECK-NEXT: blr
entry:
%not = xor <4 x i32> %B, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
@@ -185,12 +167,10 @@ define <2 x i64> @ternary_A_not_B_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i6
; CHECK-LABEL: ternary_A_not_B_and_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v3
-; CHECK-NEXT: xxland vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 28
; CHECK-NEXT: blr
entry:
%not = xor <2 x i64> %B, <i64 -1, i64 -1> ; Vector not operation
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
index 37a0edb14b78f..c36fd68ba0ece 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
@@ -1,5 +1,5 @@
; 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.
+; 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
@@ -15,10 +15,9 @@ define <4 x i32> @ternary_A_and_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %
; CHECK-LABEL: ternary_A_and_BC_B_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxland vs0, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, v3, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 49
; CHECK-NEXT: blr
entry:
%and = and <4 x i32> %B, %C
@@ -31,11 +30,10 @@ define <2 x i64> @ternary_A_and_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_and_BC_B_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxland vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v3, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 49
; CHECK-NEXT: blr
entry:
%and = and <2 x i64> %B, %C
@@ -48,10 +46,9 @@ define <4 x i32> @ternary_A_nor_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %
; CHECK-LABEL: ternary_A_nor_BC_B_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, v3, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 56
; CHECK-NEXT: blr
entry:
%or = or <4 x i32> %B, %C
@@ -65,11 +62,10 @@ define <2 x i64> @ternary_A_nor_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_nor_BC_B_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v3, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 56
; CHECK-NEXT: blr
entry:
%or = or <2 x i64> %B, %C
@@ -83,10 +79,9 @@ define <4 x i32> @ternary_A_eqv_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %
; CHECK-LABEL: ternary_A_eqv_BC_B_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxleqv vs0, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, v3, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 57
; CHECK-NEXT: blr
entry:
%xor = xor <4 x i32> %B, %C
@@ -100,11 +95,10 @@ define <2 x i64> @ternary_A_eqv_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_eqv_BC_B_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxleqv vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v3, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 57
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -118,10 +112,9 @@ define <4 x i32> @ternary_A_not_C_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C
; CHECK-LABEL: ternary_A_not_C_B_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v4, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, v3, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 58
; CHECK-NEXT: blr
entry:
%not = xor <4 x i32> %C, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
@@ -134,11 +127,10 @@ define <2 x i64> @ternary_A_not_C_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C
; CHECK-LABEL: ternary_A_not_C_B_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v4, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v3, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 58
; CHECK-NEXT: blr
entry:
%not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
@@ -151,10 +143,9 @@ define <4 x i32> @ternary_A_nand_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32>
; CHECK-LABEL: ternary_A_nand_BC_B_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlnand vs0, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, v3, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 62
; CHECK-NEXT: blr
entry:
%and = and <4 x i32> %B, %C
@@ -168,11 +159,10 @@ define <2 x i64> @ternary_A_nand_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64>
; CHECK-LABEL: ternary_A_nand_BC_B_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnand vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v3, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 62
; CHECK-NEXT: blr
entry:
%and = and <2 x i64> %B, %C
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
index 411aa27a61861..54fda6063bfac 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
@@ -1,5 +1,5 @@
; 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.
+; 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
@@ -15,10 +15,9 @@ define <4 x i32> @ternary_A_and_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %
; CHECK-LABEL: ternary_A_and_BC_C_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxland vs0, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, v4, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 81
; CHECK-NEXT: blr
entry:
%and = and <4 x i32> %B, %C
@@ -31,11 +30,10 @@ define <2 x i64> @ternary_A_and_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_and_BC_C_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxland vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v4, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 81
; CHECK-NEXT: blr
entry:
%and = and <2 x i64> %B, %C
@@ -48,10 +46,9 @@ define <4 x i32> @ternary_A_nor_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %
; CHECK-LABEL: ternary_A_nor_BC_C_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, v4, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 88
; CHECK-NEXT: blr
entry:
%or = or <4 x i32> %B, %C
@@ -65,11 +62,10 @@ define <2 x i64> @ternary_A_nor_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_nor_BC_C_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v4, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 88
; CHECK-NEXT: blr
entry:
%or = or <2 x i64> %B, %C
@@ -83,10 +79,9 @@ define <4 x i32> @ternary_A_eqv_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %
; CHECK-LABEL: ternary_A_eqv_BC_C_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxleqv vs0, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, v4, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 89
; CHECK-NEXT: blr
entry:
%xor = xor <4 x i32> %B, %C
@@ -100,11 +95,10 @@ define <2 x i64> @ternary_A_eqv_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_eqv_BC_C_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxleqv vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v4, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 89
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -118,10 +112,9 @@ define <4 x i32> @ternary_A_nand_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32>
; CHECK-LABEL: ternary_A_nand_BC_C_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlnand vs0, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, v4, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 94
; CHECK-NEXT: blr
entry:
%and = and <4 x i32> %B, %C
@@ -135,11 +128,10 @@ define <2 x i64> @ternary_A_nand_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64>
; CHECK-LABEL: ternary_A_nand_BC_C_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnand vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v4, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 94
; CHECK-NEXT: blr
entry:
%and = and <2 x i64> %B, %C
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-or.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-or.ll
index 1ad7e95e3682e..c956785a757ca 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-or.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-or.ll
@@ -120,11 +120,11 @@ define <4 x i32> @ternary_A_eqv_BC_or_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i3
; CHECK-LABEL: ternary_A_eqv_BC_or_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxleqv vs0, v3, v4
+; CHECK-NEXT: xxlxor vs0, v3, v4
; CHECK-NEXT: xxlor vs1, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, vs1, vs0, 58
; CHECK-NEXT: blr
entry:
%xor = xor <4 x i32> %B, %C
@@ -159,11 +159,10 @@ define <4 x i32> @ternary_A_not_C_or_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32
; CHECK-LABEL: ternary_A_not_C_or_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v4, v4
-; CHECK-NEXT: xxlor vs1, v3, v4
+; CHECK-NEXT: xxlor vs0, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, vs0, v4, 58
; CHECK-NEXT: blr
entry:
%not = xor <4 x i32> %C, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
@@ -177,12 +176,11 @@ define <2 x i64> @ternary_A_not_C_or_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64
; CHECK-LABEL: ternary_A_not_C_or_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v4, v4
-; CHECK-NEXT: xxlor vs1, v3, v4
+; CHECK-NEXT: xxlor vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, vs0, v4, 58
; CHECK-NEXT: blr
entry:
%not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
@@ -196,11 +194,10 @@ define <4 x i32> @ternary_A_not_B_or_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32
; CHECK-LABEL: ternary_A_not_B_or_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v3
-; CHECK-NEXT: xxlor vs1, v3, v4
+; CHECK-NEXT: xxlor vs0, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, vs0, v3, 58
; CHECK-NEXT: blr
entry:
%not = xor <4 x i32> %B, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
@@ -214,12 +211,11 @@ define <2 x i64> @ternary_A_not_B_or_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64
; CHECK-LABEL: ternary_A_not_B_or_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v3
-; CHECK-NEXT: xxlor vs1, v3, v4
+; CHECK-NEXT: xxlor vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, vs0, v3, 58
; CHECK-NEXT: blr
entry:
%not = xor <2 x i64> %B, <i64 -1, i64 -1> ; Vector not operation
@@ -233,11 +229,11 @@ define <4 x i32> @ternary_A_nand_BC_or_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i
; CHECK-LABEL: ternary_A_nand_BC_or_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlnand vs0, v3, v4
+; CHECK-NEXT: xxland vs0, v3, v4
; CHECK-NEXT: xxlor vs1, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, vs1, vs0, 58
; CHECK-NEXT: blr
entry:
%and = and <4 x i32> %B, %C
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
index f8a8b6e9a0486..74d3a3bf6196e 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
@@ -1,5 +1,5 @@
; 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.
+; 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
@@ -15,11 +15,9 @@ define <4 x i32> @ternary_A_and_BC_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i
; CHECK-LABEL: ternary_A_and_BC_xor_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxland vs0, v3, v4
-; CHECK-NEXT: xxlxor vs1, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 97
; CHECK-NEXT: blr
entry:
%and = and <4 x i32> %B, %C
@@ -33,12 +31,10 @@ define <2 x i64> @ternary_A_and_BC_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i
; CHECK-LABEL: ternary_A_and_BC_xor_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxland vs0, v3, v4
-; CHECK-NEXT: xxlxor vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 97
; CHECK-NEXT: blr
entry:
%and = and <2 x i64> %B, %C
@@ -52,10 +48,9 @@ define <4 x i32> @ternary_A_B_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %
; CHECK-LABEL: ternary_A_B_xor_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlxor vs0, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs0, v3, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 99
; CHECK-NEXT: blr
entry:
%xor = xor <4 x i32> %B, %C
@@ -68,11 +63,10 @@ define <2 x i64> @ternary_A_B_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_B_xor_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlxor vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs0, v3, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 99
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -85,10 +79,9 @@ define <4 x i32> @ternary_A_C_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %
; CHECK-LABEL: ternary_A_C_xor_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlxor vs0, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs0, v4, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 101
; CHECK-NEXT: blr
entry:
%xor = xor <4 x i32> %B, %C
@@ -101,11 +94,10 @@ define <2 x i64> @ternary_A_C_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_C_xor_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlxor vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs0, v4, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 101
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -118,11 +110,9 @@ define <4 x i32> @ternary_A_or_BC_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i3
; CHECK-LABEL: ternary_A_or_BC_xor_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlor vs0, v3, v4
-; CHECK-NEXT: xxlxor vs1, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 103
; CHECK-NEXT: blr
entry:
%or = or <4 x i32> %B, %C
@@ -136,12 +126,10 @@ define <2 x i64> @ternary_A_or_BC_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i6
; CHECK-LABEL: ternary_A_or_BC_xor_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlor vs0, v3, v4
-; CHECK-NEXT: xxlxor vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 103
; CHECK-NEXT: blr
entry:
%or = or <2 x i64> %B, %C
@@ -155,11 +143,9 @@ define <4 x i32> @ternary_A_nor_BC_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i
; CHECK-LABEL: ternary_A_nor_BC_xor_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v4
-; CHECK-NEXT: xxlxor vs1, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 104
; CHECK-NEXT: blr
entry:
%or = or <4 x i32> %B, %C
@@ -174,12 +160,10 @@ define <2 x i64> @ternary_A_nor_BC_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i
; CHECK-LABEL: ternary_A_nor_BC_xor_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v4
-; CHECK-NEXT: xxlxor vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 104
; CHECK-NEXT: blr
entry:
%or = or <2 x i64> %B, %C
>From 29e456eac9df7de8f767ea9e7e90d2bb6581ab22 Mon Sep 17 00:00:00 2001
From: Tony Varghese <tony.varghese at ibm.com>
Date: Fri, 20 Jun 2025 18:59:08 +0000
Subject: [PATCH 2/4] [PowerPC]xxeval instruction for ternary operations
support for v4i32
---
llvm/lib/Target/PowerPC/PPCInstrP10.td | 23 ++++---------------
.../CodeGen/PowerPC/xxeval-vselect-x-and.ll | 20 ++++++++++++----
.../CodeGen/PowerPC/xxeval-vselect-x-b.ll | 15 ++++++++----
.../CodeGen/PowerPC/xxeval-vselect-x-c.ll | 12 ++++++----
.../CodeGen/PowerPC/xxeval-vselect-x-or.ll | 10 ++++----
.../CodeGen/PowerPC/xxeval-vselect-x-xor.ll | 18 +++++++++++----
6 files changed, 56 insertions(+), 42 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCInstrP10.td b/llvm/lib/Target/PowerPC/PPCInstrP10.td
index d0985f4a3a9bb..947b3e188b5a3 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrP10.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrP10.td
@@ -2171,26 +2171,15 @@ class DagCondVNot<dag d, bit negate> {
class XXEvalUnaryPattern<ValueType vt> {
// vnot Operand B
- dag vnotB = !cond(
- !eq(vt, v4i32) : (vnot v4i32:$vB),
- !eq(vt, v2i64) : (v2i64 (bitconvert (vnot (v4i32 (bitconvert v2i64:$vB)))))
- );
+ dag vnotB = (vnot vt:$vB);
// vnot Operand C
- dag vnotC = !cond(
- !eq(vt, v4i32) : (vnot v4i32:$vC),
- !eq(vt, v2i64) : (v2i64 (bitconvert (vnot (v4i32 (bitconvert v2i64:$vC)))))
- );
+ dag vnotC = (vnot vt:$vC);
}
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))
- );
+ dag opPat = DagCondVNot<(op vt:$vB, vt:$vC), notResult>.res;
}
multiclass XXEvalVSelectWithXAnd<ValueType vt, bits<8> baseImm> {
@@ -2395,16 +2384,12 @@ let Predicates = [PrefixInstrs, HasP10Vector] in {
// Utilize xxeval instruction for ternary vector expressions.
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
index 19305336f78df..dfb910b8d0c75 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
@@ -31,10 +31,12 @@ define <2 x i64> @ternary_A_xor_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i
; CHECK-LABEL: ternary_A_xor_BC_and_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxlxor vs0, v3, v4
+; CHECK-NEXT: xxland vs1, v3, v4
; 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: xxsel v2, vs1, vs0, v2
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -65,10 +67,12 @@ define <2 x i64> @ternary_A_nor_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i
; CHECK-LABEL: ternary_A_nor_BC_and_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxlnor vs0, v3, v4
+; CHECK-NEXT: xxland vs1, v3, v4
; 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: xxsel v2, vs1, vs0, v2
; CHECK-NEXT: blr
entry:
%or = or <2 x i64> %B, %C
@@ -100,10 +104,12 @@ define <2 x i64> @ternary_A_eqv_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i
; CHECK-LABEL: ternary_A_eqv_BC_and_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxleqv vs0, v3, v4
+; CHECK-NEXT: xxland vs1, v3, v4
; 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: xxsel v2, vs1, vs0, v2
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -134,10 +140,12 @@ define <2 x i64> @ternary_A_not_C_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i6
; CHECK-LABEL: ternary_A_not_C_and_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxlnor vs0, v4, v4
+; CHECK-NEXT: xxland vs1, v3, v4
; 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: xxsel v2, vs1, vs0, v2
; CHECK-NEXT: blr
entry:
%not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
@@ -167,10 +175,12 @@ define <2 x i64> @ternary_A_not_B_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i6
; CHECK-LABEL: ternary_A_not_B_and_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxlnor vs0, v3, v3
+; CHECK-NEXT: xxland vs1, v3, v4
; 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: xxsel v2, vs1, vs0, v2
; CHECK-NEXT: blr
entry:
%not = xor <2 x i64> %B, <i64 -1, i64 -1> ; Vector not operation
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
index c36fd68ba0ece..9943c35dfb134 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
@@ -30,10 +30,11 @@ define <2 x i64> @ternary_A_and_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_and_BC_B_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxland vs0, v3, v4
; 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: xxsel v2, v3, vs0, v2
; CHECK-NEXT: blr
entry:
%and = and <2 x i64> %B, %C
@@ -62,10 +63,11 @@ define <2 x i64> @ternary_A_nor_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_nor_BC_B_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxlnor vs0, v3, v4
; 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: xxsel v2, v3, vs0, v2
; CHECK-NEXT: blr
entry:
%or = or <2 x i64> %B, %C
@@ -95,10 +97,11 @@ define <2 x i64> @ternary_A_eqv_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_eqv_BC_B_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxleqv vs0, v3, v4
; 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: xxsel v2, v3, vs0, v2
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -127,10 +130,11 @@ define <2 x i64> @ternary_A_not_C_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C
; CHECK-LABEL: ternary_A_not_C_B_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxlnor vs0, v4, v4
; 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: xxsel v2, v3, vs0, v2
; CHECK-NEXT: blr
entry:
%not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
@@ -159,10 +163,11 @@ define <2 x i64> @ternary_A_nand_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64>
; CHECK-LABEL: ternary_A_nand_BC_B_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxlnand vs0, v3, v4
; 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: xxsel v2, v3, vs0, v2
; CHECK-NEXT: blr
entry:
%and = and <2 x i64> %B, %C
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
index 54fda6063bfac..f770cf768147a 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
@@ -30,10 +30,11 @@ define <2 x i64> @ternary_A_and_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_and_BC_C_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxland vs0, v3, v4
; 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: xxsel v2, v4, vs0, v2
; CHECK-NEXT: blr
entry:
%and = and <2 x i64> %B, %C
@@ -62,10 +63,11 @@ define <2 x i64> @ternary_A_nor_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_nor_BC_C_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxlnor vs0, v3, v4
; 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: xxsel v2, v4, vs0, v2
; CHECK-NEXT: blr
entry:
%or = or <2 x i64> %B, %C
@@ -95,10 +97,11 @@ define <2 x i64> @ternary_A_eqv_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_eqv_BC_C_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxleqv vs0, v3, v4
; 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: xxsel v2, v4, vs0, v2
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -128,10 +131,11 @@ define <2 x i64> @ternary_A_nand_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64>
; CHECK-LABEL: ternary_A_nand_BC_C_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxlnand vs0, v3, v4
; 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: xxsel v2, v4, vs0, v2
; CHECK-NEXT: blr
entry:
%and = and <2 x i64> %B, %C
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-or.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-or.ll
index c956785a757ca..bf2b691056781 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-or.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-or.ll
@@ -176,11 +176,12 @@ define <2 x i64> @ternary_A_not_C_or_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64
; CHECK-LABEL: ternary_A_not_C_or_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlor vs0, v3, v4
+; CHECK-NEXT: xxlnor vs0, v4, v4
+; CHECK-NEXT: xxlor vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, vs0, v4, 58
+; CHECK-NEXT: xxsel v2, vs1, vs0, v2
; CHECK-NEXT: blr
entry:
%not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
@@ -211,11 +212,12 @@ define <2 x i64> @ternary_A_not_B_or_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64
; CHECK-LABEL: ternary_A_not_B_or_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlor vs0, v3, v4
+; CHECK-NEXT: xxlnor vs0, v3, v3
+; CHECK-NEXT: xxlor vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, vs0, v3, 58
+; CHECK-NEXT: xxsel v2, vs1, vs0, v2
; CHECK-NEXT: blr
entry:
%not = xor <2 x i64> %B, <i64 -1, i64 -1> ; Vector not operation
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
index 74d3a3bf6196e..2725525846dd8 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
@@ -31,10 +31,12 @@ define <2 x i64> @ternary_A_and_BC_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i
; CHECK-LABEL: ternary_A_and_BC_xor_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxland vs0, v3, v4
+; CHECK-NEXT: xxlxor vs1, v3, v4
; 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: xxsel v2, vs1, vs0, v2
; CHECK-NEXT: blr
entry:
%and = and <2 x i64> %B, %C
@@ -63,10 +65,11 @@ define <2 x i64> @ternary_A_B_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_B_xor_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxlxor vs0, v3, v4
; 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: xxsel v2, vs0, v3, v2
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -94,10 +97,11 @@ define <2 x i64> @ternary_A_C_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_C_xor_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxlxor vs0, v3, v4
; 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: xxsel v2, vs0, v4, v2
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -126,10 +130,12 @@ define <2 x i64> @ternary_A_or_BC_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i6
; CHECK-LABEL: ternary_A_or_BC_xor_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxlor vs0, v3, v4
+; CHECK-NEXT: xxlxor vs1, v3, v4
; 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: xxsel v2, vs1, vs0, v2
; CHECK-NEXT: blr
entry:
%or = or <2 x i64> %B, %C
@@ -160,10 +166,12 @@ define <2 x i64> @ternary_A_nor_BC_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i
; CHECK-LABEL: ternary_A_nor_BC_xor_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
+; CHECK-NEXT: xxlnor vs0, v3, v4
+; CHECK-NEXT: xxlxor vs1, v3, v4
; 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: xxsel v2, vs1, vs0, v2
; CHECK-NEXT: blr
entry:
%or = or <2 x i64> %B, %C
>From 87be0d01f1846f291196c739ab66314bd8feb66c Mon Sep 17 00:00:00 2001
From: Tony Varghese <tony.varghese at ibm.com>
Date: Sat, 28 Jun 2025 03:08:51 +0000
Subject: [PATCH 3/4] [PowerPC] Emit xxeval instruction for ternary vector
patterns v4i32 and v2i64 types
---
llvm/lib/Target/PowerPC/PPCInstrP10.td | 132 ++++++++++--------
.../CodeGen/PowerPC/xxeval-vselect-x-and.ll | 20 +--
.../CodeGen/PowerPC/xxeval-vselect-x-b.ll | 44 +-----
.../CodeGen/PowerPC/xxeval-vselect-x-c.ll | 12 +-
.../CodeGen/PowerPC/xxeval-vselect-x-or.ll | 18 +--
.../CodeGen/PowerPC/xxeval-vselect-x-xor.ll | 18 +--
6 files changed, 105 insertions(+), 139 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCInstrP10.td b/llvm/lib/Target/PowerPC/PPCInstrP10.td
index 947b3e188b5a3..fb79f5a7cadae 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrP10.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrP10.td
@@ -2159,121 +2159,152 @@ let AddedComplexity = 400, Predicates = [IsISA3_1, HasVSX] in {
(COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
}
+ // Defines a pattern for the XXEVAL instruction with a specific value type,
+ // pattern, and immediate.
class XXEvalPattern <ValueType vt, dag pattern, bits<8> imm> :
Pat<(vt pattern), (XXEVAL $vA, $vB, $vC, imm)> {}
-class DagCondVNot<dag d, bit negate> {
- // Utility to define a vnot around the dag.
- dag res = !if(!ne(negate, 0),
- (vnot d),
- d);
-}
-
-class XXEvalUnaryPattern<ValueType vt> {
- // vnot Operand B
- dag vnotB = (vnot vt:$vB);
- // vnot Operand C
- dag vnotC = (vnot vt:$vC);
-}
-
-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 = DagCondVNot<(op vt:$vB, vt:$vC), notResult>.res;
+ // Helper class to generate binary operation DAGs for various vector types.
+ // For v4i32, emits (op B C).
+ // For other types, bitcasts operands to v4i32, applies the op, then bitcasts back.
+class BinaryOpDag<ValueType vt, SDPatternOperator op > {
+ // The DAG for the binary operation.
+ dag OpDag = !if( !eq(vt, v4i32),
+ (op vt:$vB, vt:$vC),
+ (vt (bitconvert (op (v4i32 (bitconvert vt:$vB)), (v4i32 (bitconvert vt:$vC)))))
+ );
+ // The DAG for the binary operation with a NOT applied to the result.
+ dag VnotOpDag = !if( !eq(vt, v4i32),
+ (vnot (op vt:$vB, vt:$vC)),
+ (vt (bitconvert (vnot (op (v4i32 (bitconvert vt:$vB)), (v4i32 (bitconvert vt:$vC))))))
+ );
+
+}
+
+ // Helper class to generate unary NOT patterns for vector types.
+ // For v4i32, emits (vnot B) or (vnot C).
+ // For other types, bitcasts operand to v4i32, applies vnot, then bitcasts back.
+class XXEvalUnaryNotPattern<ValueType vt> {
+ dag vnotB = !if( !eq(vt, v4i32),
+ (vnot vt:$vB),
+ (vt (bitconvert (vnot (v4i32 (bitconvert vt:$vB)))))
+ );
+ dag vnotC = !if( !eq(vt, v4i32),
+ (vnot vt:$vC),
+ (vt (bitconvert (vnot (v4i32 (bitconvert vt:$vC)))))
+ );
+}
+
+ // Wrapper class for binary patterns with optional NOT on the result.
+ // If 'not' is 0, emits the binary op; if 1, emits vnot of the binary op.
+class XXEvalBinaryPattern<ValueType vt, SDPatternOperator op, bit not = 0> {
+ dag opPat = !if( !eq(not, 0),
+ BinaryOpDag<vt, op>.OpDag,
+ BinaryOpDag<vt, op>.VnotOpDag
+ );
}
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 = 22
+ // Multiclass for ternary patterns of the form vselect(A, X, and(B, C)).
+ // vselect(A, xor(B,C), and(B,C)) => imm = baseImm = 22
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 = 24
+ // vselect(A, nor(B,C), and(B,C)) => imm = baseImm + 2 = 24
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 = 25
+ // vselect(A, eqv(B,C), and(B,C)) => imm = baseImm + 3 = 25
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 = 26
+ // vselect(A, not(C), and(B,C)) => imm = baseImm + 4 = 26
def : XXEvalPattern<vt,
- (vselect vt:$vA, XXEvalUnaryPattern<vt>.vnotC, XXEvalBinaryPattern<vt, and>.opPat),
+ (vselect vt:$vA, XXEvalUnaryNotPattern<vt>.vnotC, XXEvalBinaryPattern<vt, and>.opPat),
!add(baseImm, 4)>;
- // Ternary(A, not(B), and(B,C)) => imm: baseImm + 6 = 28
+ // vselect(A, not(B), and(B,C)) => imm = baseImm + 6 = 28
def : XXEvalPattern<vt,
- (vselect vt:$vA, XXEvalUnaryPattern<vt>.vnotB, XXEvalBinaryPattern<vt, and>.opPat),
+ (vselect vt:$vA, XXEvalUnaryNotPattern<vt>.vnotB, 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 = 49
+ // Multiclass for ternary patterns of the form vselect(A, X, B).
+ // vselect(A, and(B,C), B) => imm = baseImm = 49
def : XXEvalPattern<vt,
(vselect vt:$vA, XXEvalBinaryPattern<vt, and>.opPat, vt:$vB),
baseImm>;
- // Ternary(A, nor(B,C), B) => imm: baseImm + 7 = 56
+ // vselect(A, nor(B,C), B) => imm = baseImm + 7 = 56
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 = 57
+ // vselect(A, eqv(B,C), B) => imm = baseImm + 8 = 57
def : XXEvalPattern<vt,
(vselect vt:$vA, XXEvalBinaryPattern<vt, xor, 1>.opPat, vt:$vB),
!add(baseImm, 8)>;
- // Ternary(A, not(C), B) => imm: baseImm + 9 = 58
- def : XXEvalPattern<vt,
- (vselect vt:$vA, XXEvalUnaryPattern<vt>.vnotC, vt:$vB),
- !add(baseImm, 9)>;
- // Ternary(A, nand(B,C), B) => imm: baseImm + 13 = 62
+ // vselect(A, nand(B,C), B) => imm = baseImm + 13 = 62
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 = 81
+ // Multiclass for ternary patterns of the form vselect(A, X, C).
+ // vselect(A, and(B,C), C) => imm = baseImm = 81
def : XXEvalPattern<vt,
(vselect vt:$vA, XXEvalBinaryPattern<vt, and>.opPat, vt:$vC),
baseImm>;
- // Ternary(A, nor(B,C), C) => imm: baseImm + 7 = 88
+ // vselect(A, nor(B,C), C) => imm = baseImm + 7 = 88
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 = 89
+ // vselect(A, eqv(B,C), C) => imm = baseImm + 8 = 89
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 = 94
+ // vselect(A, nand(B,C), C) => imm = baseImm + 13 = 94
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 = 97
+ // Multiclass for ternary patterns of the form vselect(A, X, xor(B,C)).
+ // vselect(A, and(B,C), xor(B,C)) => imm = baseImm = 97
def : XXEvalPattern<vt,
(vselect vt:$vA, XXEvalBinaryPattern<vt, and>.opPat, XXEvalBinaryPattern<vt, xor>.opPat),
baseImm>;
- // Ternary(A, B, xor(B,C)) => imm: baseImm + 2 = 99
+ // vselect(A, B, xor(B,C)) => imm = baseImm + 2 = 99
def : XXEvalPattern<vt,
(vselect vt:$vA, vt:$vB, XXEvalBinaryPattern<vt, xor>.opPat),
!add(baseImm, 2)>;
- // Ternary(A, C, xor(B,C)) => imm: baseImm + 4 = 101
+ // vselect(A, C, xor(B,C)) => imm = baseImm + 4 = 101
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 = 103
+ // vselect(A, or(B,C), xor(B,C)) => imm = baseImm + 6 = 103
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 = 104
+ // vselect(A, nor(B,C), xor(B,C)) => imm = baseImm + 7 = 104
def : XXEvalPattern<vt,
(vselect vt:$vA, XXEvalBinaryPattern<vt, or, 1>.opPat, XXEvalBinaryPattern<vt, xor>.opPat),
!add(baseImm, 7)>;
}
+ // Instantiate XXEval patterns for vector types v4i32 and v2i64
+ // with higher complexity for HasP10Vector.
+let Predicates = [HasP10Vector] in {
+ let AddedComplexity = 500 in {
+ foreach type = [v4i32, v2i64] in {
+ defm : XXEvalVSelectWithXAnd<type, 22>;
+ defm : XXEvalVSelectWithXB<type, 49>;
+ defm : XXEvalVSelectWithXC<type, 81>;
+ defm : XXEvalVSelectWithXXor<type, 97>;
+ }
+ }
+}
+
let Predicates = [PrefixInstrs, HasP10Vector] in {
let AddedComplexity = 400 in {
def : Pat<(v4i32 (build_vector i32immNonAllOneNonZero:$A,
@@ -2382,15 +2413,6 @@ let Predicates = [PrefixInstrs, HasP10Vector] in {
// (xor A, (or B, C))
def : XXEvalPattern<v4i32, (xor v4i32:$vA, (or v4i32:$vB, v4i32:$vC)), 120>;
- // Utilize xxeval instruction for ternary vector expressions.
- defm : XXEvalVSelectWithXAnd<v4i32, 22>;
-
- defm : XXEvalVSelectWithXB<v4i32, 49>;
-
- defm : XXEvalVSelectWithXC<v4i32, 81>;
-
- defm : XXEvalVSelectWithXXor<v4i32, 97>;
-
// Anonymous patterns to select prefixed VSX loads and stores.
// Load / Store f128
def : Pat<(f128 (load PDForm:$src)),
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
index dfb910b8d0c75..19305336f78df 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
@@ -31,12 +31,10 @@ define <2 x i64> @ternary_A_xor_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i
; CHECK-LABEL: ternary_A_xor_BC_and_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlxor vs0, v3, v4
-; CHECK-NEXT: xxland vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 22
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -67,12 +65,10 @@ define <2 x i64> @ternary_A_nor_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i
; CHECK-LABEL: ternary_A_nor_BC_and_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v4
-; CHECK-NEXT: xxland vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 24
; CHECK-NEXT: blr
entry:
%or = or <2 x i64> %B, %C
@@ -104,12 +100,10 @@ define <2 x i64> @ternary_A_eqv_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i
; CHECK-LABEL: ternary_A_eqv_BC_and_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxleqv vs0, v3, v4
-; CHECK-NEXT: xxland vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 25
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -140,12 +134,10 @@ define <2 x i64> @ternary_A_not_C_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i6
; CHECK-LABEL: ternary_A_not_C_and_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v4, v4
-; CHECK-NEXT: xxland vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 26
; CHECK-NEXT: blr
entry:
%not = xor <2 x i64> %C, <i64 -1, i64 -1> ; Vector not operation
@@ -175,12 +167,10 @@ define <2 x i64> @ternary_A_not_B_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i6
; CHECK-LABEL: ternary_A_not_B_and_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v3
-; CHECK-NEXT: xxland vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 28
; CHECK-NEXT: blr
entry:
%not = xor <2 x i64> %B, <i64 -1, i64 -1> ; Vector not operation
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
index 9943c35dfb134..2b060060a0fa9 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
@@ -30,11 +30,10 @@ define <2 x i64> @ternary_A_and_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_and_BC_B_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxland vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v3, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 49
; CHECK-NEXT: blr
entry:
%and = and <2 x i64> %B, %C
@@ -63,11 +62,10 @@ define <2 x i64> @ternary_A_nor_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_nor_BC_B_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v3, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 56
; CHECK-NEXT: blr
entry:
%or = or <2 x i64> %B, %C
@@ -97,11 +95,10 @@ define <2 x i64> @ternary_A_eqv_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_eqv_BC_B_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxleqv vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v3, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 57
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -110,38 +107,6 @@ entry:
ret <2 x i64> %res
}
-; Function to test ternary(A, not(C), B) for <4 x i32>
-define <4 x i32> @ternary_A_not_C_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
-; CHECK-LABEL: ternary_A_not_C_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, 58
-; 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> %not, <4 x i32> %B
- ret <4 x i32> %res
-}
-
-; Function to test ternary(A, not(C), B) for <2 x i64>
-define <2 x i64> @ternary_A_not_C_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) {
-; CHECK-LABEL: ternary_A_not_C_B_2x64:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v4, v4
-; CHECK-NEXT: xxsplti32dx v5, 1, 63
-; CHECK-NEXT: vsld v2, v2, v5
-; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v3, vs0, v2
-; 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> %not, <2 x i64> %B
- ret <2 x i64> %res
-}
-
; Function to test ternary(A, nand(B, C), B) for <4 x i32>
define <4 x i32> @ternary_A_nand_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
; CHECK-LABEL: ternary_A_nand_BC_B_4x32:
@@ -163,11 +128,10 @@ define <2 x i64> @ternary_A_nand_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64>
; CHECK-LABEL: ternary_A_nand_BC_B_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnand vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v3, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 62
; CHECK-NEXT: blr
entry:
%and = and <2 x i64> %B, %C
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
index f770cf768147a..54fda6063bfac 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
@@ -30,11 +30,10 @@ define <2 x i64> @ternary_A_and_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_and_BC_C_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxland vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v4, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 81
; CHECK-NEXT: blr
entry:
%and = and <2 x i64> %B, %C
@@ -63,11 +62,10 @@ define <2 x i64> @ternary_A_nor_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_nor_BC_C_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v4, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 88
; CHECK-NEXT: blr
entry:
%or = or <2 x i64> %B, %C
@@ -97,11 +95,10 @@ define <2 x i64> @ternary_A_eqv_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_eqv_BC_C_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxleqv vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v4, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 89
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -131,11 +128,10 @@ define <2 x i64> @ternary_A_nand_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64>
; CHECK-LABEL: ternary_A_nand_BC_C_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnand vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, v4, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 94
; CHECK-NEXT: blr
entry:
%and = and <2 x i64> %B, %C
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-or.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-or.ll
index bf2b691056781..1ad7e95e3682e 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-or.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-or.ll
@@ -120,11 +120,11 @@ define <4 x i32> @ternary_A_eqv_BC_or_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i3
; CHECK-LABEL: ternary_A_eqv_BC_or_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlxor vs0, v3, v4
+; CHECK-NEXT: xxleqv vs0, v3, v4
; CHECK-NEXT: xxlor vs1, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, vs1, vs0, 58
+; CHECK-NEXT: xxsel v2, vs1, vs0, v2
; CHECK-NEXT: blr
entry:
%xor = xor <4 x i32> %B, %C
@@ -159,10 +159,11 @@ define <4 x i32> @ternary_A_not_C_or_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32
; CHECK-LABEL: ternary_A_not_C_or_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlor vs0, v3, v4
+; CHECK-NEXT: xxlnor vs0, v4, v4
+; CHECK-NEXT: xxlor vs1, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, vs0, v4, 58
+; CHECK-NEXT: xxsel v2, vs1, vs0, v2
; CHECK-NEXT: blr
entry:
%not = xor <4 x i32> %C, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
@@ -195,10 +196,11 @@ define <4 x i32> @ternary_A_not_B_or_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32
; CHECK-LABEL: ternary_A_not_B_or_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxlor vs0, v3, v4
+; CHECK-NEXT: xxlnor vs0, v3, v3
+; CHECK-NEXT: xxlor vs1, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, vs0, v3, 58
+; CHECK-NEXT: xxsel v2, vs1, vs0, v2
; CHECK-NEXT: blr
entry:
%not = xor <4 x i32> %B, <i32 -1, i32 -1, i32 -1, i32 -1> ; Vector not operation
@@ -231,11 +233,11 @@ define <4 x i32> @ternary_A_nand_BC_or_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i
; CHECK-LABEL: ternary_A_nand_BC_or_BC_4x32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxleqv v5, v5, v5
-; CHECK-NEXT: xxland vs0, v3, v4
+; CHECK-NEXT: xxlnand vs0, v3, v4
; CHECK-NEXT: xxlor vs1, v3, v4
; CHECK-NEXT: vslw v2, v2, v5
; CHECK-NEXT: vsraw v2, v2, v5
-; CHECK-NEXT: xxeval v2, v2, vs1, vs0, 58
+; CHECK-NEXT: xxsel v2, vs1, vs0, v2
; CHECK-NEXT: blr
entry:
%and = and <4 x i32> %B, %C
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
index 2725525846dd8..74d3a3bf6196e 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
@@ -31,12 +31,10 @@ define <2 x i64> @ternary_A_and_BC_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i
; CHECK-LABEL: ternary_A_and_BC_xor_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxland vs0, v3, v4
-; CHECK-NEXT: xxlxor vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 97
; CHECK-NEXT: blr
entry:
%and = and <2 x i64> %B, %C
@@ -65,11 +63,10 @@ define <2 x i64> @ternary_A_B_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_B_xor_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlxor vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs0, v3, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 99
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -97,11 +94,10 @@ define <2 x i64> @ternary_A_C_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %
; CHECK-LABEL: ternary_A_C_xor_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlxor vs0, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs0, v4, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 101
; CHECK-NEXT: blr
entry:
%xor = xor <2 x i64> %B, %C
@@ -130,12 +126,10 @@ define <2 x i64> @ternary_A_or_BC_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i6
; CHECK-LABEL: ternary_A_or_BC_xor_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlor vs0, v3, v4
-; CHECK-NEXT: xxlxor vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 103
; CHECK-NEXT: blr
entry:
%or = or <2 x i64> %B, %C
@@ -166,12 +160,10 @@ define <2 x i64> @ternary_A_nor_BC_xor_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i
; CHECK-LABEL: ternary_A_nor_BC_xor_BC_2x64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor v5, v5, v5
-; CHECK-NEXT: xxlnor vs0, v3, v4
-; CHECK-NEXT: xxlxor vs1, v3, v4
; CHECK-NEXT: xxsplti32dx v5, 1, 63
; CHECK-NEXT: vsld v2, v2, v5
; CHECK-NEXT: vsrad v2, v2, v5
-; CHECK-NEXT: xxsel v2, vs1, vs0, v2
+; CHECK-NEXT: xxeval v2, v2, v3, v4, 104
; CHECK-NEXT: blr
entry:
%or = or <2 x i64> %B, %C
>From e3ab08c37d255ecf2e05b3959ddd9e45e2f67ada Mon Sep 17 00:00:00 2001
From: Tony Varghese <tony.varghese at ibm.com>
Date: Wed, 2 Jul 2025 19:11:05 +0000
Subject: [PATCH 4/4] [PowerPC] Emit xxeval instruction for ternary vector
patterns v4i32, v2i64, v16i8 and v8i16 operand types
---
llvm/lib/Target/PowerPC/PPCInstrP10.td | 111 +++++++++++-
.../CodeGen/PowerPC/xxeval-vselect-x-and.ll | 164 ++++++++++++++++++
.../CodeGen/PowerPC/xxeval-vselect-x-b.ll | 126 ++++++++++++++
.../CodeGen/PowerPC/xxeval-vselect-x-c.ll | 126 ++++++++++++++
.../CodeGen/PowerPC/xxeval-vselect-x-xor.ll | 158 +++++++++++++++++
5 files changed, 681 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCInstrP10.td b/llvm/lib/Target/PowerPC/PPCInstrP10.td
index fb79f5a7cadae..aa31478589cea 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrP10.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrP10.td
@@ -2178,7 +2178,6 @@ class BinaryOpDag<ValueType vt, SDPatternOperator op > {
(vnot (op vt:$vB, vt:$vC)),
(vt (bitconvert (vnot (op (v4i32 (bitconvert vt:$vB)), (v4i32 (bitconvert vt:$vC))))))
);
-
}
// Helper class to generate unary NOT patterns for vector types.
@@ -2292,16 +2291,120 @@ multiclass XXEvalVSelectWithXXor<ValueType vt, bits<8> baseImm>{
!add(baseImm, 7)>;
}
- // Instantiate XXEval patterns for vector types v4i32 and v2i64
- // with higher complexity for HasP10Vector.
+ // Pattern class using COPY_TO_REGCLASS for type casting
+class XXEvalBitcastPattern<ValueType vt, dag pattern, bits<8> imm> :
+ Pat<(vt pattern),
+ (COPY_TO_REGCLASS
+ (XXEVAL
+ (COPY_TO_REGCLASS vt:$vA, VSRC),
+ (COPY_TO_REGCLASS vt:$vB, VSRC),
+ (COPY_TO_REGCLASS vt:$vC, VSRC),
+ imm),
+ VRRC)>;
+
+multiclass XXEvalVSelectWithXAndCast<ValueType vt, bits<8> baseImm> {
+ // Multiclass for ternary patterns using COPY_TO_REGCLASS for unsupported types
+ // vselect(A, xor(B,C), and(B,C)) => imm = baseImm = 22
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, xor>.opPat, XXEvalBinaryPattern<vt, and>.opPat),
+ baseImm>;
+ // vselect(A, nor(B,C), and(B,C)) => imm = baseImm + 2 = 24
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or, 1>.opPat, XXEvalBinaryPattern<vt, and>.opPat),
+ !add(baseImm, 2)>;
+ // vselect(A, eqv(B,C), and(B,C)) => imm = baseImm + 3 = 25
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, xor, 1>.opPat, XXEvalBinaryPattern<vt, and>.opPat),
+ !add(baseImm, 3)>;
+ // vselect(A, not(C), and(B,C)) => imm = baseImm + 4 = 26
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalUnaryNotPattern<vt>.vnotC, XXEvalBinaryPattern<vt, and>.opPat),
+ !add(baseImm, 4)>;
+ // vselect(A, not(B), and(B,C)) => imm = baseImm + 6 = 28
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalUnaryNotPattern<vt>.vnotB, XXEvalBinaryPattern<vt, and>.opPat),
+ !add(baseImm, 6)>;
+}
+
+multiclass XXEvalVSelectWithXBCast<ValueType vt, bits<8> baseImm>{
+ // vselect(A, and(B,C), B) => imm = baseImm = 49
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and>.opPat, vt:$vB),
+ baseImm>;
+ // vselect(A, nor(B,C), B) => imm = baseImm + 7 = 56
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or, 1>.opPat, vt:$vB),
+ !add(baseImm, 7)>;
+ // vselect(A, eqv(B,C), B) => imm = baseImm + 8 = 57
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, xor, 1>.opPat, vt:$vB),
+ !add(baseImm, 8)>;
+ // vselect(A, nand(B,C), B) => imm = baseImm + 13 = 62
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and, 1>.opPat, vt:$vB),
+ !add(baseImm, 13)>;
+}
+
+multiclass XXEvalVSelectWithXCCast<ValueType vt, bits<8> baseImm>{
+ // vselect(A, and(B,C), C) => imm = baseImm = 81
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and>.opPat, vt:$vC),
+ baseImm>;
+ // vselect(A, nor(B,C), C) => imm = baseImm + 7 = 88
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or, 1>.opPat, vt:$vC),
+ !add(baseImm, 7)>;
+ // vselect(A, eqv(B,C), C) => imm = baseImm + 8 = 89
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, xor, 1>.opPat, vt:$vC),
+ !add(baseImm, 8)>;
+ // vselect(A, nand(B,C), C) => imm = baseImm + 13 = 94
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and, 1>.opPat, vt:$vC),
+ !add(baseImm, 13)>;
+}
+
+multiclass XXEvalVSelectWithXXorCast<ValueType vt, bits<8> baseImm>{
+ // vselect(A, and(B,C), xor(B,C)) => imm = baseImm = 97
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, and>.opPat, XXEvalBinaryPattern<vt, xor>.opPat),
+ baseImm>;
+ // vselect(A, B, xor(B,C)) => imm = baseImm + 2 = 99
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, vt:$vB, XXEvalBinaryPattern<vt, xor>.opPat),
+ !add(baseImm, 2)>;
+ // vselect(A, C, xor(B,C)) => imm = baseImm + 4 = 101
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, vt:$vC, XXEvalBinaryPattern<vt, xor>.opPat),
+ !add(baseImm, 4)>;
+ // vselect(A, or(B,C), xor(B,C)) => imm = baseImm + 6 = 103
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or>.opPat, XXEvalBinaryPattern<vt, xor>.opPat),
+ !add(baseImm, 6)>;
+ // vselect(A, nor(B,C), xor(B,C)) => imm = baseImm + 7 = 104
+ def : XXEvalBitcastPattern<vt,
+ (vselect vt:$vA, XXEvalBinaryPattern<vt, or, 1>.opPat, XXEvalBinaryPattern<vt, xor>.opPat),
+ !add(baseImm, 7)>;
+}
+
+// Instantiate XXEval patterns for all vector types
let Predicates = [HasP10Vector] in {
let AddedComplexity = 500 in {
+ // For types directly supported by XXEVAL (v4i32, v2i64)
foreach type = [v4i32, v2i64] in {
defm : XXEvalVSelectWithXAnd<type, 22>;
defm : XXEvalVSelectWithXB<type, 49>;
defm : XXEvalVSelectWithXC<type, 81>;
defm : XXEvalVSelectWithXXor<type, 97>;
- }
+ }
+
+ // For types that need COPY_TO_REGCLASS (v8i16, v16i8)
+ foreach type = [v8i16, v16i8] in {
+ defm : XXEvalVSelectWithXAndCast<type, 22>;
+ defm : XXEvalVSelectWithXBCast<type, 49>;
+ defm : XXEvalVSelectWithXCCast<type, 81>;
+ defm : XXEvalVSelectWithXXorCast<type, 97>;
+ }
}
}
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
index 19305336f78df..b41220b01373a 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
@@ -43,6 +43,38 @@ entry:
ret <2 x i64> %res
}
+; Function to test ternary(A, xor(B, C), and(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_xor_BC_and_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_and_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, 22
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <16 x i8> %B, %C
+ %and = and <16 x i8> %B, %C
+ %res = select <16 x i1> %A, <16 x i8> %xor, <16 x i8> %and
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, xor(B, C), and(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_xor_BC_and_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_xor_BC_and_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, 22
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <8 x i16> %B, %C
+ %and = and <8 x i16> %B, %C
+ %res = select <8 x i1> %A, <8 x i16> %xor, <8 x i16> %and
+ ret <8 x i16> %res
+}
+
; Function to test ternary(A, nor(B, C), and(B, C)) for <4 x i32>
define <4 x i32> @ternary_A_nor_BC_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
; CHECK-LABEL: ternary_A_nor_BC_and_BC_4x32:
@@ -78,6 +110,40 @@ entry:
ret <2 x i64> %res
}
+; Function to test ternary(A, nor(B, C), and(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_nor_BC_and_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_nor_BC_and_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, 24
+; 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
+ %and = and <16 x i8> %B, %C
+ %res = select <16 x i1> %A, <16 x i8> %nor, <16 x i8> %and
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, nor(B, C), and(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_nor_BC_and_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_nor_BC_and_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, 24
+; 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
+ %and = and <8 x i16> %B, %C
+ %res = select <8 x i1> %A, <8 x i16> %nor, <8 x i16> %and
+ ret <8 x i16> %res
+}
+
; Function to test ternary(A, eqv(B, C), and(B, C)) for <4 x i32>
define <4 x i32> @ternary_A_eqv_BC_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
; CHECK-LABEL: ternary_A_eqv_BC_and_BC_4x32:
@@ -113,6 +179,40 @@ entry:
ret <2 x i64> %res
}
+; Function to test ternary(A, eqv(B, C), and(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_eqv_BC_and_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_eqv_BC_and_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, 25
+; 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
+ %res = select <16 x i1> %A, <16 x i8> %eqv, <16 x i8> %and
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, eqv(B, C), and(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_eqv_BC_and_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_eqv_BC_and_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, 25
+; 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
+ %res = select <8 x i1> %A, <8 x i16> %eqv, <8 x i16> %and
+ ret <8 x i16> %res
+}
+
; Function to test ternary(A, not(C), and(B, C)) for <4 x i32>
define <4 x i32> @ternary_A_not_C_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
; CHECK-LABEL: ternary_A_not_C_and_BC_4x32:
@@ -146,6 +246,38 @@ entry:
ret <2 x i64> %res
}
+; Function to test ternary(A, not(C), and(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_not_C_and_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_not_C_and_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, 26
+; 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
+ %and = and <16 x i8> %B, %C
+ %res = select <16 x i1> %A, <16 x i8> %not, <16 x i8> %and
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, not(C), and(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_not_C_and_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_not_C_and_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, 26
+; 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
+ %and = and <8 x i16> %B, %C
+ %res = select <8 x i1> %A, <8 x i16> %not, <8 x i16> %and
+ ret <8 x i16> %res
+}
+
; Function to test ternary(A, not(B), and(B, C)) for <4 x i32>
define <4 x i32> @ternary_A_not_B_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
; CHECK-LABEL: ternary_A_not_B_and_BC_4x32:
@@ -178,3 +310,35 @@ entry:
%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 <16 x i8>
+define <16 x i8> @ternary_A_not_B_and_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_not_B_and_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, 28
+; 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
+ %and = and <16 x i8> %B, %C
+ %res = select <16 x i1> %A, <16 x i8> %not, <16 x i8> %and
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, not(B), and(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_not_B_and_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_not_B_and_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, 28
+; 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
+ %and = and <8 x i16> %B, %C
+ %res = select <8 x i1> %A, <8 x i16> %not, <8 x i16> %and
+ ret <8 x i16> %res
+}
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
index 2b060060a0fa9..8fd2453266706 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
@@ -41,6 +41,36 @@ entry:
ret <2 x i64> %res
}
+; Function to test ternary(A, and(B, C), B) for <16 x i8>
+define <16 x i8> @ternary_A_and_BC_B_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_and_BC_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, 49
+; CHECK-NEXT: blr
+entry:
+ %and = and <16 x i8> %B, %C
+ %res = select <16 x i1> %A, <16 x i8> %and, <16 x i8> %B
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, and(B, C), B) for <8 x i16>
+define <8 x i16> @ternary_A_and_BC_B_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_and_BC_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, 49
+; CHECK-NEXT: blr
+entry:
+ %and = and <8 x i16> %B, %C
+ %res = select <8 x i1> %A, <8 x i16> %and, <8 x i16> %B
+ ret <8 x i16> %res
+}
+
; Function to test ternary(A, nor(B, C), B) for <4 x i32>
define <4 x i32> @ternary_A_nor_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
; CHECK-LABEL: ternary_A_nor_BC_B_4x32:
@@ -74,6 +104,38 @@ entry:
ret <2 x i64> %res
}
+; Function to test ternary(A, nor(B, C), B) for <16 x i8>
+define <16 x i8> @ternary_A_nor_BC_B_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_nor_BC_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, 56
+; 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> %nor, <16 x i8> %B
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, nor(B, C), B) for <8 x i16>
+define <8 x i16> @ternary_A_nor_BC_B_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_nor_BC_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, 56
+; 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> %nor, <8 x i16> %B
+ ret <8 x i16> %res
+}
+
; Function to test ternary(A, eqv(B, C), B) for <4 x i32>
define <4 x i32> @ternary_A_eqv_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
; CHECK-LABEL: ternary_A_eqv_BC_B_4x32:
@@ -107,6 +169,38 @@ entry:
ret <2 x i64> %res
}
+; Function to test ternary(A, eqv(B, C), B) for <16 x i8>
+define <16 x i8> @ternary_A_eqv_BC_B_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_eqv_BC_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, 57
+; 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
+ %res = select <16 x i1> %A, <16 x i8> %eqv, <16 x i8> %B
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, eqv(B, C), B) for <8 x i16>
+define <8 x i16> @ternary_A_eqv_BC_B_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_eqv_BC_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, 57
+; 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
+ %res = select <8 x i1> %A, <8 x i16> %eqv, <8 x i16> %B
+ ret <8 x i16> %res
+}
+
; Function to test ternary(A, nand(B, C), B) for <4 x i32>
define <4 x i32> @ternary_A_nand_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
; CHECK-LABEL: ternary_A_nand_BC_B_4x32:
@@ -139,3 +233,35 @@ entry:
%res = select <2 x i1> %A, <2 x i64> %nand, <2 x i64> %B
ret <2 x i64> %res
}
+
+; Function to test ternary(A, nand(B, C), B) for <16 x i8>
+define <16 x i8> @ternary_A_nand_BC_B_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_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, 62
+; 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> %nand, <16 x i8> %B
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, nand(B, C), B) for <8 x i16>
+define <8 x i16> @ternary_A_nand_BC_B_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_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, 62
+; 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> %nand, <8 x i16> %B
+ ret <8 x i16> %res
+}
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
index 54fda6063bfac..c25288df78af6 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
@@ -41,6 +41,36 @@ entry:
ret <2 x i64> %res
}
+; Function to test ternary(A, and(B, C), C) for <16 x i8>
+define <16 x i8> @ternary_A_and_BC_C_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_and_BC_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, 81
+; CHECK-NEXT: blr
+entry:
+ %and = and <16 x i8> %B, %C
+ %res = select <16 x i1> %A, <16 x i8> %and, <16 x i8> %C
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, and(B, C), C) for <8 x i16>
+define <8 x i16> @ternary_A_and_BC_C_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_and_BC_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, 81
+; CHECK-NEXT: blr
+entry:
+ %and = and <8 x i16> %B, %C
+ %res = select <8 x i1> %A, <8 x i16> %and, <8 x i16> %C
+ ret <8 x i16> %res
+}
+
; Function to test ternary(A, nor(B, C), C) for <4 x i32>
define <4 x i32> @ternary_A_nor_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
; CHECK-LABEL: ternary_A_nor_BC_C_4x32:
@@ -74,6 +104,38 @@ entry:
ret <2 x i64> %res
}
+; Function to test ternary(A, nor(B, C), C) for <16 x i8>
+define <16 x i8> @ternary_A_nor_BC_C_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_nor_BC_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, 88
+; 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> %nor, <16 x i8> %C
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, nor(B, C), C) for <8 x i16>
+define <8 x i16> @ternary_A_nor_BC_C_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_nor_BC_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, 88
+; 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> %nor, <8 x i16> %C
+ ret <8 x i16> %res
+}
+
; Function to test ternary(A, eqv(B, C), C) for <4 x i32>
define <4 x i32> @ternary_A_eqv_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
; CHECK-LABEL: ternary_A_eqv_BC_C_4x32:
@@ -107,6 +169,38 @@ entry:
ret <2 x i64> %res
}
+; Function to test ternary(A, eqv(B, C), C) for <16 x i8>
+define <16 x i8> @ternary_A_eqv_BC_C_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_eqv_BC_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, 89
+; 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
+ %res = select <16 x i1> %A, <16 x i8> %eqv, <16 x i8> %C
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, eqv(B, C), C) for <8 x i16>
+define <8 x i16> @ternary_A_eqv_BC_C_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_eqv_BC_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, 89
+; 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
+ %res = select <8 x i1> %A, <8 x i16> %eqv, <8 x i16> %C
+ ret <8 x i16> %res
+}
+
; Function to test ternary(A, nand(B, C), C) for <4 x i32>
define <4 x i32> @ternary_A_nand_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
; CHECK-LABEL: ternary_A_nand_BC_C_4x32:
@@ -139,3 +233,35 @@ entry:
%res = select <2 x i1> %A, <2 x i64> %nand, <2 x i64> %C
ret <2 x i64> %res
}
+
+; Function to test ternary(A, nand(B, C), C) for <16 x i8>
+define <16 x i8> @ternary_A_nand_BC_C_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_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, 94
+; 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> %nand, <16 x i8> %C
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, nand(B, C), C) for <8 x i16>
+define <8 x i16> @ternary_A_nand_BC_C_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_nand_BC_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, 94
+; 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> %nand, <8 x i16> %C
+ ret <8 x i16> %res
+}
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
index 74d3a3bf6196e..0fc296cc5a4e2 100644
--- a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
@@ -43,6 +43,38 @@ entry:
ret <2 x i64> %res
}
+; Function to test ternary(A, and(B, C), xor(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_and_BC_xor_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_and_BC_xor_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, 97
+; CHECK-NEXT: blr
+entry:
+ %and = and <16 x i8> %B, %C
+ %xor = xor <16 x i8> %B, %C
+ %res = select <16 x i1> %A, <16 x i8> %and, <16 x i8> %xor
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, and(B, C), xor(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_and_BC_xor_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_and_BC_xor_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, 97
+; CHECK-NEXT: blr
+entry:
+ %and = and <8 x i16> %B, %C
+ %xor = xor <8 x i16> %B, %C
+ %res = select <8 x i1> %A, <8 x i16> %and, <8 x i16> %xor
+ ret <8 x i16> %res
+}
+
; Function to test ternary(A, B, xor(B, C)) for <4 x i32>
define <4 x i32> @ternary_A_B_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
; CHECK-LABEL: ternary_A_B_xor_BC_4x32:
@@ -74,6 +106,36 @@ entry:
ret <2 x i64> %res
}
+; Function to test ternary(A, B, xor(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_B_xor_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_B_xor_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, 99
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <16 x i8> %B, %C
+ %res = select <16 x i1> %A, <16 x i8> %B, <16 x i8> %xor
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, B, xor(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_B_xor_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_B_xor_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, 99
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <8 x i16> %B, %C
+ %res = select <8 x i1> %A, <8 x i16> %B, <8 x i16> %xor
+ ret <8 x i16> %res
+}
+
; Function to test ternary(A, C, xor(B, C)) for <4 x i32>
define <4 x i32> @ternary_A_C_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
; CHECK-LABEL: ternary_A_C_xor_BC_4x32:
@@ -105,6 +167,36 @@ entry:
ret <2 x i64> %res
}
+; Function to test ternary(A, C, xor(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_C_xor_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_C_xor_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, 101
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <16 x i8> %B, %C
+ %res = select <16 x i1> %A, <16 x i8> %C, <16 x i8> %xor
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, C, xor(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_C_xor_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_C_xor_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, 101
+; CHECK-NEXT: blr
+entry:
+ %xor = xor <8 x i16> %B, %C
+ %res = select <8 x i1> %A, <8 x i16> %C, <8 x i16> %xor
+ ret <8 x i16> %res
+}
+
; Function to test ternary(A, or(B, C), xor(B, C)) for <4 x i32>
define <4 x i32> @ternary_A_or_BC_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
; CHECK-LABEL: ternary_A_or_BC_xor_BC_4x32:
@@ -138,6 +230,38 @@ entry:
ret <2 x i64> %res
}
+; Function to test ternary(A, or(B, C), xor(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_or_BC_xor_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_or_BC_xor_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, 103
+; CHECK-NEXT: blr
+entry:
+ %or = or <16 x i8> %B, %C
+ %xor = xor <16 x i8> %B, %C
+ %res = select <16 x i1> %A, <16 x i8> %or, <16 x i8> %xor
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, or(B, C), xor(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_or_BC_xor_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_or_BC_xor_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, 103
+; CHECK-NEXT: blr
+entry:
+ %or = or <8 x i16> %B, %C
+ %xor = xor <8 x i16> %B, %C
+ %res = select <8 x i1> %A, <8 x i16> %or, <8 x i16> %xor
+ ret <8 x i16> %res
+}
+
; Function to test ternary(A, nor(B, C), xor(B, C)) for <4 x i32>
define <4 x i32> @ternary_A_nor_BC_xor_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) {
; CHECK-LABEL: ternary_A_nor_BC_xor_BC_4x32:
@@ -172,3 +296,37 @@ entry:
%res = select <2 x i1> %A, <2 x i64> %nor, <2 x i64> %xor
ret <2 x i64> %res
}
+
+; Function to test ternary(A, nor(B, C), xor(B, C)) for <16 x i8>
+define <16 x i8> @ternary_A_nor_BC_xor_BC_16x8(<16 x i1> %A, <16 x i8> %B, <16 x i8> %C) {
+; CHECK-LABEL: ternary_A_nor_BC_xor_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, 104
+; 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
+ %res = select <16 x i1> %A, <16 x i8> %nor, <16 x i8> %xor
+ ret <16 x i8> %res
+}
+
+; Function to test ternary(A, nor(B, C), xor(B, C)) for <8 x i16>
+define <8 x i16> @ternary_A_nor_BC_xor_BC_8x16(<8 x i1> %A, <8 x i16> %B, <8 x i16> %C) {
+; CHECK-LABEL: ternary_A_nor_BC_xor_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, 104
+; 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
+ %res = select <8 x i1> %A, <8 x i16> %nor, <8 x i16> %xor
+ ret <8 x i16> %res
+}
More information about the llvm-commits
mailing list