[clang] [llvm] [PowerPC] Add AES Builtins (PR #186895)
Lei Huang via cfe-commits
cfe-commits at lists.llvm.org
Tue May 5 10:05:24 PDT 2026
https://github.com/lei137 updated https://github.com/llvm/llvm-project/pull/186895
>From 8e534f1b341e5be3244f97c1e68564b890ed6381 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Tue, 3 Mar 2026 15:45:59 -0500
Subject: [PATCH 1/3] Implement builtins for aes builtins
---
clang/include/clang/Basic/BuiltinsPPC.def | 38 +++
clang/lib/CodeGen/TargetBuiltins/PPC.cpp | 92 ++++--
.../PowerPC/builtins-aes-acceleration.c | 205 ++++++++++++++
.../PowerPC/builtins-aes-acceleration-error.c | 263 ++++++++++++++++++
llvm/include/llvm/IR/IntrinsicsPowerPC.td | 21 ++
llvm/lib/Target/PowerPC/PPCInstrFuture.td | 34 ++-
.../PowerPC/builtins-ppc-aes-acceleration.ll | 174 ++++++++++++
7 files changed, 802 insertions(+), 25 deletions(-)
create mode 100644 clang/test/CodeGen/PowerPC/builtins-aes-acceleration.c
create mode 100644 clang/test/Sema/PowerPC/builtins-aes-acceleration-error.c
create mode 100644 llvm/test/CodeGen/PowerPC/builtins-ppc-aes-acceleration.ll
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index 8c3d0179d991a..0cb48c6d4fe93 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1237,6 +1237,44 @@ TARGET_BUILTIN(__builtin_altivec_vupkint4tofp32, "V16UcV16UcIi", "",
TARGET_BUILTIN(__builtin_altivec_vupkint8tofp32, "V16UcV16UcIi", "",
"isa-future-instructions")
+// AES Encrypt Paired builtins
+UNALIASED_CUSTOM_BUILTIN(aes_encrypt_paired, "W256W256W256i2", false,
+ "future-vector,paired-vector-memops")
+CUSTOM_BUILTIN(aes128_encrypt_paired, aes_encrypt_paired, "W256W256W256", false,
+ "future-vector,paired-vector-memops")
+CUSTOM_BUILTIN(aes192_encrypt_paired, aes_encrypt_paired, "W256W256W256", false,
+ "future-vector,paired-vector-memops")
+CUSTOM_BUILTIN(aes256_encrypt_paired, aes_encrypt_paired, "W256W256W256", false,
+ "future-vector,paired-vector-memops")
+
+// AES Decrypt Paired builtins
+UNALIASED_CUSTOM_BUILTIN(aes_decrypt_paired, "W256W256W256i2", false,
+ "future-vector,paired-vector-memops")
+CUSTOM_BUILTIN(aes128_decrypt_paired, aes_decrypt_paired, "W256W256W256", false,
+ "future-vector,paired-vector-memops")
+CUSTOM_BUILTIN(aes192_decrypt_paired, aes_decrypt_paired, "W256W256W256", false,
+ "future-vector,paired-vector-memops")
+CUSTOM_BUILTIN(aes256_decrypt_paired, aes_decrypt_paired, "W256W256W256", false,
+ "future-vector,paired-vector-memops")
+
+// AES Generate Last Key Paired builtins
+UNALIASED_CUSTOM_BUILTIN(aes_genlastkey_paired, "W256W256i2", false,
+ "future-vector,paired-vector-memops")
+CUSTOM_BUILTIN(aes128_genlastkey_paired, aes_genlastkey_paired, "W256W256", false,
+ "future-vector,paired-vector-memops")
+CUSTOM_BUILTIN(aes192_genlastkey_paired, aes_genlastkey_paired, "W256W256", false,
+ "future-vector,paired-vector-memops")
+CUSTOM_BUILTIN(aes256_genlastkey_paired, aes_genlastkey_paired, "W256W256", false,
+ "future-vector,paired-vector-memops")
+
+// Galois Field Multiplication builtins
+UNALIASED_CUSTOM_BUILTIN(galois_field_mult, "VVVi1", false,
+ "future-vector")
+CUSTOM_BUILTIN(galois_field_mult_gcm, galois_field_mult, "VVV", false,
+ "future-vector")
+CUSTOM_BUILTIN(galois_field_mult_xts, galois_field_mult, "VVV", false,
+ "future-vector")
+
// FIXME: Obviously incomplete.
#undef BUILTIN
diff --git a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
index 796efb7a8ad18..f75458e13e5d1 100644
--- a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
@@ -1138,20 +1138,84 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
break;
#include "clang/Basic/BuiltinsPPC.def"
}
- if (BuiltinID == PPC::BI__builtin_vsx_lxvp ||
- BuiltinID == PPC::BI__builtin_vsx_stxvp ||
- BuiltinID == PPC::BI__builtin_mma_lxvp ||
- BuiltinID == PPC::BI__builtin_mma_stxvp) {
- if (BuiltinID == PPC::BI__builtin_vsx_lxvp ||
- BuiltinID == PPC::BI__builtin_mma_lxvp) {
- Ops[0] = Builder.CreateGEP(Int8Ty, Ops[1], Ops[0]);
- } else {
- Ops[1] = Builder.CreateGEP(Int8Ty, Ops[2], Ops[1]);
- }
+ // Handle Accumulate=false custom builtins that returns directly.
+ switch (BuiltinID) {
+ case PPC::BI__builtin_vsx_lxvp:
+ case PPC::BI__builtin_mma_lxvp:
+ Ops[0] = Builder.CreateGEP(Int8Ty, Ops[1], Ops[0]);
+ Ops.pop_back();
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+ case PPC::BI__builtin_vsx_stxvp:
+ case PPC::BI__builtin_mma_stxvp:
+ Ops[1] = Builder.CreateGEP(Int8Ty, Ops[2], Ops[1]);
Ops.pop_back();
- llvm::Function *F = CGM.getIntrinsic(ID);
- return Builder.CreateCall(F, Ops, "");
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+ case PPC::BI__builtin_disassemble_dmr:
+ Ops[1] = Builder.CreateLoad(EmitPointerWithAlignment(E->getArg(1)));
+ return Builder.CreateAlignedStore(Ops[1], Ops[0], MaybeAlign());
+
+ // Handle AES encrypt paired builtins - they return a value directly.
+ // For variant builtins, add the appropriate immediate value.
+ case PPC::BI__builtin_aes128_encrypt_paired:
+ Ops.push_back(llvm::ConstantInt::get(Int32Ty, 0));
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+ case PPC::BI__builtin_aes192_encrypt_paired:
+ Ops.push_back(llvm::ConstantInt::get(Int32Ty, 1));
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+ case PPC::BI__builtin_aes256_encrypt_paired:
+ Ops.push_back(llvm::ConstantInt::get(Int32Ty, 2));
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+ case PPC::BI__builtin_aes_encrypt_paired:
+ // For base builtin, Ops already has all 3 arguments.
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+
+ // Handle AES decrypt paired builtins - they return a value directly.
+ // For variant builtins, add the appropriate immediate value.
+ case PPC::BI__builtin_aes128_decrypt_paired:
+ Ops.push_back(llvm::ConstantInt::get(Int32Ty, 0));
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+ case PPC::BI__builtin_aes192_decrypt_paired:
+ Ops.push_back(llvm::ConstantInt::get(Int32Ty, 1));
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+ case PPC::BI__builtin_aes256_decrypt_paired:
+ Ops.push_back(llvm::ConstantInt::get(Int32Ty, 2));
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+ case PPC::BI__builtin_aes_decrypt_paired:
+ // For base builtin, Ops already has all 3 arguments.
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+
+ // Handle AES genlastkey paired builtins.
+ case PPC::BI__builtin_aes128_genlastkey_paired:
+ Ops.push_back(llvm::ConstantInt::get(Int32Ty, 0));
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+ case PPC::BI__builtin_aes192_genlastkey_paired:
+ Ops.push_back(llvm::ConstantInt::get(Int32Ty, 1));
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+ case PPC::BI__builtin_aes256_genlastkey_paired:
+ Ops.push_back(llvm::ConstantInt::get(Int32Ty, 2));
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+ case PPC::BI__builtin_aes_genlastkey_paired:
+ // For base builtin, Ops already has all 2 arguments.
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+
+ // Handle Galois Field multiplication builtins.
+ case PPC::BI__builtin_galois_field_mult_gcm:
+ Ops.push_back(llvm::ConstantInt::get(Int32Ty, 0));
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+ case PPC::BI__builtin_galois_field_mult_xts:
+ Ops.push_back(llvm::ConstantInt::get(Int32Ty, 1));
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+ case PPC::BI__builtin_galois_field_mult:
+ // For base builtin, Ops already has all 3 arguments.
+ return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
+
+ default:
+ break;
}
+
+ // Handle Accumulate = true custom builtins that need to load the existing
+ // accumulator value from the first argument (a pointer) and pass it as the
+ // first operand to the intrinsic call.
SmallVector<Value*, 4> CallOps;
if (Accumulate) {
Address Addr = EmitPointerWithAlignment(E->getArg(0));
@@ -1166,10 +1230,6 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
Ops[1] = Builder.CreateLoad(Addr);
break;
}
- case PPC::BI__builtin_disassemble_dmr: {
- Ops[1] = Builder.CreateLoad(EmitPointerWithAlignment(E->getArg(1)));
- return Builder.CreateAlignedStore(Ops[1], Ops[0], MaybeAlign());
- }
case PPC::BI__builtin_dmsha256hash:
case PPC::BI__builtin_dmsha512hash: {
Ops[1] = Builder.CreateLoad(EmitPointerWithAlignment(E->getArg(1)));
diff --git a/clang/test/CodeGen/PowerPC/builtins-aes-acceleration.c b/clang/test/CodeGen/PowerPC/builtins-aes-acceleration.c
new file mode 100644
index 0000000000000..d6e5bec7bb923
--- /dev/null
+++ b/clang/test/CodeGen/PowerPC/builtins-aes-acceleration.c
@@ -0,0 +1,205 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -O3 -triple powerpc64le-unknown-unknown -target-cpu future \
+// RUN: -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -O3 -triple powerpc64-unknown-unknown -target-cpu future \
+// RUN: -emit-llvm %s -o - | FileCheck %s
+
+// Made with AI
+
+// CHECK-LABEL: @test_aes_encrypt_paired(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6:![0-9]+]]
+// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 0)
+// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: ret void
+//
+void test_aes_encrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
+ __vector_pair vp1 = *((__vector_pair *)vpp1);
+ __vector_pair vp2 = *((__vector_pair *)vpp2);
+ __vector_pair res = __builtin_aes_encrypt_paired(vp1, vp2, 0);
+ *((__vector_pair *)resp) = res;
+}
+
+// CHECK-LABEL: @test_aes128_encrypt_paired(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 0)
+// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: ret void
+//
+void test_aes128_encrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
+ __vector_pair vp1 = *((__vector_pair *)vpp1);
+ __vector_pair vp2 = *((__vector_pair *)vpp2);
+ __vector_pair res = __builtin_aes128_encrypt_paired(vp1, vp2);
+ *((__vector_pair *)resp) = res;
+}
+
+// CHECK-LABEL: @test_aes192_encrypt_paired(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 1)
+// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: ret void
+//
+void test_aes192_encrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
+ __vector_pair vp1 = *((__vector_pair *)vpp1);
+ __vector_pair vp2 = *((__vector_pair *)vpp2);
+ __vector_pair res = __builtin_aes192_encrypt_paired(vp1, vp2);
+ *((__vector_pair *)resp) = res;
+}
+
+// CHECK-LABEL: @test_aes256_encrypt_paired(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 2)
+// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: ret void
+//
+void test_aes256_encrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
+ __vector_pair vp1 = *((__vector_pair *)vpp1);
+ __vector_pair vp2 = *((__vector_pair *)vpp2);
+ __vector_pair res = __builtin_aes256_encrypt_paired(vp1, vp2);
+ *((__vector_pair *)resp) = res;
+}
+
+// CHECK-LABEL: @test_aes_decrypt_paired(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 0)
+// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: ret void
+//
+void test_aes_decrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
+ __vector_pair vp1 = *((__vector_pair *)vpp1);
+ __vector_pair vp2 = *((__vector_pair *)vpp2);
+ __vector_pair res = __builtin_aes_decrypt_paired(vp1, vp2, 0);
+ *((__vector_pair *)resp) = res;
+}
+
+// CHECK-LABEL: @test_aes128_decrypt_paired(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 0)
+// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: ret void
+//
+void test_aes128_decrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
+ __vector_pair vp1 = *((__vector_pair *)vpp1);
+ __vector_pair vp2 = *((__vector_pair *)vpp2);
+ __vector_pair res = __builtin_aes128_decrypt_paired(vp1, vp2);
+ *((__vector_pair *)resp) = res;
+}
+
+// CHECK-LABEL: @test_aes192_decrypt_paired(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 1)
+// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: ret void
+//
+void test_aes192_decrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
+ __vector_pair vp1 = *((__vector_pair *)vpp1);
+ __vector_pair vp2 = *((__vector_pair *)vpp2);
+ __vector_pair res = __builtin_aes192_decrypt_paired(vp1, vp2);
+ *((__vector_pair *)resp) = res;
+}
+
+// CHECK-LABEL: @test_aes256_decrypt_paired(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 2)
+// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: ret void
+//
+void test_aes256_decrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
+ __vector_pair vp1 = *((__vector_pair *)vpp1);
+ __vector_pair vp2 = *((__vector_pair *)vpp2);
+ __vector_pair res = __builtin_aes256_decrypt_paired(vp1, vp2);
+ *((__vector_pair *)resp) = res;
+}
+// CHECK-LABEL: @test_aes_genlastkey_paired(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1> [[TMP0]], i32 0)
+// CHECK-NEXT: store <256 x i1> [[TMP1]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: ret void
+//
+void test_aes_genlastkey_paired(unsigned char *vpp1, unsigned char *resp) {
+ __vector_pair vp1 = *((__vector_pair *)vpp1);
+ __vector_pair res = __builtin_aes_genlastkey_paired(vp1, 0);
+ *((__vector_pair *)resp) = res;
+}
+
+// CHECK-LABEL: @test_aes128_genlastkey_paired(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1> [[TMP0]], i32 0)
+// CHECK-NEXT: store <256 x i1> [[TMP1]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: ret void
+//
+void test_aes128_genlastkey_paired(unsigned char *vpp1, unsigned char *resp) {
+ __vector_pair vp1 = *((__vector_pair *)vpp1);
+ __vector_pair res = __builtin_aes128_genlastkey_paired(vp1);
+ *((__vector_pair *)resp) = res;
+}
+
+// CHECK-LABEL: @test_aes192_genlastkey_paired(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1> [[TMP0]], i32 1)
+// CHECK-NEXT: store <256 x i1> [[TMP1]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: ret void
+//
+void test_aes192_genlastkey_paired(unsigned char *vpp1, unsigned char *resp) {
+ __vector_pair vp1 = *((__vector_pair *)vpp1);
+ __vector_pair res = __builtin_aes192_genlastkey_paired(vp1);
+ *((__vector_pair *)resp) = res;
+}
+
+// CHECK-LABEL: @test_aes256_genlastkey_paired(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1> [[TMP0]], i32 2)
+// CHECK-NEXT: store <256 x i1> [[TMP1]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
+// CHECK-NEXT: ret void
+//
+void test_aes256_genlastkey_paired(unsigned char *vpp1, unsigned char *resp) {
+ __vector_pair vp1 = *((__vector_pair *)vpp1);
+ __vector_pair res = __builtin_aes256_genlastkey_paired(vp1);
+ *((__vector_pair *)resp) = res;
+}
+
+// CHECK-LABEL: @test_galois_field_mult(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.galois.field.mult(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], i32 0)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+//
+vector unsigned char test_galois_field_mult(vector unsigned char a, vector unsigned char b) {
+ return __builtin_galois_field_mult(a, b, 0);
+}
+
+// CHECK-LABEL: @test_galois_field_mult_gcm(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.galois.field.mult(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], i32 0)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+//
+vector unsigned char test_galois_field_mult_gcm(vector unsigned char a, vector unsigned char b) {
+ return __builtin_galois_field_mult_gcm(a, b);
+}
+
+// CHECK-LABEL: @test_galois_field_mult_xts(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.galois.field.mult(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], i32 1)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+//
+vector unsigned char test_galois_field_mult_xts(vector unsigned char a, vector unsigned char b) {
+ return __builtin_galois_field_mult_xts(a, b);
+}
diff --git a/clang/test/Sema/PowerPC/builtins-aes-acceleration-error.c b/clang/test/Sema/PowerPC/builtins-aes-acceleration-error.c
new file mode 100644
index 0000000000000..0fc640c1c3146
--- /dev/null
+++ b/clang/test/Sema/PowerPC/builtins-aes-acceleration-error.c
@@ -0,0 +1,263 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu future \
+// RUN: -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-cpu future \
+// RUN: -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr11 \
+// RUN: -fsyntax-only -verify=pwr11 %s
+
+// Made with AI
+
+void test_aes_encrypt_paired_invalid_imm(void) {
+ __vector_pair vp1, vp2;
+
+ // Test invalid immediate values (valid range is 0-2)
+ // expected-error at +2 {{argument value 3 is outside the valid range}}
+ // pwr11-error at +1 {{'__builtin_aes_encrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res1 = __builtin_aes_encrypt_paired(vp1, vp2, 3);
+ // expected-error at +2 {{argument value -1 is outside the valid range}}
+ // pwr11-error at +1 {{'__builtin_aes_encrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res2 = __builtin_aes_encrypt_paired(vp1, vp2, -1);
+ // expected-error at +2 {{argument value 10 is outside the valid range}}
+ // pwr11-error at +1 {{'__builtin_aes_encrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res3 = __builtin_aes_encrypt_paired(vp1, vp2, 10);
+}
+
+void test_aes_encrypt_paired_type_mismatch(void) {
+ __vector_pair vp;
+ vector unsigned char vc;
+
+ // Test type mismatches
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes_encrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res1 = __builtin_aes_encrypt_paired(vc, vp, 0);
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes_encrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res2 = __builtin_aes_encrypt_paired(vp, vc, 0);
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type 'int'}}
+ // pwr11-error at +1 {{'__builtin_aes_encrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res3 = __builtin_aes_encrypt_paired(vp, vp, vc);
+}
+
+void test_aes128_encrypt_paired_type_mismatch(void) {
+ __vector_pair vp;
+ vector unsigned char vc;
+
+ // Test type mismatches for aes128 variant
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes128_encrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res1 = __builtin_aes128_encrypt_paired(vc, vp);
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes128_encrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res2 = __builtin_aes128_encrypt_paired(vp, vc);
+}
+
+void test_aes192_encrypt_paired_type_mismatch(void) {
+ __vector_pair vp;
+ vector unsigned char vc;
+
+ // Test type mismatches for aes192 variant
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes192_encrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res1 = __builtin_aes192_encrypt_paired(vc, vp);
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes192_encrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res2 = __builtin_aes192_encrypt_paired(vp, vc);
+}
+
+void test_aes256_encrypt_paired_type_mismatch(void) {
+ __vector_pair vp;
+ vector unsigned char vc;
+
+ // Test type mismatches for aes256 variant
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes256_encrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res1 = __builtin_aes256_encrypt_paired(vc, vp);
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes256_encrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res2 = __builtin_aes256_encrypt_paired(vp, vc);
+}
+
+void test_aes_decrypt_paired_invalid_imm(void) {
+ __vector_pair vp1, vp2;
+
+ // Test invalid immediate values (valid range is 0-2)
+ // expected-error at +2 {{argument value 3 is outside the valid range}}
+ // pwr11-error at +1 {{'__builtin_aes_decrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res1 = __builtin_aes_decrypt_paired(vp1, vp2, 3);
+ // expected-error at +2 {{argument value -1 is outside the valid range}}
+ // pwr11-error at +1 {{'__builtin_aes_decrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res2 = __builtin_aes_decrypt_paired(vp1, vp2, -1);
+ // expected-error at +2 {{argument value 10 is outside the valid range}}
+ // pwr11-error at +1 {{'__builtin_aes_decrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res3 = __builtin_aes_decrypt_paired(vp1, vp2, 10);
+}
+
+void test_aes_decrypt_paired_type_mismatch(void) {
+ __vector_pair vp;
+ vector unsigned char vc;
+
+ // Test type mismatches
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes_decrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res1 = __builtin_aes_decrypt_paired(vc, vp, 0);
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes_decrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res2 = __builtin_aes_decrypt_paired(vp, vc, 0);
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type 'int'}}
+ // pwr11-error at +1 {{'__builtin_aes_decrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res3 = __builtin_aes_decrypt_paired(vp, vp, vc);
+}
+
+void test_aes128_decrypt_paired_type_mismatch(void) {
+ __vector_pair vp;
+ vector unsigned char vc;
+
+ // Test type mismatches for aes128 variant
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes128_decrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res1 = __builtin_aes128_decrypt_paired(vc, vp);
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes128_decrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res2 = __builtin_aes128_decrypt_paired(vp, vc);
+}
+
+void test_aes192_decrypt_paired_type_mismatch(void) {
+ __vector_pair vp;
+ vector unsigned char vc;
+
+ // Test type mismatches for aes192 variant
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes192_decrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res1 = __builtin_aes192_decrypt_paired(vc, vp);
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes192_decrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res2 = __builtin_aes192_decrypt_paired(vp, vc);
+}
+
+void test_aes256_decrypt_paired_type_mismatch(void) {
+ __vector_pair vp;
+ vector unsigned char vc;
+
+ // Test type mismatches for aes256 variant
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes256_decrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res1 = __builtin_aes256_decrypt_paired(vc, vp);
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes256_decrypt_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res2 = __builtin_aes256_decrypt_paired(vp, vc);
+}
+void test_aes_genlastkey_paired_invalid_imm(void) {
+ __vector_pair vp1;
+
+ // Test invalid immediate values (valid range is 0-2)
+ // expected-error at +2 {{argument value 3 is outside the valid range}}
+ // pwr11-error at +1 {{'__builtin_aes_genlastkey_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res1 = __builtin_aes_genlastkey_paired(vp1, 3);
+ // expected-error at +2 {{argument value -1 is outside the valid range}}
+ // pwr11-error at +1 {{'__builtin_aes_genlastkey_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res2 = __builtin_aes_genlastkey_paired(vp1, -1);
+ // expected-error at +2 {{argument value 10 is outside the valid range}}
+ // pwr11-error at +1 {{'__builtin_aes_genlastkey_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res3 = __builtin_aes_genlastkey_paired(vp1, 10);
+}
+
+void test_aes_genlastkey_paired_type_mismatch(void) {
+ __vector_pair vp;
+ vector unsigned char vc;
+
+ // Test type mismatches
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes_genlastkey_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res1 = __builtin_aes_genlastkey_paired(vc, 0);
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type 'int'}}
+ // pwr11-error at +1 {{'__builtin_aes_genlastkey_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res2 = __builtin_aes_genlastkey_paired(vp, vc);
+}
+
+void test_aes128_genlastkey_paired_type_mismatch(void) {
+ __vector_pair vp;
+ vector unsigned char vc;
+
+ // Test type mismatches for aes128 variant
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes128_genlastkey_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res1 = __builtin_aes128_genlastkey_paired(vc);
+}
+
+void test_aes192_genlastkey_paired_type_mismatch(void) {
+ __vector_pair vp;
+ vector unsigned char vc;
+
+ // Test type mismatches for aes192 variant
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes192_genlastkey_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res1 = __builtin_aes192_genlastkey_paired(vc);
+}
+
+void test_aes256_genlastkey_paired_type_mismatch(void) {
+ __vector_pair vp;
+ vector unsigned char vc;
+
+ // Test type mismatches for aes256 variant
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type '__vector_pair'}}
+ // pwr11-error at +1 {{'__builtin_aes256_genlastkey_paired' needs target feature future-vector,paired-vector-memops}}
+ __vector_pair res1 = __builtin_aes256_genlastkey_paired(vc);
+}
+
+void test_galois_field_mult_invalid_imm(void) {
+ vector unsigned char a, b;
+
+ // Test invalid immediate values (valid range is 0-1)
+ // expected-error at +2 {{argument value 2 is outside the valid range}}
+ // pwr11-error at +1 {{'__builtin_galois_field_mult' needs target feature future-vector}}
+ vector unsigned char res1 = __builtin_galois_field_mult(a, b, 2);
+ // expected-error at +2 {{argument value -1 is outside the valid range}}
+ // pwr11-error at +1 {{'__builtin_galois_field_mult' needs target feature future-vector}}
+ vector unsigned char res2 = __builtin_galois_field_mult(a, b, -1);
+ // expected-error at +2 {{argument value 10 is outside the valid range}}
+ // pwr11-error at +1 {{'__builtin_galois_field_mult' needs target feature future-vector}}
+ vector unsigned char res3 = __builtin_galois_field_mult(a, b, 10);
+}
+
+void test_galois_field_mult_type_mismatch(void) {
+ vector unsigned char vc;
+ __vector_pair vp;
+
+ // Test type mismatches
+ // expected-error at +2 {{passing '__vector_pair' to parameter of incompatible type '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+ // pwr11-error at +1 {{'__builtin_galois_field_mult' needs target feature future-vector}}
+ vector unsigned char res1 = __builtin_galois_field_mult(vp, vc, 0);
+ // expected-error at +2 {{passing '__vector_pair' to parameter of incompatible type '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+ // pwr11-error at +1 {{'__builtin_galois_field_mult' needs target feature future-vector}}
+ vector unsigned char res2 = __builtin_galois_field_mult(vc, vp, 0);
+ // expected-error at +2 {{passing '__vector unsigned char' (vector of 16 'unsigned char' values) to parameter of incompatible type 'int'}}
+ // pwr11-error at +1 {{'__builtin_galois_field_mult' needs target feature future-vector}}
+ vector unsigned char res3 = __builtin_galois_field_mult(vc, vc, vc);
+}
+
+void test_galois_field_mult_gcm_type_mismatch(void) {
+ vector unsigned char vc;
+ __vector_pair vp;
+
+ // Test type mismatches for gcm variant
+ // expected-error at +2 {{passing '__vector_pair' to parameter of incompatible type '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+ // pwr11-error at +1 {{'__builtin_galois_field_mult_gcm' needs target feature future-vector}}
+ vector unsigned char res1 = __builtin_galois_field_mult_gcm(vp, vc);
+ // expected-error at +2 {{passing '__vector_pair' to parameter of incompatible type '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+ // pwr11-error at +1 {{'__builtin_galois_field_mult_gcm' needs target feature future-vector}}
+ vector unsigned char res2 = __builtin_galois_field_mult_gcm(vc, vp);
+}
+
+void test_galois_field_mult_xts_type_mismatch(void) {
+ vector unsigned char vc;
+ __vector_pair vp;
+
+ // Test type mismatches for xts variant
+ // expected-error at +2 {{passing '__vector_pair' to parameter of incompatible type '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+ // pwr11-error at +1 {{'__builtin_galois_field_mult_xts' needs target feature future-vector}}
+ vector unsigned char res1 = __builtin_galois_field_mult_xts(vp, vc);
+ // expected-error at +2 {{passing '__vector_pair' to parameter of incompatible type '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+ // pwr11-error at +1 {{'__builtin_galois_field_mult_xts' needs target feature future-vector}}
+ vector unsigned char res2 = __builtin_galois_field_mult_xts(vc, vp);
+}
diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index 392c47ee7e456..b955a9f081094 100644
--- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -1755,6 +1755,27 @@ let TargetPrefix = "ppc" in {
DefaultAttrsIntrinsic<[llvm_v16i8_ty, llvm_v16i8_ty],
[llvm_v256i1_ty], [IntrNoMem]>;
+ // AES Encrypt Paired Instructions.
+ def int_ppc_aes_encrypt_paired :
+ DefaultAttrsIntrinsic<[llvm_v256i1_ty],
+ [llvm_v256i1_ty, llvm_v256i1_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+ // AES Decrypt Paired Instructions.
+ def int_ppc_aes_decrypt_paired :
+ DefaultAttrsIntrinsic<[llvm_v256i1_ty],
+ [llvm_v256i1_ty, llvm_v256i1_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+ // AES Generate Last Key Paired Instructions.
+ def int_ppc_aes_genlastkey_paired :
+ DefaultAttrsIntrinsic<[llvm_v256i1_ty],
+ [llvm_v256i1_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+ // Galois Field Multiplication Instructions.
+ def int_ppc_galois_field_mult :
+ DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
def int_ppc_mma_assemble_acc :
DefaultAttrsIntrinsic<[llvm_v512i1_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty,
diff --git a/llvm/lib/Target/PowerPC/PPCInstrFuture.td b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
index c1f95de578dbe..2ddc25a938c8a 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrFuture.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
@@ -492,17 +492,30 @@ let Predicates = [HasFutureVector] in {
"xvrlw $XT, $XA, $XB",
[(set v4i32:$XT, (int_ppc_vsx_xvrlw v4i32:$XA,
v4i32:$XB))]>;
+}
// AES Acceleration Instructions
- def XXAESENCP : XX3Form_XTABp5_M2<194, (outs vsrprc:$XTp),
- (ins vsrprc:$XAp, vsrprc:$XBp, u2imm:$M),
- "xxaesencp $XTp, $XAp, $XBp, $M", []>;
- def XXAESDECP : XX3Form_XTABp5_M2<202, (outs vsrprc:$XTp),
- (ins vsrprc:$XAp, vsrprc:$XBp, u2imm:$M),
- "xxaesdecp $XTp, $XAp, $XBp, $M", []>;
- def XXAESGENLKP : XX3Form_XTBp5_M2<420, (outs vsrprc:$XTp),
- (ins vsrprc:$XBp, u2imm:$M),
- "xxaesgenlkp $XTp, $XBp, $M", []>;
+let Predicates = [HasFutureVector, PairedVectorMemops] in {
+ def XXAESENCP
+ : XX3Form_XTABp5_M2<194, (outs vsrprc:$XTp),
+ (ins vsrprc:$XAp, vsrprc:$XBp, u2imm:$M),
+ "xxaesencp $XTp, $XAp, $XBp, $M",
+ [(set v256i1:$XTp,
+ (int_ppc_aes_encrypt_paired v256i1:$XAp, v256i1:$XBp, u2imm_timm:$M))]>;
+ def XXAESDECP
+ : XX3Form_XTABp5_M2<202, (outs vsrprc:$XTp),
+ (ins vsrprc:$XAp, vsrprc:$XBp, u2imm:$M),
+ "xxaesdecp $XTp, $XAp, $XBp, $M",
+ [(set v256i1:$XTp,
+ (int_ppc_aes_decrypt_paired v256i1:$XAp, v256i1:$XBp, u2imm_timm:$M))]>;
+ def XXAESGENLKP
+ : XX3Form_XTBp5_M2<420, (outs vsrprc:$XTp), (ins vsrprc:$XBp, u2imm:$M),
+ "xxaesgenlkp $XTp, $XBp, $M",
+ [(set v256i1:$XTp,
+ (int_ppc_aes_genlastkey_paired v256i1:$XBp, u2imm_timm:$M))]>;
+}
+
+let Predicates = [HasFutureVector] in {
def XXGFMUL128 : XX3Form_XTAB6_P1<26, (outs vsrc:$XT),
(ins vsrc:$XA, vsrc:$XB, u1imm:$P),
"xxgfmul128 $XT, $XA, $XB, $P", []>;
@@ -621,6 +634,9 @@ def : Pat<(int_ppc_vsx_stxvprl v256i1:$XTp, addr:$RA, i64:$RB), (STXVPRL $XTp,
def : Pat<(int_ppc_vsx_stxvprll v256i1:$XTp, addr:$RA, i64:$RB), (STXVPRLL $XTp,
$RA, $RB)>;
+def: Pat<(v16i8 (int_ppc_galois_field_mult v16i8:$XA, v16i8:$XB, u1imm_timm:$IMM)),
+ (COPY_TO_REGCLASS (XXGFMUL128 RCCp.AToVSRC, RCCp.BToVSRC, $IMM), VSRC)>;
+
// Regular load/store patterns for v256i1 (for ISA Future)
let Predicates = [HasFutureVector, PairedVectorMemops] in {
def : Pat<(v256i1 (load iaddrX16:$src)), (LXVP iaddrX16:$src)>;
diff --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-aes-acceleration.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-aes-acceleration.ll
new file mode 100644
index 0000000000000..18864bb5592fc
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-aes-acceleration.ll
@@ -0,0 +1,174 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
+; RUN: -mcpu=future -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr \
+; RUN: < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
+; RUN: -mcpu=future -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr \
+; RUN: < %s | FileCheck %s
+
+; Generated by AI.
+
+declare <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1>, i32)
+declare <16 x i8> @llvm.ppc.galois.field.mult(<16 x i8>, <16 x i8>, i32)
+declare <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1>, <256 x i1>, i32)
+declare <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1>, <256 x i1>, i32)
+
+define void @test_aes_encrypt_paired_imm0(ptr %ptr, ptr %vpp1, ptr %vpp2) {
+; CHECK-LABEL: test_aes_encrypt_paired_imm0:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lxvp vsp34, 0(r4)
+; CHECK-NEXT: lxvp vsp36, 0(r5)
+; CHECK-NEXT: xxaes128encp vsp34, vsp34, vsp36
+; CHECK-NEXT: stxvp vsp34, 0(r3)
+; CHECK-NEXT: blr
+entry:
+ %vp1 = load <256 x i1>, ptr %vpp1, align 32
+ %vp2 = load <256 x i1>, ptr %vpp2, align 32
+ %0 = tail call <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1> %vp1, <256 x i1> %vp2, i32 0)
+ store <256 x i1> %0, ptr %ptr, align 32
+ ret void
+}
+
+define void @test_aes_encrypt_paired_imm1(ptr %ptr, ptr %vpp1, ptr %vpp2) {
+; CHECK-LABEL: test_aes_encrypt_paired_imm1:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lxvp vsp34, 0(r4)
+; CHECK-NEXT: lxvp vsp36, 0(r5)
+; CHECK-NEXT: xxaes192encp vsp34, vsp34, vsp36
+; CHECK-NEXT: stxvp vsp34, 0(r3)
+; CHECK-NEXT: blr
+entry:
+ %vp1 = load <256 x i1>, ptr %vpp1, align 32
+ %vp2 = load <256 x i1>, ptr %vpp2, align 32
+ %0 = tail call <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1> %vp1, <256 x i1> %vp2, i32 1)
+ store <256 x i1> %0, ptr %ptr, align 32
+ ret void
+}
+
+define void @test_aes_encrypt_paired_imm2(ptr %ptr, ptr %vpp1, ptr %vpp2) {
+; CHECK-LABEL: test_aes_encrypt_paired_imm2:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lxvp vsp34, 0(r4)
+; CHECK-NEXT: lxvp vsp36, 0(r5)
+; CHECK-NEXT: xxaes256encp vsp34, vsp34, vsp36
+; CHECK-NEXT: stxvp vsp34, 0(r3)
+; CHECK-NEXT: blr
+entry:
+ %vp1 = load <256 x i1>, ptr %vpp1, align 32
+ %vp2 = load <256 x i1>, ptr %vpp2, align 32
+ %0 = tail call <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1> %vp1, <256 x i1> %vp2, i32 2)
+ store <256 x i1> %0, ptr %ptr, align 32
+ ret void
+}
+
+
+define void @test_aes_decrypt_paired_imm0(ptr %ptr, ptr %vpp1, ptr %vpp2) {
+; CHECK-LABEL: test_aes_decrypt_paired_imm0:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lxvp vsp34, 0(r4)
+; CHECK-NEXT: lxvp vsp36, 0(r5)
+; CHECK-NEXT: xxaes128decp vsp34, vsp34, vsp36
+; CHECK-NEXT: stxvp vsp34, 0(r3)
+; CHECK-NEXT: blr
+entry:
+ %vp1 = load <256 x i1>, ptr %vpp1, align 32
+ %vp2 = load <256 x i1>, ptr %vpp2, align 32
+ %0 = tail call <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1> %vp1, <256 x i1> %vp2, i32 0)
+ store <256 x i1> %0, ptr %ptr, align 32
+ ret void
+}
+
+define void @test_aes_decrypt_paired_imm1(ptr %ptr, ptr %vpp1, ptr %vpp2) {
+; CHECK-LABEL: test_aes_decrypt_paired_imm1:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lxvp vsp34, 0(r4)
+; CHECK-NEXT: lxvp vsp36, 0(r5)
+; CHECK-NEXT: xxaes192decp vsp34, vsp34, vsp36
+; CHECK-NEXT: stxvp vsp34, 0(r3)
+; CHECK-NEXT: blr
+entry:
+ %vp1 = load <256 x i1>, ptr %vpp1, align 32
+ %vp2 = load <256 x i1>, ptr %vpp2, align 32
+ %0 = tail call <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1> %vp1, <256 x i1> %vp2, i32 1)
+ store <256 x i1> %0, ptr %ptr, align 32
+ ret void
+}
+
+define void @test_aes_decrypt_paired_imm2(ptr %ptr, ptr %vpp1, ptr %vpp2) {
+; CHECK-LABEL: test_aes_decrypt_paired_imm2:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lxvp vsp34, 0(r4)
+; CHECK-NEXT: lxvp vsp36, 0(r5)
+; CHECK-NEXT: xxaes256decp vsp34, vsp34, vsp36
+; CHECK-NEXT: stxvp vsp34, 0(r3)
+; CHECK-NEXT: blr
+entry:
+ %vp1 = load <256 x i1>, ptr %vpp1, align 32
+ %vp2 = load <256 x i1>, ptr %vpp2, align 32
+ %0 = tail call <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1> %vp1, <256 x i1> %vp2, i32 2)
+ store <256 x i1> %0, ptr %ptr, align 32
+ ret void
+}
+
+
+define void @test_aes_genlastkey_paired_imm0(ptr %ptr, ptr %vpp1) {
+; CHECK-LABEL: test_aes_genlastkey_paired_imm0:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lxvp vsp34, 0(r4)
+; CHECK-NEXT: xxaes128genlkp vsp34, vsp34
+; CHECK-NEXT: stxvp vsp34, 0(r3)
+; CHECK-NEXT: blr
+entry:
+ %vp1 = load <256 x i1>, ptr %vpp1, align 32
+ %0 = tail call <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1> %vp1, i32 0)
+ store <256 x i1> %0, ptr %ptr, align 32
+ ret void
+}
+
+define void @test_aes_genlastkey_paired_imm1(ptr %ptr, ptr %vpp1) {
+; CHECK-LABEL: test_aes_genlastkey_paired_imm1:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lxvp vsp34, 0(r4)
+; CHECK-NEXT: xxaes192genlkp vsp34, vsp34
+; CHECK-NEXT: stxvp vsp34, 0(r3)
+; CHECK-NEXT: blr
+entry:
+ %vp1 = load <256 x i1>, ptr %vpp1, align 32
+ %0 = tail call <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1> %vp1, i32 1)
+ store <256 x i1> %0, ptr %ptr, align 32
+ ret void
+}
+
+define void @test_aes_genlastkey_paired_imm2(ptr %ptr, ptr %vpp1) {
+; CHECK-LABEL: test_aes_genlastkey_paired_imm2:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lxvp vsp34, 0(r4)
+; CHECK-NEXT: xxaes256genlkp vsp34, vsp34
+; CHECK-NEXT: stxvp vsp34, 0(r3)
+; CHECK-NEXT: blr
+entry:
+ %vp1 = load <256 x i1>, ptr %vpp1, align 32
+ %0 = tail call <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1> %vp1, i32 2)
+ store <256 x i1> %0, ptr %ptr, align 32
+ ret void
+}
+
+define <16 x i8> @test_galois_field_mult_imm0(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_galois_field_mult_imm0:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxgfmul128gcm v2, v2, v3
+; CHECK-NEXT: blr
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.galois.field.mult(<16 x i8> %a, <16 x i8> %b, i32 0)
+ ret <16 x i8> %0
+}
+
+define <16 x i8> @test_galois_field_mult_imm1(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_galois_field_mult_imm1:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xxgfmul128xts v2, v2, v3
+; CHECK-NEXT: blr
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.galois.field.mult(<16 x i8> %a, <16 x i8> %b, i32 1)
+ ret <16 x i8> %0
+}
>From ce12bbdeba8f5464a42239e2fb09af965055dc95 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Tue, 28 Apr 2026 09:43:31 -0400
Subject: [PATCH 2/3] address Digger's comments
---
.../PowerPC/builtins-aes-acceleration.c | 218 +++++++-----------
.../PowerPC/builtins-aes-acceleration-error.c | 12 -
2 files changed, 77 insertions(+), 153 deletions(-)
diff --git a/clang/test/CodeGen/PowerPC/builtins-aes-acceleration.c b/clang/test/CodeGen/PowerPC/builtins-aes-acceleration.c
index d6e5bec7bb923..506c2e10b6891 100644
--- a/clang/test/CodeGen/PowerPC/builtins-aes-acceleration.c
+++ b/clang/test/CodeGen/PowerPC/builtins-aes-acceleration.c
@@ -1,205 +1,141 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
-// RUN: %clang_cc1 -O3 -triple powerpc64le-unknown-unknown -target-cpu future \
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu future \
// RUN: -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -O3 -triple powerpc64-unknown-unknown -target-cpu future \
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-cpu future \
// RUN: -emit-llvm %s -o - | FileCheck %s
-// Made with AI
-
// CHECK-LABEL: @test_aes_encrypt_paired(
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6:![0-9]+]]
-// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 0)
-// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: ret void
-//
-void test_aes_encrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
- __vector_pair vp1 = *((__vector_pair *)vpp1);
- __vector_pair vp2 = *((__vector_pair *)vpp2);
+// CHECK: {{.*}}call <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1> {{.*}}, <256 x i1> {{.*}}, i32 0)
+// CHECK: ret void
+void test_aes_encrypt_paired(__vector_pair *vpp1, __vector_pair *vpp2, __vector_pair *resp) {
+ __vector_pair vp1 = *vpp1;
+ __vector_pair vp2 = *vpp2;
__vector_pair res = __builtin_aes_encrypt_paired(vp1, vp2, 0);
- *((__vector_pair *)resp) = res;
+ *resp = res;
}
// CHECK-LABEL: @test_aes128_encrypt_paired(
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 0)
-// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: ret void
-//
-void test_aes128_encrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
- __vector_pair vp1 = *((__vector_pair *)vpp1);
- __vector_pair vp2 = *((__vector_pair *)vpp2);
+// CHECK: {{.*}}call <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1> {{.*}}, <256 x i1> {{.*}}, i32 0)
+// CHECK: ret void
+void test_aes128_encrypt_paired(__vector_pair *vpp1, __vector_pair *vpp2, __vector_pair *resp) {
+ __vector_pair vp1 = *vpp1;
+ __vector_pair vp2 = *vpp2;
__vector_pair res = __builtin_aes128_encrypt_paired(vp1, vp2);
- *((__vector_pair *)resp) = res;
+ *resp = res;
}
// CHECK-LABEL: @test_aes192_encrypt_paired(
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 1)
-// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: ret void
-//
-void test_aes192_encrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
- __vector_pair vp1 = *((__vector_pair *)vpp1);
- __vector_pair vp2 = *((__vector_pair *)vpp2);
+// CHECK: {{.*}}call <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1> {{.*}}, <256 x i1> {{.*}}, i32 1)
+// CHECK: ret void
+void test_aes192_encrypt_paired(__vector_pair *vpp1, __vector_pair *vpp2, __vector_pair *resp) {
+ __vector_pair vp1 = *vpp1;
+ __vector_pair vp2 = *vpp2;
__vector_pair res = __builtin_aes192_encrypt_paired(vp1, vp2);
- *((__vector_pair *)resp) = res;
+ *resp = res;
}
// CHECK-LABEL: @test_aes256_encrypt_paired(
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 2)
-// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: ret void
-//
-void test_aes256_encrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
- __vector_pair vp1 = *((__vector_pair *)vpp1);
- __vector_pair vp2 = *((__vector_pair *)vpp2);
+// CHECK: {{.*}}call <256 x i1> @llvm.ppc.aes.encrypt.paired(<256 x i1> {{.*}}, <256 x i1> {{.*}}, i32 2)
+// CHECK: ret void
+void test_aes256_encrypt_paired(__vector_pair *vpp1, __vector_pair *vpp2, __vector_pair *resp) {
+ __vector_pair vp1 = *vpp1;
+ __vector_pair vp2 = *vpp2;
__vector_pair res = __builtin_aes256_encrypt_paired(vp1, vp2);
- *((__vector_pair *)resp) = res;
+ *resp = res;
}
// CHECK-LABEL: @test_aes_decrypt_paired(
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 0)
-// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: ret void
-//
-void test_aes_decrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
- __vector_pair vp1 = *((__vector_pair *)vpp1);
- __vector_pair vp2 = *((__vector_pair *)vpp2);
+// CHECK: {{.*}}call <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1> {{.*}}, <256 x i1> {{.*}}, i32 0)
+// CHECK: ret void
+void test_aes_decrypt_paired(__vector_pair *vpp1, __vector_pair *vpp2, __vector_pair *resp) {
+ __vector_pair vp1 = *vpp1;
+ __vector_pair vp2 = *vpp2;
__vector_pair res = __builtin_aes_decrypt_paired(vp1, vp2, 0);
- *((__vector_pair *)resp) = res;
+ *resp = res;
}
// CHECK-LABEL: @test_aes128_decrypt_paired(
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 0)
-// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: ret void
-//
-void test_aes128_decrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
- __vector_pair vp1 = *((__vector_pair *)vpp1);
- __vector_pair vp2 = *((__vector_pair *)vpp2);
+// CHECK: {{.*}}call <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1> {{.*}}, <256 x i1> {{.*}}, i32 0)
+// CHECK: ret void
+void test_aes128_decrypt_paired(__vector_pair *vpp1, __vector_pair *vpp2, __vector_pair *resp) {
+ __vector_pair vp1 = *vpp1;
+ __vector_pair vp2 = *vpp2;
__vector_pair res = __builtin_aes128_decrypt_paired(vp1, vp2);
- *((__vector_pair *)resp) = res;
+ *resp = res;
}
// CHECK-LABEL: @test_aes192_decrypt_paired(
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 1)
-// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: ret void
-//
-void test_aes192_decrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
- __vector_pair vp1 = *((__vector_pair *)vpp1);
- __vector_pair vp2 = *((__vector_pair *)vpp2);
+// CHECK: {{.*}}call <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1> {{.*}}, <256 x i1> {{.*}}, i32 1)
+// CHECK: ret void
+void test_aes192_decrypt_paired(__vector_pair *vpp1, __vector_pair *vpp2, __vector_pair *resp) {
+ __vector_pair vp1 = *vpp1;
+ __vector_pair vp2 = *vpp2;
__vector_pair res = __builtin_aes192_decrypt_paired(vp1, vp2);
- *((__vector_pair *)resp) = res;
+ *resp = res;
}
// CHECK-LABEL: @test_aes256_decrypt_paired(
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP2:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP2:%.*]] = tail call <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1> [[TMP0]], <256 x i1> [[TMP1]], i32 2)
-// CHECK-NEXT: store <256 x i1> [[TMP2]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: ret void
-//
-void test_aes256_decrypt_paired(unsigned char *vpp1, unsigned char *vpp2, unsigned char *resp) {
- __vector_pair vp1 = *((__vector_pair *)vpp1);
- __vector_pair vp2 = *((__vector_pair *)vpp2);
+// CHECK: {{.*}}call <256 x i1> @llvm.ppc.aes.decrypt.paired(<256 x i1> {{.*}}, <256 x i1> {{.*}}, i32 2)
+// CHECK: ret void
+void test_aes256_decrypt_paired(__vector_pair *vpp1, __vector_pair *vpp2, __vector_pair *resp) {
+ __vector_pair vp1 = *vpp1;
+ __vector_pair vp2 = *vpp2;
__vector_pair res = __builtin_aes256_decrypt_paired(vp1, vp2);
- *((__vector_pair *)resp) = res;
+ *resp = res;
}
// CHECK-LABEL: @test_aes_genlastkey_paired(
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP1:%.*]] = tail call <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1> [[TMP0]], i32 0)
-// CHECK-NEXT: store <256 x i1> [[TMP1]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: ret void
-//
-void test_aes_genlastkey_paired(unsigned char *vpp1, unsigned char *resp) {
- __vector_pair vp1 = *((__vector_pair *)vpp1);
+// CHECK: {{.*}}call <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1> {{.*}}, i32 0)
+// CHECK: ret void
+void test_aes_genlastkey_paired(__vector_pair *vpp1, __vector_pair *resp) {
+ __vector_pair vp1 = *vpp1;
__vector_pair res = __builtin_aes_genlastkey_paired(vp1, 0);
- *((__vector_pair *)resp) = res;
+ *resp = res;
}
// CHECK-LABEL: @test_aes128_genlastkey_paired(
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP1:%.*]] = tail call <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1> [[TMP0]], i32 0)
-// CHECK-NEXT: store <256 x i1> [[TMP1]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: ret void
-//
-void test_aes128_genlastkey_paired(unsigned char *vpp1, unsigned char *resp) {
- __vector_pair vp1 = *((__vector_pair *)vpp1);
+// CHECK: {{.*}}call <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1> {{.*}}, i32 0)
+// CHECK: ret void
+void test_aes128_genlastkey_paired(__vector_pair *vpp1, __vector_pair *resp) {
+ __vector_pair vp1 = *vpp1;
__vector_pair res = __builtin_aes128_genlastkey_paired(vp1);
- *((__vector_pair *)resp) = res;
+ *resp = res;
}
// CHECK-LABEL: @test_aes192_genlastkey_paired(
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP1:%.*]] = tail call <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1> [[TMP0]], i32 1)
-// CHECK-NEXT: store <256 x i1> [[TMP1]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: ret void
-//
-void test_aes192_genlastkey_paired(unsigned char *vpp1, unsigned char *resp) {
- __vector_pair vp1 = *((__vector_pair *)vpp1);
+// CHECK: {{.*}}call <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1> {{.*}}, i32 1)
+// CHECK: ret void
+void test_aes192_genlastkey_paired(__vector_pair *vpp1, __vector_pair *resp) {
+ __vector_pair vp1 = *vpp1;
__vector_pair res = __builtin_aes192_genlastkey_paired(vp1);
- *((__vector_pair *)resp) = res;
+ *resp = res;
}
// CHECK-LABEL: @test_aes256_genlastkey_paired(
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP1:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: [[TMP1:%.*]] = tail call <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1> [[TMP0]], i32 2)
-// CHECK-NEXT: store <256 x i1> [[TMP1]], ptr [[RESP:%.*]], align 32, !tbaa [[TBAA6]]
-// CHECK-NEXT: ret void
-//
-void test_aes256_genlastkey_paired(unsigned char *vpp1, unsigned char *resp) {
- __vector_pair vp1 = *((__vector_pair *)vpp1);
+// CHECK: {{.*}}call <256 x i1> @llvm.ppc.aes.genlastkey.paired(<256 x i1> {{.*}}, i32 2)
+// CHECK: ret void
+void test_aes256_genlastkey_paired(__vector_pair *vpp1, __vector_pair *resp) {
+ __vector_pair vp1 = *vpp1;
__vector_pair res = __builtin_aes256_genlastkey_paired(vp1);
- *((__vector_pair *)resp) = res;
+ *resp = res;
}
// CHECK-LABEL: @test_galois_field_mult(
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.galois.field.mult(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], i32 0)
-// CHECK-NEXT: ret <16 x i8> [[TMP0]]
-//
+// CHECK: {{.*}}call <16 x i8> @llvm.ppc.galois.field.mult(<16 x i8> {{.*}}, <16 x i8> {{.*}}, i32 0)
+// CHECK: ret <16 x i8>
vector unsigned char test_galois_field_mult(vector unsigned char a, vector unsigned char b) {
return __builtin_galois_field_mult(a, b, 0);
}
// CHECK-LABEL: @test_galois_field_mult_gcm(
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.galois.field.mult(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], i32 0)
-// CHECK-NEXT: ret <16 x i8> [[TMP0]]
-//
+// CHECK: {{.*}}call <16 x i8> @llvm.ppc.galois.field.mult(<16 x i8> {{.*}}, <16 x i8> {{.*}}, i32 0)
+// CHECK: ret <16 x i8>
vector unsigned char test_galois_field_mult_gcm(vector unsigned char a, vector unsigned char b) {
return __builtin_galois_field_mult_gcm(a, b);
}
// CHECK-LABEL: @test_galois_field_mult_xts(
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.galois.field.mult(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], i32 1)
-// CHECK-NEXT: ret <16 x i8> [[TMP0]]
-//
+// CHECK: {{.*}}call <16 x i8> @llvm.ppc.galois.field.mult(<16 x i8> {{.*}}, <16 x i8> {{.*}}, i32 1)
+// CHECK: ret <16 x i8>
vector unsigned char test_galois_field_mult_xts(vector unsigned char a, vector unsigned char b) {
return __builtin_galois_field_mult_xts(a, b);
}
diff --git a/clang/test/Sema/PowerPC/builtins-aes-acceleration-error.c b/clang/test/Sema/PowerPC/builtins-aes-acceleration-error.c
index 0fc640c1c3146..5528ab4ebab95 100644
--- a/clang/test/Sema/PowerPC/builtins-aes-acceleration-error.c
+++ b/clang/test/Sema/PowerPC/builtins-aes-acceleration-error.c
@@ -18,9 +18,6 @@ void test_aes_encrypt_paired_invalid_imm(void) {
// expected-error at +2 {{argument value -1 is outside the valid range}}
// pwr11-error at +1 {{'__builtin_aes_encrypt_paired' needs target feature future-vector,paired-vector-memops}}
__vector_pair res2 = __builtin_aes_encrypt_paired(vp1, vp2, -1);
- // expected-error at +2 {{argument value 10 is outside the valid range}}
- // pwr11-error at +1 {{'__builtin_aes_encrypt_paired' needs target feature future-vector,paired-vector-memops}}
- __vector_pair res3 = __builtin_aes_encrypt_paired(vp1, vp2, 10);
}
void test_aes_encrypt_paired_type_mismatch(void) {
@@ -88,9 +85,6 @@ void test_aes_decrypt_paired_invalid_imm(void) {
// expected-error at +2 {{argument value -1 is outside the valid range}}
// pwr11-error at +1 {{'__builtin_aes_decrypt_paired' needs target feature future-vector,paired-vector-memops}}
__vector_pair res2 = __builtin_aes_decrypt_paired(vp1, vp2, -1);
- // expected-error at +2 {{argument value 10 is outside the valid range}}
- // pwr11-error at +1 {{'__builtin_aes_decrypt_paired' needs target feature future-vector,paired-vector-memops}}
- __vector_pair res3 = __builtin_aes_decrypt_paired(vp1, vp2, 10);
}
void test_aes_decrypt_paired_type_mismatch(void) {
@@ -157,9 +151,6 @@ void test_aes_genlastkey_paired_invalid_imm(void) {
// expected-error at +2 {{argument value -1 is outside the valid range}}
// pwr11-error at +1 {{'__builtin_aes_genlastkey_paired' needs target feature future-vector,paired-vector-memops}}
__vector_pair res2 = __builtin_aes_genlastkey_paired(vp1, -1);
- // expected-error at +2 {{argument value 10 is outside the valid range}}
- // pwr11-error at +1 {{'__builtin_aes_genlastkey_paired' needs target feature future-vector,paired-vector-memops}}
- __vector_pair res3 = __builtin_aes_genlastkey_paired(vp1, 10);
}
void test_aes_genlastkey_paired_type_mismatch(void) {
@@ -215,9 +206,6 @@ void test_galois_field_mult_invalid_imm(void) {
// expected-error at +2 {{argument value -1 is outside the valid range}}
// pwr11-error at +1 {{'__builtin_galois_field_mult' needs target feature future-vector}}
vector unsigned char res2 = __builtin_galois_field_mult(a, b, -1);
- // expected-error at +2 {{argument value 10 is outside the valid range}}
- // pwr11-error at +1 {{'__builtin_galois_field_mult' needs target feature future-vector}}
- vector unsigned char res3 = __builtin_galois_field_mult(a, b, 10);
}
void test_galois_field_mult_type_mismatch(void) {
>From dde61cb5de057ba9607439b2623500f06accfe7b Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Tue, 5 May 2026 13:02:16 -0400
Subject: [PATCH 3/3] add doc to explain the diff sections of custom code
handling.
---
clang/lib/CodeGen/TargetBuiltins/PPC.cpp | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
index f75458e13e5d1..ee932eb8bb366 100644
--- a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
@@ -1138,7 +1138,8 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
break;
#include "clang/Basic/BuiltinsPPC.def"
}
- // Handle Accumulate=false custom builtins that returns directly.
+ // Handle custom builtins that return early without using the common
+ // store-back pattern.
switch (BuiltinID) {
case PPC::BI__builtin_vsx_lxvp:
case PPC::BI__builtin_mma_lxvp:
@@ -1213,15 +1214,25 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
break;
}
- // Handle Accumulate = true custom builtins that need to load the existing
- // accumulator value from the first argument (a pointer) and pass it as the
- // first operand to the intrinsic call.
SmallVector<Value*, 4> CallOps;
+
+ // Accumulate = true, are used for builtins where the hardware instruction
+ // reads the old destination value, performs an operation with it, and
+ // writes the result back.
+ // Load the existing value from the first argument (destination pointer) and
+ // add it to CallOps as the first intrinsic operand.
if (Accumulate) {
Address Addr = EmitPointerWithAlignment(E->getArg(0));
Value *Acc = Builder.CreateLoad(Addr);
CallOps.push_back(Acc);
}
+
+ // Handles builtins that need special argument handling such as:
+ // - Dereferencing pointer arguments to load actual register values.
+ // - Adding implicit operands required by the intrinsic.
+ // - Transforming or reordering operands.
+ // After preprocessing, the loop at end copies Ops[1..n] into CallOps,
+ // skipping Ops[0] which is the destination pointer for result storage.
switch (BuiltinID) {
case PPC::BI__builtin_dmmr:
case PPC::BI__builtin_dmxor:
More information about the cfe-commits
mailing list