[clang] [llvm] [PowerPC] Add AES Builtins (PR #186895)

Lei Huang via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 17 10:14:08 PDT 2026


https://github.com/lei137 updated https://github.com/llvm/llvm-project/pull/186895

>From 187e6d78db92eb70ced6a45a7030e2ea9c315626 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/2] Implement builtins for aes builtins

---
 clang/include/clang/Basic/BuiltinsPPC.def     |  38 +++
 clang/lib/CodeGen/TargetBuiltins/PPC.cpp      |  57 ++++
 .../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, 783 insertions(+), 9 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 187e2fdd3d985..fddc3e06a6c86 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1213,6 +1213,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 721071308c251..356765f540910 100644
--- a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
@@ -1154,6 +1154,63 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
       llvm::Function *F = CGM.getIntrinsic(ID);
       return Builder.CreateCall(F, Ops, "");
     }
+    // Handle AES encrypt paired builtins - they return a value directly.
+    // For variant builtins, add the appropriate immediate value.
+    if (BuiltinID == PPC::BI__builtin_aes_encrypt_paired ||
+        BuiltinID == PPC::BI__builtin_aes128_encrypt_paired ||
+        BuiltinID == PPC::BI__builtin_aes192_encrypt_paired ||
+        BuiltinID == PPC::BI__builtin_aes256_encrypt_paired) {
+      if (BuiltinID == PPC::BI__builtin_aes128_encrypt_paired)
+        Ops.push_back(llvm::ConstantInt::get(Int32Ty, 0));
+      else if (BuiltinID == PPC::BI__builtin_aes192_encrypt_paired)
+        Ops.push_back(llvm::ConstantInt::get(Int32Ty, 1));
+      else if (BuiltinID == PPC::BI__builtin_aes256_encrypt_paired)
+        Ops.push_back(llvm::ConstantInt::get(Int32Ty, 2));
+      // For base builtin, Ops already has all 3 arguments.
+      llvm::Function *F = CGM.getIntrinsic(ID);
+      return Builder.CreateCall(F, Ops, "");
+    }
+    // Handle AES decrypt paired builtins - they return a value directly.
+    // For variant builtins, add the appropriate immediate value.
+    if (BuiltinID == PPC::BI__builtin_aes_decrypt_paired ||
+        BuiltinID == PPC::BI__builtin_aes128_decrypt_paired ||
+        BuiltinID == PPC::BI__builtin_aes192_decrypt_paired ||
+        BuiltinID == PPC::BI__builtin_aes256_decrypt_paired) {
+      if (BuiltinID == PPC::BI__builtin_aes128_decrypt_paired)
+        Ops.push_back(llvm::ConstantInt::get(Int32Ty, 0));
+      else if (BuiltinID == PPC::BI__builtin_aes192_decrypt_paired)
+        Ops.push_back(llvm::ConstantInt::get(Int32Ty, 1));
+      else if (BuiltinID == PPC::BI__builtin_aes256_decrypt_paired)
+        Ops.push_back(llvm::ConstantInt::get(Int32Ty, 2));
+      // For base builtin, Ops already has all 3 arguments.
+      llvm::Function *F = CGM.getIntrinsic(ID);
+      return Builder.CreateCall(F, Ops, "");
+    }
+    if (BuiltinID == PPC::BI__builtin_aes_genlastkey_paired ||
+        BuiltinID == PPC::BI__builtin_aes128_genlastkey_paired ||
+        BuiltinID == PPC::BI__builtin_aes192_genlastkey_paired ||
+        BuiltinID == PPC::BI__builtin_aes256_genlastkey_paired) {
+      if (BuiltinID == PPC::BI__builtin_aes128_genlastkey_paired)
+        Ops.push_back(llvm::ConstantInt::get(Int32Ty, 0));
+      else if (BuiltinID == PPC::BI__builtin_aes192_genlastkey_paired)
+        Ops.push_back(llvm::ConstantInt::get(Int32Ty, 1));
+      else if (BuiltinID == PPC::BI__builtin_aes256_genlastkey_paired)
+        Ops.push_back(llvm::ConstantInt::get(Int32Ty, 2));
+      // For base builtin, Ops already has all 2 arguments.
+      llvm::Function *F = CGM.getIntrinsic(ID);
+      return Builder.CreateCall(F, Ops, "");
+    }
+    if (BuiltinID == PPC::BI__builtin_galois_field_mult ||
+        BuiltinID == PPC::BI__builtin_galois_field_mult_gcm ||
+        BuiltinID == PPC::BI__builtin_galois_field_mult_xts) {
+      if (BuiltinID == PPC::BI__builtin_galois_field_mult_gcm)
+        Ops.push_back(llvm::ConstantInt::get(Int32Ty, 0));
+      else if (BuiltinID == PPC::BI__builtin_galois_field_mult_xts)
+        Ops.push_back(llvm::ConstantInt::get(Int32Ty, 1));
+      // For base builtin, Ops already has all 3 arguments.
+      llvm::Function *F = CGM.getIntrinsic(ID);
+      return Builder.CreateCall(F, Ops, "");
+    }
     SmallVector<Value*, 4> CallOps;
     if (Accumulate) {
       Address Addr = EmitPointerWithAlignment(E->getArg(0));
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 8d89056e6afaf..419d9a261e904 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 8fa603e0be8e2a6869affa34f7bc6c615a9f5644 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Fri, 17 Apr 2026 13:13:54 -0400
Subject: [PATCH 2/2] fix test file name

---
 .../{builtins--aes-acceleration.c => builtins-aes-acceleration.c} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename clang/test/CodeGen/PowerPC/{builtins--aes-acceleration.c => builtins-aes-acceleration.c} (100%)

diff --git a/clang/test/CodeGen/PowerPC/builtins--aes-acceleration.c b/clang/test/CodeGen/PowerPC/builtins-aes-acceleration.c
similarity index 100%
rename from clang/test/CodeGen/PowerPC/builtins--aes-acceleration.c
rename to clang/test/CodeGen/PowerPC/builtins-aes-acceleration.c



More information about the cfe-commits mailing list