Skip to content

[NFC][PowerPC] Add testcases for locking down the xxeval instruction support for ternary operators #141601

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 3, 2025

Conversation

tonykuttai
Copy link
Contributor

NFC patch to add testcases for locking down the support of ternary operators using the xxsel instructions. Currently ternary operators are supoprted by emitting xxsel instructions instead of xxeval.

@llvmbot
Copy link
Member

llvmbot commented May 27, 2025

@llvm/pr-subscribers-backend-powerpc

Author: Tony Varghese (tonykuttai)

Changes

NFC patch to add testcases for locking down the support of ternary operators using the xxsel instructions. Currently ternary operators are supoprted by emitting xxsel instructions instead of xxeval.


Patch is 26.03 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/141601.diff

4 Files Affected:

  • (added) llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll (+188)
  • (added) llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll (+169)
  • (added) llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll (+138)
  • (added) llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll (+177)
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
new file mode 100644
index 0000000000000..05fb6534bebcd
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-and.ll
@@ -0,0 +1,188 @@
+; Test file to verify the emission of Vector selection instructions when ternary operators are used.
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc64le-unknown-unknown \
+; RUN:   -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc-ibm-aix-xcoff \
+; RUN:   -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc64-ibm-aix-xcoff \
+; RUN:   -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; Function to test ternary(A, xor(B, C), and(B, C)) for <4 x i32>
+; CHECK-LABEL: ternary_A_xor_BC_and_BC_4x32
+; CHECK: xxspltiw v5, 31
+; 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: blr
+define dso_local <4 x i32> @ternary_A_xor_BC_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+  %xor = xor <4 x i32> %B, %C
+  %and = and <4 x i32> %B, %C
+  %res = select <4 x i1> %A, <4 x i32> %xor, <4 x i32> %and
+  ret <4 x i32> %res
+}
+
+; Function to test ternary(A, xor(B, C), and(B, C)) for <2 x i64>
+; CHECK-LABEL: ternary_A_xor_BC_and_BC_2x64
+; CHECK: xxlxor 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: blr
+define dso_local <2 x i64> @ternary_A_xor_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+  %xor = xor <2 x i64> %B, %C
+  %and = and <2 x i64> %B, %C
+  %res = select <2 x i1> %A, <2 x i64> %xor, <2 x i64> %and
+  ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nor(B, C), and(B, C)) for <4 x i32>
+; CHECK-LABEL: ternary_A_nor_BC_and_BC_4x32
+; CHECK: xxspltiw v5, 31
+; 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: blr
+define dso_local <4 x i32> @ternary_A_nor_BC_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+  %or = or <4 x i32> %B, %C
+  %nor = xor <4 x i32> %or, <i32 -1, i32 -1, i32 -1, i32 -1>  ; Vector NOR operation
+  %and = and <4 x i32> %B, %C
+  %res = select <4 x i1> %A, <4 x i32> %nor, <4 x i32> %and
+  ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nor(B, C), and(B, C)) for <2 x i64>
+; CHECK-LABEL: ternary_A_nor_BC_and_BC_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: 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: blr
+define dso_local <2 x i64> @ternary_A_nor_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+  %or = or <2 x i64> %B, %C
+  %nor = xor <2 x i64> %or, <i64 -1, i64 -1>  ; Vector NOR operation
+  %and = and <2 x i64> %B, %C
+  %res = select <2 x i1> %A, <2 x i64> %nor, <2 x i64> %and
+  ret <2 x i64> %res
+}
+
+; Function to test ternary(A, eqv(B, C), and(B, C)) for <4 x i32>
+; CHECK-LABEL: ternary_A_eqv_BC_and_BC_4x32
+; CHECK: xxspltiw v5, 31
+; 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: blr
+define dso_local <4 x i32> @ternary_A_eqv_BC_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+  %xor = xor <4 x i32> %B, %C
+  %eqv = xor <4 x i32> %xor, <i32 -1, i32 -1, i32 -1, i32 -1>  ; Vector eqv operation
+  %and = and <4 x i32> %B, %C
+  %res = select <4 x i1> %A, <4 x i32> %eqv, <4 x i32> %and
+  ret <4 x i32> %res
+}
+
+; Function to test ternary(A, eqv(B, C), and(B, C)) for <2 x i64>
+; CHECK-LABEL: ternary_A_eqv_BC_and_BC_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: 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: blr
+define dso_local <2 x i64> @ternary_A_eqv_BC_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+  %xor = xor <2 x i64> %B, %C
+  %eqv = xor <2 x i64> %xor, <i64 -1, i64 -1>  ; Vector eqv operation
+  %and = and <2 x i64> %B, %C
+  %res = select <2 x i1> %A, <2 x i64> %eqv, <2 x i64> %and
+  ret <2 x i64> %res
+}
+
+; Function to test ternary(A, not(C), and(B, C)) for <4 x i32>
+; CHECK-LABEL: ternary_A_not_C_and_BC_4x32
+; CHECK: xxspltiw v5, 31
+; 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: blr
+define dso_local <4 x i32> @ternary_A_not_C_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+  %not = xor <4 x i32> %C, <i32 -1, i32 -1, i32 -1, i32 -1>  ; Vector not operation
+  %and = and <4 x i32> %B, %C
+  %res = select <4 x i1> %A, <4 x i32> %not, <4 x i32> %and
+  ret <4 x i32> %res
+}
+
+; Function to test ternary(A, not(C), and(B, C)) for <2 x i64>
+; CHECK-LABEL: ternary_A_not_C_and_BC_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: 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: blr
+define dso_local <2 x i64> @ternary_A_not_C_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+  %not = xor <2 x i64> %C, <i64 -1, i64 -1>  ; Vector not operation
+  %and = and <2 x i64> %B, %C
+  %res = select <2 x i1> %A, <2 x i64> %not, <2 x i64> %and
+  ret <2 x i64> %res
+}
+
+; Function to test ternary(A, not(B), and(B, C)) for <4 x i32>
+; CHECK-LABEL: ternary_A_not_B_and_BC_4x32
+; CHECK: xxspltiw v5, 31
+; 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: blr
+define dso_local <4 x i32> @ternary_A_not_B_and_BC_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+  %not = xor <4 x i32> %B, <i32 -1, i32 -1, i32 -1, i32 -1>  ; Vector not operation
+  %and = and <4 x i32> %B, %C
+  %res = select <4 x i1> %A, <4 x i32> %not, <4 x i32> %and
+  ret <4 x i32> %res
+}
+
+; Function to test ternary(A, not(B), and(B, C)) for <2 x i64>
+; CHECK-LABEL: ternary_A_not_B_and_BC_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: 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: blr
+define dso_local <2 x i64> @ternary_A_not_B_and_BC_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+  %not = xor <2 x i64> %B, <i64 -1, i64 -1>  ; Vector not operation
+  %and = and <2 x i64> %B, %C
+  %res = select <2 x i1> %A, <2 x i64> %not, <2 x i64> %and
+  ret <2 x i64> %res
+}
\ No newline at end of file
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
new file mode 100644
index 0000000000000..3966c69636986
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-b.ll
@@ -0,0 +1,169 @@
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc64le-unknown-unknown \
+; RUN:   -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc-ibm-aix-xcoff \
+; RUN:   -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc64-ibm-aix-xcoff \
+; RUN:   -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; Function to test ternary(A, and(B, C), B) for <4 x i32>
+; CHECK-LABEL: ternary_A_and_BC_B_4x32
+; CHECK: xxspltiw v5, 31
+; 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: blr
+define dso_local <4 x i32> @ternary_A_and_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+  %and = and <4 x i32> %B, %C
+  %res = select <4 x i1> %A, <4 x i32> %and, <4 x i32> %B
+  ret <4 x i32> %res
+}
+
+; Function to test ternary(A, and(B, C), B) for <2 x i64>
+; CHECK-LABEL: ternary_A_and_BC_B_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: 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: blr
+define dso_local <2 x i64> @ternary_A_and_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+  %and = and <2 x i64> %B, %C
+  %res = select <2 x i1> %A, <2 x i64> %and, <2 x i64> %B
+  ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nor(B, C), B) for <4 x i32>
+; CHECK-LABEL: ternary_A_nor_BC_B_4x32
+; CHECK: xxspltiw v5, 31
+; 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: blr
+define dso_local <4 x i32> @ternary_A_nor_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+  %or = or <4 x i32> %B, %C
+  %nor = xor <4 x i32> %or, <i32 -1, i32 -1, i32 -1, i32 -1>  ; Vector NOR operation
+  %res = select <4 x i1> %A, <4 x i32> %nor, <4 x i32> %B
+  ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nor(B, C), B) for <2 x i64>
+; CHECK-LABEL: ternary_A_nor_BC_B_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: 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: blr
+define dso_local <2 x i64> @ternary_A_nor_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+  %or = or <2 x i64> %B, %C
+  %nor = xor <2 x i64> %or, <i64 -1, i64 -1>  ; Vector NOR operation
+  %res = select <2 x i1> %A, <2 x i64> %nor, <2 x i64> %B
+  ret <2 x i64> %res
+}
+
+; Function to test ternary(A, eqv(B, C), B) for <4 x i32>
+; CHECK-LABEL: ternary_A_eqv_BC_B_4x32
+; CHECK: xxspltiw v5, 31
+; 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: blr
+define dso_local <4 x i32> @ternary_A_eqv_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+  %xor = xor <4 x i32> %B, %C
+  %eqv = xor <4 x i32> %xor, <i32 -1, i32 -1, i32 -1, i32 -1>  ; Vector eqv operation
+  %res = select <4 x i1> %A, <4 x i32> %eqv, <4 x i32> %B
+  ret <4 x i32> %res
+}
+
+; Function to test ternary(A, eqv(B, C), B) for <2 x i64>
+; CHECK-LABEL: ternary_A_eqv_BC_B_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: 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: blr
+define dso_local <2 x i64> @ternary_A_eqv_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+  %xor = xor <2 x i64> %B, %C
+  %eqv = xor <2 x i64> %xor, <i64 -1, i64 -1>  ; Vector eqv operation
+  %res = select <2 x i1> %A, <2 x i64> %eqv, <2 x i64> %B
+  ret <2 x i64> %res
+}
+
+; Function to test ternary(A, not(C), B) for <4 x i32>
+; CHECK-LABEL: ternary_A_not_C_B_4x32
+; CHECK: xxspltiw v5, 31
+; 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: blr
+define dso_local <4 x i32> @ternary_A_not_C_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+  %not = xor <4 x i32> %C, <i32 -1, i32 -1, i32 -1, i32 -1>  ; Vector not operation
+  %res = select <4 x i1> %A, <4 x i32> %not, <4 x i32> %B
+  ret <4 x i32> %res
+}
+
+; Function to test ternary(A, not(C), B) for <2 x i64>
+; CHECK-LABEL: ternary_A_not_C_B_2x64
+; CHECK: 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
+define dso_local <2 x i64> @ternary_A_not_C_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+  %not = xor <2 x i64> %C, <i64 -1, i64 -1>  ; Vector not operation
+  %res = select <2 x i1> %A, <2 x i64> %not, <2 x i64> %B
+  ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nand(B, C), B) for <4 x i32>
+; CHECK-LABEL: ternary_A_nand_BC_B_4x32
+; CHECK: xxspltiw v5, 31
+; 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: blr
+define dso_local <4 x i32> @ternary_A_nand_BC_B_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+  %and = and <4 x i32> %B, %C
+  %nand = xor <4 x i32> %and, <i32 -1, i32 -1, i32 -1, i32 -1>  ; Vector nand operation
+  %res = select <4 x i1> %A, <4 x i32> %nand, <4 x i32> %B
+  ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nand(B, C), B) for <2 x i64>
+; CHECK-LABEL: ternary_A_nand_BC_B_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: 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: blr
+define dso_local <2 x i64> @ternary_A_nand_BC_B_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+  %and = and <2 x i64> %B, %C
+  %nand = xor <2 x i64> %and, <i64 -1, i64 -1>  ; Vector nand operation
+  %res = select <2 x i1> %A, <2 x i64> %nand, <2 x i64> %B
+  ret <2 x i64> %res
+}
\ No newline at end of file
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
new file mode 100644
index 0000000000000..76ff1b2f2f683
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-c.ll
@@ -0,0 +1,138 @@
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc64le-unknown-unknown \
+; RUN:   -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc-ibm-aix-xcoff \
+; RUN:   -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc64-ibm-aix-xcoff \
+; RUN:   -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; Function to test ternary(A, and(B, C), C) for <4 x i32>
+; CHECK-LABEL: ternary_A_and_BC_C_4x32
+; CHECK: xxspltiw v5, 31
+; 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: blr
+define dso_local <4 x i32> @ternary_A_and_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+  %and = and <4 x i32> %B, %C
+  %res = select <4 x i1> %A, <4 x i32> %and, <4 x i32> %C
+  ret <4 x i32> %res
+}
+
+; Function to test ternary(A, and(B, C), C) for <2 x i64>
+; CHECK-LABEL: ternary_A_and_BC_C_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: 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: blr
+define dso_local <2 x i64> @ternary_A_and_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+  %and = and <2 x i64> %B, %C
+  %res = select <2 x i1> %A, <2 x i64> %and, <2 x i64> %C
+  ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nor(B, C), C) for <4 x i32>
+; CHECK-LABEL: ternary_A_nor_BC_C_4x32
+; CHECK: xxspltiw v5, 31
+; 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: blr
+define dso_local <4 x i32> @ternary_A_nor_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+  %or = or <4 x i32> %B, %C
+  %nor = xor <4 x i32> %or, <i32 -1, i32 -1, i32 -1, i32 -1>  ; Vector NOR operation
+  %res = select <4 x i1> %A, <4 x i32> %nor, <4 x i32> %C
+  ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nor(B, C), C) for <2 x i64>
+; CHECK-LABEL: ternary_A_nor_BC_C_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: 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: blr
+define dso_local <2 x i64> @ternary_A_nor_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+  %or = or <2 x i64> %B, %C
+  %nor = xor <2 x i64> %or, <i64 -1, i64 -1>  ; Vector NOR operation
+  %res = select <2 x i1> %A, <2 x i64> %nor, <2 x i64> %C
+  ret <2 x i64> %res
+}
+
+; Function to test ternary(A, eqv(B, C), C) for <4 x i32>
+; CHECK-LABEL: ternary_A_eqv_BC_C_4x32
+; CHECK: xxspltiw v5, 31
+; 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: blr
+define dso_local <4 x i32> @ternary_A_eqv_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+  %xor = xor <4 x i32> %B, %C
+  %eqv = xor <4 x i32> %xor, <i32 -1, i32 -1, i32 -1, i32 -1>  ; Vector eqv operation
+  %res = select <4 x i1> %A, <4 x i32> %eqv, <4 x i32> %C
+  ret <4 x i32> %res
+}
+
+; Function to test ternary(A, eqv(B, C), C) for <2 x i64>
+; CHECK-LABEL: ternary_A_eqv_BC_C_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: 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: blr
+define dso_local <2 x i64> @ternary_A_eqv_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+  %xor = xor <2 x i64> %B, %C
+  %eqv = xor <2 x i64> %xor, <i64 -1, i64 -1>  ; Vector eqv operation
+  %res = select <2 x i1> %A, <2 x i64> %eqv, <2 x i64> %C
+  ret <2 x i64> %res
+}
+
+; Function to test ternary(A, nand(B, C), C) for <4 x i32>
+; CHECK-LABEL: ternary_A_nand_BC_C_4x32
+; CHECK: xxspltiw v5, 31
+; 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: blr
+define dso_local <4 x i32> @ternary_A_nand_BC_C_4x32(<4 x i1> %A, <4 x i32> %B, <4 x i32> %C) local_unnamed_addr #0 {
+entry:
+  %and = and <4 x i32> %B, %C
+  %nand = xor <4 x i32> %and, <i32 -1, i32 -1, i32 -1, i32 -1>  ; Vector nand operation
+  %res = select <4 x i1> %A, <4 x i32> %nand, <4 x i32> %C
+  ret <4 x i32> %res
+}
+
+; Function to test ternary(A, nand(B, C), C) for <2 x i64>
+; CHECK-LABEL: ternary_A_nand_BC_C_2x64
+; CHECK: xxlxor v5, v5, v5
+; CHECK-NEXT: 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: blr
+define dso_local <2 x i64> @ternary_A_nand_BC_C_2x64(<2 x i1> %A, <2 x i64> %B, <2 x i64> %C) local_unnamed_addr #0 {
+entry:
+  %and = and <2 x i64> %B, %C
+  %nand = xor <2 x i64> %and, <i64 -1, i64 -1>  ; Vector nand operation
+  %res = select <2 x i1> %A, <2 x i64> %nand, <2 x i64> %C
+  ret <2 x i64> %res
+}
\ No newline at end of file
diff --git a/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
new file mode 100644
index 0000000000000..0a919bc982c85
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/xxeval-vselect-x-xor.ll
@@ -0,0 +1,177 @@
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc64le-unknown-unknown \
+; RUN:   -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -mtriple=powerpc-ibm-aix-xcoff \
+; RUN:   -ppc-asm-full-reg-names --ppc-vsr-nums-as-vr < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr10 -...
[truncated]

@tonykuttai
Copy link
Contributor Author

@RolandF77 @lei137 @amy-kwan

@tonykuttai tonykuttai marked this pull request as draft May 28, 2025 04:44
@tonykuttai tonykuttai marked this pull request as ready for review May 28, 2025 05:48
@tonykuttai tonykuttai force-pushed the tvarghese/ternaryxxeval branch from 1ddd5a9 to f401061 Compare May 28, 2025 06:02
Copy link
Contributor

@lei137 lei137 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For easy future maintenance, it's best if we generate the checks via update_llc_test_checks.py

@tonykuttai
Copy link
Contributor Author

For easy future maintenance, it's best if we generate the checks via update_llc_test_checks.py

Done.

@tonykuttai tonykuttai requested a review from lei137 May 28, 2025 17:45
@lei137 lei137 requested a review from amy-kwan May 28, 2025 17:46
Copy link
Contributor

@lei137 lei137 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with nit

@tonykuttai tonykuttai force-pushed the tvarghese/ternaryxxeval branch from 685e5ad to e50b4de Compare May 29, 2025 16:23
@amy-kwan amy-kwan changed the title [NFC][PowerpC] Add testcases for locking down the xxeval instruction support for ternary operators [NFC][PowerPC] Add testcases for locking down the xxeval instruction support for ternary operators May 30, 2025
@w2yehia w2yehia merged commit 52cf598 into llvm:main Jun 3, 2025
11 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Jun 3, 2025

LLVM Buildbot has detected a new failure on builder libc-riscv32-qemu-yocto-fullbuild-dbg running on rv32gc-qemu-system while building llvm at step 4 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/196/builds/8655

Here is the relevant piece of the build log for the reference
Step 4 (annotate) failure: 'python ../llvm-zorg/zorg/buildbot/builders/annotated/libc-linux.py ...' (failure)
...
sh: line 1: /timer.21046: Permission denied
[==========] Running 3 tests from 1 test suite.
[ RUN      ] LlvmLibcSendRecvTest.SucceedsWithSocketPair
[       OK ] LlvmLibcSendRecvTest.SucceedsWithSocketPair (2 ms)
[ RUN      ] LlvmLibcSendRecvTest.SendFails
[       OK ] LlvmLibcSendRecvTest.SendFails (299 us)
[ RUN      ] LlvmLibcSendRecvTest.RecvFails
[       OK ] LlvmLibcSendRecvTest.RecvFails (68 us)
Ran 3 tests.  PASS: 3  FAIL: 0
[912/1015] Running unit test libc.test.src.sys.stat.fchmodat_test
FAILED: libc/test/src/sys/stat/CMakeFiles/libc.test.src.sys.stat.fchmodat_test /home/libcrv32buildbot/bbroot/libc-riscv32-qemu-yocto-fullbuild-dbg/build/libc/test/src/sys/stat/CMakeFiles/libc.test.src.sys.stat.fchmodat_test 
cd /home/libcrv32buildbot/bbroot/libc-riscv32-qemu-yocto-fullbuild-dbg/build/libc/test/src/sys/stat && /home/libcrv32buildbot/cross.sh libc.test.src.sys.stat.fchmodat_test.__build__
sh: line 1: /timer.21070: Permission denied
[==========] Running 2 tests from 1 test suite.
[ RUN      ] LlvmLibcFchmodatTest.ChangeAndOpen
/home/libcrv32buildbot/bbroot/libc-riscv32-qemu-yocto-fullbuild-dbg/llvm-project/libc/test/src/sys/stat/fchmodat_test.cpp:49: FAILURE
      Expected: __llvm_libc_21_0_0_git::open(TEST_FILE, 00002000 | 00000001)
      Which is: 4
To be equal to: -1
      Which is: -1
/home/libcrv32buildbot/bbroot/libc-riscv32-qemu-yocto-fullbuild-dbg/llvm-project/libc/test/src/sys/stat/fchmodat_test.cpp:50: FAILURE
          Expected: 0
          Which is: 0
To be not equal to: static_cast<int>(__llvm_libc_21_0_0_git::libc_errno)
          Which is: 0
[  FAILED  ] LlvmLibcFchmodatTest.ChangeAndOpen
[ RUN      ] LlvmLibcFchmodatTest.NonExistentFile
[       OK ] LlvmLibcFchmodatTest.NonExistentFile (449 us)
Ran 2 tests.  PASS: 1  FAIL: 1
[913/1015] Running unit test libc.test.src.sys.stat.fchmod_test
sh: line 1: /timer.21084: Permission denied
[==========] Running 2 tests from 1 test suite.
[ RUN      ] LlvmLibcFchmodTest.ChangeAndOpen
[       OK ] LlvmLibcFchmodTest.ChangeAndOpen (1 ms)
[ RUN      ] LlvmLibcFchmodTest.NonExistentFile
[       OK ] LlvmLibcFchmodTest.NonExistentFile (148 us)
Ran 2 tests.  PASS: 2  FAIL: 0
[914/1015] Running unit test libc.test.src.sys.stat.chmod_test
sh: line 1: /timer.21083: Permission denied
[==========] Running 2 tests from 1 test suite.
[ RUN      ] LlvmLibcChmodTest.ChangeAndOpen
[       OK ] LlvmLibcChmodTest.ChangeAndOpen (2 ms)
[ RUN      ] LlvmLibcChmodTest.NonExistentFile
[       OK ] LlvmLibcChmodTest.NonExistentFile (198 us)
Ran 2 tests.  PASS: 2  FAIL: 0
[915/1015] Running unit test libc.test.src.sys.stat.mkdirat_test
sh: line 1: /timer.21104: Permission denied
[==========] Running 2 tests from 1 test suite.
[ RUN      ] LlvmLibcMkdiratTest.CreateAndRemove
Step 8 (libc-unit-tests) failure: libc-unit-tests (failure)
...
sh: line 1: /timer.21046: Permission denied
[==========] Running 3 tests from 1 test suite.
[ RUN      ] LlvmLibcSendRecvTest.SucceedsWithSocketPair
[       OK ] LlvmLibcSendRecvTest.SucceedsWithSocketPair (2 ms)
[ RUN      ] LlvmLibcSendRecvTest.SendFails
[       OK ] LlvmLibcSendRecvTest.SendFails (299 us)
[ RUN      ] LlvmLibcSendRecvTest.RecvFails
[       OK ] LlvmLibcSendRecvTest.RecvFails (68 us)
Ran 3 tests.  PASS: 3  FAIL: 0
[912/1015] Running unit test libc.test.src.sys.stat.fchmodat_test
FAILED: libc/test/src/sys/stat/CMakeFiles/libc.test.src.sys.stat.fchmodat_test /home/libcrv32buildbot/bbroot/libc-riscv32-qemu-yocto-fullbuild-dbg/build/libc/test/src/sys/stat/CMakeFiles/libc.test.src.sys.stat.fchmodat_test 
cd /home/libcrv32buildbot/bbroot/libc-riscv32-qemu-yocto-fullbuild-dbg/build/libc/test/src/sys/stat && /home/libcrv32buildbot/cross.sh libc.test.src.sys.stat.fchmodat_test.__build__
sh: line 1: /timer.21070: Permission denied
[==========] Running 2 tests from 1 test suite.
[ RUN      ] LlvmLibcFchmodatTest.ChangeAndOpen
/home/libcrv32buildbot/bbroot/libc-riscv32-qemu-yocto-fullbuild-dbg/llvm-project/libc/test/src/sys/stat/fchmodat_test.cpp:49: FAILURE
      Expected: __llvm_libc_21_0_0_git::open(TEST_FILE, 00002000 | 00000001)
      Which is: 4
To be equal to: -1
      Which is: -1
/home/libcrv32buildbot/bbroot/libc-riscv32-qemu-yocto-fullbuild-dbg/llvm-project/libc/test/src/sys/stat/fchmodat_test.cpp:50: FAILURE
          Expected: 0
          Which is: 0
To be not equal to: static_cast<int>(__llvm_libc_21_0_0_git::libc_errno)
          Which is: 0
[  FAILED  ] LlvmLibcFchmodatTest.ChangeAndOpen
[ RUN      ] LlvmLibcFchmodatTest.NonExistentFile
[       OK ] LlvmLibcFchmodatTest.NonExistentFile (449 us)
Ran 2 tests.  PASS: 1  FAIL: 1
[913/1015] Running unit test libc.test.src.sys.stat.fchmod_test
sh: line 1: /timer.21084: Permission denied
[==========] Running 2 tests from 1 test suite.
[ RUN      ] LlvmLibcFchmodTest.ChangeAndOpen
[       OK ] LlvmLibcFchmodTest.ChangeAndOpen (1 ms)
[ RUN      ] LlvmLibcFchmodTest.NonExistentFile
[       OK ] LlvmLibcFchmodTest.NonExistentFile (148 us)
Ran 2 tests.  PASS: 2  FAIL: 0
[914/1015] Running unit test libc.test.src.sys.stat.chmod_test
sh: line 1: /timer.21083: Permission denied
[==========] Running 2 tests from 1 test suite.
[ RUN      ] LlvmLibcChmodTest.ChangeAndOpen
[       OK ] LlvmLibcChmodTest.ChangeAndOpen (2 ms)
[ RUN      ] LlvmLibcChmodTest.NonExistentFile
[       OK ] LlvmLibcChmodTest.NonExistentFile (198 us)
Ran 2 tests.  PASS: 2  FAIL: 0
[915/1015] Running unit test libc.test.src.sys.stat.mkdirat_test
sh: line 1: /timer.21104: Permission denied
[==========] Running 2 tests from 1 test suite.
[ RUN      ] LlvmLibcMkdiratTest.CreateAndRemove

rorth pushed a commit to rorth/llvm-project that referenced this pull request Jun 11, 2025
…support for ternary operators (llvm#141601)

NFC patch to add testcases for locking down the support of ternary
operators using the `xxsel` instructions. Currently ternary operators
are supoprted by emitting `xxsel` instructions instead of `xxeval`.

Co-authored-by: Tony Varghese <tony.varghese@ibm.com>
DhruvSrivastavaX pushed a commit to DhruvSrivastavaX/lldb-for-aix that referenced this pull request Jun 12, 2025
…support for ternary operators (llvm#141601)

NFC patch to add testcases for locking down the support of ternary
operators using the `xxsel` instructions. Currently ternary operators
are supoprted by emitting `xxsel` instructions instead of `xxeval`.

Co-authored-by: Tony Varghese <tony.varghese@ibm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants