[clang] [llvm] [PowerPC] Implement Elliptic Curve Cryptography Builtins (PR #184681)

Lei Huang via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 26 09:14:10 PDT 2026


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

>From e8c6734d2e5c6872c74a273cf0829eb707d8070e Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Wed, 4 Mar 2026 15:18:36 -0500
Subject: [PATCH 1/6] [PowerPC] Implement Elliptic Curve Cryptography Builtins

Add support for the following ISA Future elliptic curve cryptograpy builtins.

* Builtins with immediate parameters
vector unsigned char __builtin_xxmulmul(vector unsigned char, vector
unsigned char, unsigned int);
vector unsigned char __builtin_xxmulmulhiadd(vector unsigned char,
vector unsigned char, unsigned int, unsigned int, unsigned int);
vector unsigned char __builtin_xxmulmulloadd(vector unsigned char,
vector unsigned char, unsigned int, unsigned int);
vector unsigned char __builtin_xxssumudm(vector unsigned char, vector
unsigned char, unsigned int);
vector unsigned char __builtin_xxssumudmc(vector unsigned char, vector
unsigned char, unsigned int);
vector unsigned char __builtin_xxssumudmcext(vector unsigned char,
vector unsigned char, vector unsigned char, unsigned int);

* Builtins with two vector parameters (no immediates)
vector unsigned char __builtin_xsaddadduqm(vector unsigned char, vector
unsigned char);
vector unsigned char __builtin_xsaddaddsuqm(vector unsigned char, vector
unsigned char);
vector unsigned char __builtin_xsaddsubuqm(vector unsigned char, vector
unsigned char);
vector unsigned char __builtin_xsaddsubsuqm(vector unsigned char, vector
unsigned char);
vector unsigned char __builtin_xsmerge2t1uqm(vector unsigned char,
vector unsigned char);
vector unsigned char __builtin_xsmerge2t2uqm(vector unsigned char,
vector unsigned char);
vector unsigned char __builtin_xsmerge2t3uqm(vector unsigned char,
vector unsigned char);
vector unsigned char __builtin_xsmerge3t1uqm(vector unsigned char,
vector unsigned char);
vector unsigned char __builtin_xsrebase2t1uqm(vector unsigned char,
vector unsigned char);
vector unsigned char __builtin_xsrebase2t2uqm(vector unsigned char,
vector unsigned char);
vector unsigned char __builtin_xsrebase2t3uqm(vector unsigned char,
vector unsigned char);
vector unsigned char __builtin_xsrebase2t4uqm(vector unsigned char,
vector unsigned char);
vector unsigned char __builtin_xsrebase3t1uqm(vector unsigned char,
vector unsigned char);
vector unsigned char __builtin_xsrebase3t2uqm(vector unsigned char,
vector unsigned char);
vector unsigned char __builtin_xsrebase3t3uqm(vector unsigned char,
vector unsigned char);
---
 clang/include/clang/Basic/BuiltinsPPC.def     |  23 ++
 clang/test/CodeGen/PowerPC/builtins-ppc-ecc.c | 244 ++++++++++++++++++
 clang/test/Sema/builtins-ppc-ecc-error.c      |  47 ++++
 llvm/include/llvm/IR/IntrinsicsPowerPC.td     |  91 +++++++
 llvm/lib/Target/PowerPC/PPCInstrFuture.td     |  49 +++-
 llvm/lib/Target/PowerPC/PPCInstrP10.td        |   1 +
 llvm/test/CodeGen/PowerPC/builtins-ppc-ecc.ll | 216 ++++++++++++++++
 7 files changed, 668 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/CodeGen/PowerPC/builtins-ppc-ecc.c
 create mode 100644 clang/test/Sema/builtins-ppc-ecc-error.c
 create mode 100644 llvm/test/CodeGen/PowerPC/builtins-ppc-ecc.ll

diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index c0c92c0b73793..c11277cc9ff20 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1162,6 +1162,29 @@ UNALIASED_CUSTOM_MMA_BUILTIN(mma_dmxvf16gerx2, "vW1024*W256V",
 UNALIASED_CUSTOM_MMA_BUILTIN(mma_pmdmxvf16gerx2, "vW1024*W256Vi255i15i3",
                              "mma,isa-future-instructions")
 
+// Elliptic Curve Cryptography Builtins
+UNALIASED_CUSTOM_BUILTIN(xxmulmul, "VVVi7", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xxmulmulhiadd, "VVVi1i1i1", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xxmulmulloadd, "VVVi1i1", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xxssumudm, "VVVi1", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xxssumudmc, "VVVi1", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xxssumudmcext, "VVVVi1", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xsaddadduqm, "VVV", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xsaddaddsuqm, "VVV", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xsaddsubuqm, "VVV", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xsaddsubsuqm, "VVV", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xsmerge2t1uqm, "VVV", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xsmerge2t2uqm, "VVV", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xsmerge2t3uqm, "VVV", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xsmerge3t1uqm, "VVV", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xsrebase2t1uqm, "VVV", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xsrebase2t2uqm, "VVV", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xsrebase2t3uqm, "VVV", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xsrebase2t4uqm, "VVV", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xsrebase3t1uqm, "VVV", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xsrebase3t2uqm, "VVV", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xsrebase3t3uqm, "VVV", false, "isa-future-instructions")
+
 // FIXME: Obviously incomplete.
 
 #undef BUILTIN
diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-ecc.c b/clang/test/CodeGen/PowerPC/builtins-ppc-ecc.c
new file mode 100644
index 0000000000000..d5389ca9cccff
--- /dev/null
+++ b/clang/test/CodeGen/PowerPC/builtins-ppc-ecc.c
@@ -0,0 +1,244 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -flax-vector-conversions=none -triple powerpc64-unknown-unknown \
+// RUN:   -target-cpu future -target-feature +vsx \
+// RUN:   -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -flax-vector-conversions=none -triple powerpc64le-unknown-unknown \
+// RUN:   -target-cpu future -target-feature +vsx \
+// RUN:   -emit-llvm %s -o - | FileCheck %s
+
+// AI Generated.
+
+vector unsigned char vuca, vucb, vucc;
+
+// CHECK-LABEL: @test_xxmulmul(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xxmulmul(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 3)
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xxmulmul() {
+  return __builtin_xxmulmul(vuca, vucb, 3);
+}
+
+// CHECK-LABEL: @test_xxmulmulhiadd(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xxmulmulhiadd(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 0, i32 1, i32 0)
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xxmulmulhiadd() {
+  return __builtin_xxmulmulhiadd(vuca, vucb, 0, 1, 0);
+}
+
+// CHECK-LABEL: @test_xxmulmulloadd(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xxmulmulloadd(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1, i32 0)
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xxmulmulloadd() {
+  return __builtin_xxmulmulloadd(vuca, vucb, 1, 0);
+}
+
+// CHECK-LABEL: @test_xxssumudm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xxssumudm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 1)
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xxssumudm() {
+  return __builtin_xxssumudm(vuca, vucb, 1);
+}
+
+// CHECK-LABEL: @test_xxssumudmc(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xxssumudmc(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], i32 0)
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xxssumudmc() {
+  return __builtin_xxssumudmc(vuca, vucb, 0);
+}
+
+// CHECK-LABEL: @test_xxssumudmcext(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = load <16 x i8>, ptr @vucc, align 16
+// CHECK-NEXT:    [[TMP3:%.*]] = call <16 x i8> @llvm.ppc.xxssumudmcext(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]], i32 1)
+// CHECK-NEXT:    ret <16 x i8> [[TMP3]]
+//
+vector unsigned char test_xxssumudmcext() {
+  return __builtin_xxssumudmcext(vuca, vucb, vucc, 1);
+}
+
+// CHECK-LABEL: @test_xsaddadduqm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xsaddadduqm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xsaddadduqm() {
+  return __builtin_xsaddadduqm(vuca, vucb);
+}
+
+// CHECK-LABEL: @test_xsaddaddsuqm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xsaddaddsuqm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xsaddaddsuqm() {
+  return __builtin_xsaddaddsuqm(vuca, vucb);
+}
+
+// CHECK-LABEL: @test_xsaddsubuqm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xsaddsubuqm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xsaddsubuqm() {
+  return __builtin_xsaddsubuqm(vuca, vucb);
+}
+
+// CHECK-LABEL: @test_xsaddsubsuqm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xsaddsubsuqm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xsaddsubsuqm() {
+  return __builtin_xsaddsubsuqm(vuca, vucb);
+}
+
+// CHECK-LABEL: @test_xsmerge2t1uqm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xsmerge2t1uqm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xsmerge2t1uqm() {
+  return __builtin_xsmerge2t1uqm(vuca, vucb);
+}
+
+// CHECK-LABEL: @test_xsmerge2t2uqm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xsmerge2t2uqm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xsmerge2t2uqm() {
+  return __builtin_xsmerge2t2uqm(vuca, vucb);
+}
+
+// CHECK-LABEL: @test_xsmerge2t3uqm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xsmerge2t3uqm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xsmerge2t3uqm() {
+  return __builtin_xsmerge2t3uqm(vuca, vucb);
+}
+
+// CHECK-LABEL: @test_xsmerge3t1uqm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xsmerge3t1uqm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xsmerge3t1uqm() {
+  return __builtin_xsmerge3t1uqm(vuca, vucb);
+}
+
+// CHECK-LABEL: @test_xsrebase2t1uqm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xsrebase2t1uqm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xsrebase2t1uqm() {
+  return __builtin_xsrebase2t1uqm(vuca, vucb);
+}
+
+// CHECK-LABEL: @test_xsrebase2t2uqm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xsrebase2t2uqm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xsrebase2t2uqm() {
+  return __builtin_xsrebase2t2uqm(vuca, vucb);
+}
+
+// CHECK-LABEL: @test_xsrebase2t3uqm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xsrebase2t3uqm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xsrebase2t3uqm() {
+  return __builtin_xsrebase2t3uqm(vuca, vucb);
+}
+
+// CHECK-LABEL: @test_xsrebase2t4uqm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xsrebase2t4uqm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xsrebase2t4uqm() {
+  return __builtin_xsrebase2t4uqm(vuca, vucb);
+}
+
+// CHECK-LABEL: @test_xsrebase3t1uqm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xsrebase3t1uqm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xsrebase3t1uqm() {
+  return __builtin_xsrebase3t1uqm(vuca, vucb);
+}
+
+// CHECK-LABEL: @test_xsrebase3t2uqm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xsrebase3t2uqm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xsrebase3t2uqm() {
+  return __builtin_xsrebase3t2uqm(vuca, vucb);
+}
+
+// CHECK-LABEL: @test_xsrebase3t3uqm(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr @vuca, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, ptr @vucb, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = call <16 x i8> @llvm.ppc.xsrebase3t3uqm(<16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+vector unsigned char test_xsrebase3t3uqm() {
+  return __builtin_xsrebase3t3uqm(vuca, vucb);
+}
diff --git a/clang/test/Sema/builtins-ppc-ecc-error.c b/clang/test/Sema/builtins-ppc-ecc-error.c
new file mode 100644
index 0000000000000..612d40cdf12e4
--- /dev/null
+++ b/clang/test/Sema/builtins-ppc-ecc-error.c
@@ -0,0 +1,47 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-cpu future \
+// RUN:   -target-feature +vsx -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu future \
+// RUN:   -target-feature +vsx -fsyntax-only -verify %s
+
+// AI Generated.
+
+vector unsigned char vuca, vucb, vucc;
+int ia;
+
+void test_xxmulmul() {
+  __builtin_xxmulmul(vuca, vucb, 8);   // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+  __builtin_xxmulmul(vuca, vucb, -1);  // expected-error {{argument value -1 is outside the valid range [0, 7]}}
+  __builtin_xxmulmul(vuca, vucb, ia);  // expected-error {{argument to '__builtin_xxmulmul' must be a constant integer}}
+}
+
+void test_xxmulmulhiadd() {
+  __builtin_xxmulmulhiadd(vuca, vucb, 2, 0, 0);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+  __builtin_xxmulmulhiadd(vuca, vucb, 0, 2, 0);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+  __builtin_xxmulmulhiadd(vuca, vucb, 0, 0, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+  __builtin_xxmulmulhiadd(vuca, vucb, ia, 0, 0); // expected-error {{argument to '__builtin_xxmulmulhiadd' must be a constant integer}}
+}
+
+void test_xxmulmulloadd() {
+  __builtin_xxmulmulloadd(vuca, vucb, 2, 0);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+  __builtin_xxmulmulloadd(vuca, vucb, 0, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+  __builtin_xxmulmulloadd(vuca, vucb, ia, 0); // expected-error {{argument to '__builtin_xxmulmulloadd' must be a constant integer}}
+}
+
+void test_xxssumudm() {
+  __builtin_xxssumudm(vuca, vucb, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+  __builtin_xxssumudm(vuca, vucb, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}}
+  __builtin_xxssumudm(vuca, vucb, ia); // expected-error {{argument to '__builtin_xxssumudm' must be a constant integer}}
+}
+
+void test_xxssumudmc() {
+  __builtin_xxssumudmc(vuca, vucb, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+  __builtin_xxssumudmc(vuca, vucb, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}}
+  __builtin_xxssumudmc(vuca, vucb, ia); // expected-error {{argument to '__builtin_xxssumudmc' must be a constant integer}}
+}
+
+void test_xxssumudmcext() {
+  __builtin_xxssumudmcext(vuca, vucb, vucc, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+  __builtin_xxssumudmcext(vuca, vucb, vucc, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}}
+  __builtin_xxssumudmcext(vuca, vucb, vucc, ia); // expected-error {{argument to '__builtin_xxssumudmcext' must be a constant integer}}
+}
diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index bd8fb9e9a564d..99f8b8c4f5381 100644
--- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -2200,4 +2200,95 @@ let TargetPrefix = "ppc" in {
     DefaultAttrsIntrinsic<[llvm_i64_ty],[llvm_ptr_ty,
                            llvm_i64_ty, llvm_i64_ty],
                           [IntrArgMemOnly]>;
+
+  // Elliptic Curve Cryptography Intrinsics
+  def int_ppc_xxmulmul : ClangBuiltin<"__builtin_xxmulmul">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+                            [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+  def int_ppc_xxmulmulhiadd : ClangBuiltin<"__builtin_xxmulmulhiadd">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
+                             llvm_i32_ty, llvm_i32_ty],
+                            [IntrNoMem, ImmArg<ArgIndex<2>>,
+                             ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
+  def int_ppc_xxmulmulloadd : ClangBuiltin<"__builtin_xxmulmulloadd">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
+                             llvm_i32_ty],
+                            [IntrNoMem, ImmArg<ArgIndex<2>>,
+                             ImmArg<ArgIndex<3>>]>;
+  def int_ppc_xxssumudm : ClangBuiltin<"__builtin_xxssumudm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+                            [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+  def int_ppc_xxssumudmc : ClangBuiltin<"__builtin_xxssumudmc">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+                            [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+  def int_ppc_xxssumudmcext : ClangBuiltin<"__builtin_xxssumudmcext">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty,
+                             llvm_i32_ty],
+                            [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+  def int_ppc_xsaddadduqm : ClangBuiltin<"__builtin_xsaddadduqm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty],
+                            [IntrNoMem]>;
+  def int_ppc_xsaddaddsuqm : ClangBuiltin<"__builtin_xsaddaddsuqm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty],
+                            [IntrNoMem]>;
+  def int_ppc_xsaddsubuqm : ClangBuiltin<"__builtin_xsaddsubuqm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty],
+                            [IntrNoMem]>;
+  def int_ppc_xsaddsubsuqm : ClangBuiltin<"__builtin_xsaddsubsuqm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty],
+                            [IntrNoMem]>;
+  def int_ppc_xsmerge2t1uqm : ClangBuiltin<"__builtin_xsmerge2t1uqm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty],
+                            [IntrNoMem]>;
+  def int_ppc_xsmerge2t2uqm : ClangBuiltin<"__builtin_xsmerge2t2uqm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty],
+                            [IntrNoMem]>;
+  def int_ppc_xsmerge2t3uqm : ClangBuiltin<"__builtin_xsmerge2t3uqm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty],
+                            [IntrNoMem]>;
+  def int_ppc_xsmerge3t1uqm : ClangBuiltin<"__builtin_xsmerge3t1uqm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty],
+                            [IntrNoMem]>;
+  def int_ppc_xsrebase2t1uqm : ClangBuiltin<"__builtin_xsrebase2t1uqm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty],
+                            [IntrNoMem]>;
+  def int_ppc_xsrebase2t2uqm : ClangBuiltin<"__builtin_xsrebase2t2uqm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty],
+                            [IntrNoMem]>;
+  def int_ppc_xsrebase2t3uqm : ClangBuiltin<"__builtin_xsrebase2t3uqm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty],
+                            [IntrNoMem]>;
+  def int_ppc_xsrebase2t4uqm : ClangBuiltin<"__builtin_xsrebase2t4uqm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty],
+                            [IntrNoMem]>;
+  def int_ppc_xsrebase3t1uqm : ClangBuiltin<"__builtin_xsrebase3t1uqm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty],
+                            [IntrNoMem]>;
+  def int_ppc_xsrebase3t2uqm : ClangBuiltin<"__builtin_xsrebase3t2uqm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty],
+                            [IntrNoMem]>;
+  def int_ppc_xsrebase3t3uqm : ClangBuiltin<"__builtin_xsrebase3t3uqm">,
+      DefaultAttrsIntrinsic<[llvm_v16i8_ty],
+                            [llvm_v16i8_ty, llvm_v16i8_ty],
+                            [IntrNoMem]>;
 }
diff --git a/llvm/lib/Target/PowerPC/PPCInstrFuture.td b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
index 0cd63a88cb96b..7a75984a553bb 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrFuture.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
@@ -607,16 +607,59 @@ let Predicates = [HasFutureVector, PairedVectorMemops] in {
   def : Pat<(store v256i1:$XSp, xoaddr:$dst), (STXVPX $XSp, xoaddr:$dst)>;
 }
 
-let Predicates = [HasFutureVector] in {
+let Predicates = [HasVSX, HasFutureVector] in {
   def : Pat<(v4i32 (rotl v4i32:$vA, v4i32:$vB)), (v4i32 (XVRLW v4i32:$vA,
                                                      v4i32:$vB))>;
+  // Elliptic Curve Cryptography Patterns
+  def : Pat<(v16i8 (int_ppc_xxmulmul v16i8:$XA, v16i8:$XB, u3imm_timm:$S)),
+            (v16i8 (COPY_TO_REGCLASS (XXMULMUL RCCp.AToVSRC, RCCp.BToVSRC, $S), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xxmulmulhiadd v16i8:$XA, v16i8:$XB, u1imm_timm:$S0, u1imm_timm:$S1, u1imm_timm:$S2)),
+            (v16i8 (COPY_TO_REGCLASS (XXMULMULHIADD RCCp.AToVSRC, RCCp.BToVSRC, $S0, $S1, $S2), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xxmulmulloadd v16i8:$XA, v16i8:$XB, u1imm_timm:$S1, u1imm_timm:$S2)),
+            (v16i8 (COPY_TO_REGCLASS (XXMULMULLOADD RCCp.AToVSRC, RCCp.BToVSRC, $S1, $S2), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xxssumudm v16i8:$XA, v16i8:$XB, u1imm_timm:$P)),
+            (v16i8 (COPY_TO_REGCLASS (XXSSUMUDM RCCp.AToVSRC, RCCp.BToVSRC, $P), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xxssumudmc v16i8:$XA, v16i8:$XB, u1imm_timm:$P)),
+            (v16i8 (COPY_TO_REGCLASS (XXSSUMUDMC RCCp.AToVSRC, RCCp.BToVSRC, $P), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xxssumudmcext v16i8:$XA, v16i8:$XB, v16i8:$XC, u1imm_timm:$P)),
+            (v16i8 (COPY_TO_REGCLASS (XXSSUMUDMCEXT RCCp.AToVSRC, RCCp.BToVSRC, RCCp.CToVSRC, $P), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xsaddadduqm v16i8:$XA, v16i8:$XB)),
+            (v16i8 (COPY_TO_REGCLASS (XSADDADDUQM RCCp.AToVSRC, RCCp.BToVSRC), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xsaddaddsuqm v16i8:$XA, v16i8:$XB)),
+            (v16i8 (COPY_TO_REGCLASS (XSADDADDSUQM RCCp.AToVSRC, RCCp.BToVSRC), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xsaddsubuqm v16i8:$XA, v16i8:$XB)),
+            (v16i8 (COPY_TO_REGCLASS (XSADDSUBUQM RCCp.AToVSRC, RCCp.BToVSRC), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xsaddsubsuqm v16i8:$XA, v16i8:$XB)),
+            (v16i8 (COPY_TO_REGCLASS (XSADDSUBSUQM RCCp.AToVSRC, RCCp.BToVSRC), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xsmerge2t1uqm v16i8:$XA, v16i8:$XB)),
+            (v16i8 (COPY_TO_REGCLASS (XSMERGE2T1UQM RCCp.AToVSRC, RCCp.BToVSRC), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xsmerge2t2uqm v16i8:$XA, v16i8:$XB)),
+            (v16i8 (COPY_TO_REGCLASS (XSMERGE2T2UQM RCCp.AToVSRC, RCCp.BToVSRC), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xsmerge2t3uqm v16i8:$XA, v16i8:$XB)),
+            (v16i8 (COPY_TO_REGCLASS (XSMERGE2T3UQM RCCp.AToVSRC, RCCp.BToVSRC), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xsmerge3t1uqm v16i8:$XA, v16i8:$XB)),
+            (v16i8 (COPY_TO_REGCLASS (XSMERGE3T1UQM RCCp.AToVSRC, RCCp.BToVSRC), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xsrebase2t1uqm v16i8:$XA, v16i8:$XB)),
+            (v16i8 (COPY_TO_REGCLASS (XSREBASE2T1UQM RCCp.AToVSRC, RCCp.BToVSRC), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xsrebase2t2uqm v16i8:$XA, v16i8:$XB)),
+            (v16i8 (COPY_TO_REGCLASS (XSREBASE2T2UQM RCCp.AToVSRC, RCCp.BToVSRC), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xsrebase2t3uqm v16i8:$XA, v16i8:$XB)),
+            (v16i8 (COPY_TO_REGCLASS (XSREBASE2T3UQM RCCp.AToVSRC, RCCp.BToVSRC), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xsrebase2t4uqm v16i8:$XA, v16i8:$XB)),
+            (v16i8 (COPY_TO_REGCLASS (XSREBASE2T4UQM RCCp.AToVSRC, RCCp.BToVSRC), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xsrebase3t1uqm v16i8:$XA, v16i8:$XB)),
+            (v16i8 (COPY_TO_REGCLASS (XSREBASE3T1UQM RCCp.AToVSRC, RCCp.BToVSRC), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xsrebase3t2uqm v16i8:$XA, v16i8:$XB)),
+            (v16i8 (COPY_TO_REGCLASS (XSREBASE3T2UQM RCCp.AToVSRC, RCCp.BToVSRC), VSRC))>;
+  def : Pat<(v16i8 (int_ppc_xsrebase3t3uqm v16i8:$XA, v16i8:$XB)),
+            (v16i8 (COPY_TO_REGCLASS (XSREBASE3T3UQM RCCp.AToVSRC, RCCp.BToVSRC), VSRC))>;
 }
 
 //---------------------------- Instruction aliases ---------------------------//
 // Predicate combinations available:
-// [HasVSX, IsISAFuture]
+// [HasVSX, HasFutureVector]
 
-let Predicates = [HasFutureVector] in {
+let Predicates = [HasVSX, HasFutureVector] in {
   def : InstAlias<"xxaes128encp $XTp, $XAp, $XBp",
                   (XXAESENCP vsrprc:$XTp, vsrprc:$XAp, vsrprc:$XBp, 0)>;
   def : InstAlias<"xxaes192encp $XTp, $XAp, $XBp",
diff --git a/llvm/lib/Target/PowerPC/PPCInstrP10.td b/llvm/lib/Target/PowerPC/PPCInstrP10.td
index fdea9c5a4e0ba..6799a9838ec63 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrP10.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrP10.td
@@ -652,6 +652,7 @@ multiclass 8LS_DForm_R_SI34_XT6_RA5_MEM_p<bits<5> opcode, dag OOL, dag IOL,
 def RCCp {
   dag AToVSRC = (COPY_TO_REGCLASS $XA, VSRC);
   dag BToVSRC = (COPY_TO_REGCLASS $XB, VSRC);
+  dag CToVSRC = (COPY_TO_REGCLASS $XC, VSRC);
 }
 
 let Predicates = [PrefixInstrs] in {
diff --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-ecc.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-ecc.ll
new file mode 100644
index 0000000000000..abae8c8706eef
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-ecc.ll
@@ -0,0 +1,216 @@
+; 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 < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
+; RUN:   -mcpu=future -ppc-asm-full-reg-names < %s | FileCheck %s
+
+declare <16 x i8> @llvm.ppc.xxmulmul(<16 x i8>, <16 x i8>, i32 immarg)
+declare <16 x i8> @llvm.ppc.xxmulmulhiadd(<16 x i8>, <16 x i8>, i32 immarg, i32 immarg, i32 immarg)
+declare <16 x i8> @llvm.ppc.xxmulmulloadd(<16 x i8>, <16 x i8>, i32 immarg, i32 immarg)
+declare <16 x i8> @llvm.ppc.xxssumudm(<16 x i8>, <16 x i8>, i32 immarg)
+declare <16 x i8> @llvm.ppc.xxssumudmc(<16 x i8>, <16 x i8>, i32 immarg)
+declare <16 x i8> @llvm.ppc.xxssumudmcext(<16 x i8>, <16 x i8>, <16 x i8>, i32 immarg)
+declare <16 x i8> @llvm.ppc.xsaddadduqm(<16 x i8>, <16 x i8>)
+declare <16 x i8> @llvm.ppc.xsaddaddsuqm(<16 x i8>, <16 x i8>)
+declare <16 x i8> @llvm.ppc.xsaddsubuqm(<16 x i8>, <16 x i8>)
+declare <16 x i8> @llvm.ppc.xsaddsubsuqm(<16 x i8>, <16 x i8>)
+declare <16 x i8> @llvm.ppc.xsmerge2t1uqm(<16 x i8>, <16 x i8>)
+declare <16 x i8> @llvm.ppc.xsmerge2t2uqm(<16 x i8>, <16 x i8>)
+declare <16 x i8> @llvm.ppc.xsmerge2t3uqm(<16 x i8>, <16 x i8>)
+declare <16 x i8> @llvm.ppc.xsmerge3t1uqm(<16 x i8>, <16 x i8>)
+declare <16 x i8> @llvm.ppc.xsrebase2t1uqm(<16 x i8>, <16 x i8>)
+declare <16 x i8> @llvm.ppc.xsrebase2t2uqm(<16 x i8>, <16 x i8>)
+declare <16 x i8> @llvm.ppc.xsrebase2t3uqm(<16 x i8>, <16 x i8>)
+declare <16 x i8> @llvm.ppc.xsrebase2t4uqm(<16 x i8>, <16 x i8>)
+declare <16 x i8> @llvm.ppc.xsrebase3t1uqm(<16 x i8>, <16 x i8>)
+declare <16 x i8> @llvm.ppc.xsrebase3t2uqm(<16 x i8>, <16 x i8>)
+declare <16 x i8> @llvm.ppc.xsrebase3t3uqm(<16 x i8>, <16 x i8>)
+
+define <16 x i8> @test_xxmulmul(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xxmulmul:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xxmulmul vs34, vs34, vs35, 3
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xxmulmul(<16 x i8> %a, <16 x i8> %b, i32 3)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xxmulmulhiadd(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xxmulmulhiadd:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xxmulmulhiadd vs34, vs34, vs35, 0, 1, 0
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xxmulmulhiadd(<16 x i8> %a, <16 x i8> %b, i32 0, i32 1, i32 0)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xxmulmulloadd(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xxmulmulloadd:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xxmulmulloadd vs34, vs34, vs35, 1, 0
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xxmulmulloadd(<16 x i8> %a, <16 x i8> %b, i32 1, i32 0)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xxssumudm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xxssumudm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xxssumudm vs34, vs34, vs35, 1
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xxssumudm(<16 x i8> %a, <16 x i8> %b, i32 1)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xxssumudmc(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xxssumudmc:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xxssumudmc vs34, vs34, vs35, 0
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xxssumudmc(<16 x i8> %a, <16 x i8> %b, i32 0)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xxssumudmcext(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c) {
+; CHECK-LABEL: test_xxssumudmcext:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xxssumudmcext vs34, vs34, vs35, vs36, 1
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xxssumudmcext(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c, i32 1)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xsaddadduqm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xsaddadduqm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xsaddadduqm vs34, vs34, vs35
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xsaddadduqm(<16 x i8> %a, <16 x i8> %b)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xsaddaddsuqm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xsaddaddsuqm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xsaddaddsuqm vs34, vs34, vs35
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xsaddaddsuqm(<16 x i8> %a, <16 x i8> %b)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xsaddsubuqm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xsaddsubuqm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xsaddsubuqm vs34, vs34, vs35
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xsaddsubuqm(<16 x i8> %a, <16 x i8> %b)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xsaddsubsuqm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xsaddsubsuqm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xsaddsubsuqm vs34, vs34, vs35
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xsaddsubsuqm(<16 x i8> %a, <16 x i8> %b)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xsmerge2t1uqm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xsmerge2t1uqm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xsmerge2t1uqm vs34, vs34, vs35
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xsmerge2t1uqm(<16 x i8> %a, <16 x i8> %b)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xsmerge2t2uqm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xsmerge2t2uqm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xsmerge2t2uqm vs34, vs34, vs35
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xsmerge2t2uqm(<16 x i8> %a, <16 x i8> %b)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xsmerge2t3uqm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xsmerge2t3uqm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xsmerge2t3uqm vs34, vs34, vs35
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xsmerge2t3uqm(<16 x i8> %a, <16 x i8> %b)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xsmerge3t1uqm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xsmerge3t1uqm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xsmerge3t1uqm vs34, vs34, vs35
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xsmerge3t1uqm(<16 x i8> %a, <16 x i8> %b)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xsrebase2t1uqm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xsrebase2t1uqm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xsrebase2t1uqm vs34, vs34, vs35
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xsrebase2t1uqm(<16 x i8> %a, <16 x i8> %b)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xsrebase2t2uqm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xsrebase2t2uqm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xsrebase2t2uqm vs34, vs34, vs35
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xsrebase2t2uqm(<16 x i8> %a, <16 x i8> %b)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xsrebase2t3uqm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xsrebase2t3uqm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xsrebase2t3uqm vs34, vs34, vs35
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xsrebase2t3uqm(<16 x i8> %a, <16 x i8> %b)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xsrebase2t4uqm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xsrebase2t4uqm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xsrebase2t4uqm vs34, vs34, vs35
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xsrebase2t4uqm(<16 x i8> %a, <16 x i8> %b)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xsrebase3t1uqm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xsrebase3t1uqm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xsrebase3t1uqm vs34, vs34, vs35
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xsrebase3t1uqm(<16 x i8> %a, <16 x i8> %b)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xsrebase3t2uqm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xsrebase3t2uqm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xsrebase3t2uqm vs34, vs34, vs35
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xsrebase3t2uqm(<16 x i8> %a, <16 x i8> %b)
+  ret <16 x i8> %res
+}
+
+define <16 x i8> @test_xsrebase3t3uqm(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: test_xsrebase3t3uqm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xsrebase3t3uqm vs34, vs34, vs35
+; CHECK-NEXT:    blr
+  %res = call <16 x i8> @llvm.ppc.xsrebase3t3uqm(<16 x i8> %a, <16 x i8> %b)
+  ret <16 x i8> %res
+}
\ No newline at end of file

>From c430668eb3c2f37b03ad13b001ac0e80c090a1ea Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Wed, 25 Mar 2026 19:12:39 -0400
Subject: [PATCH 2/6] add error for non mcpu=future runs

---
 .../Sema/PowerPC/builtins-ppc-ecc-error.c     | 66 +++++++++++++++++++
 clang/test/Sema/builtins-ppc-ecc-error.c      | 47 -------------
 2 files changed, 66 insertions(+), 47 deletions(-)
 create mode 100644 clang/test/Sema/PowerPC/builtins-ppc-ecc-error.c
 delete mode 100644 clang/test/Sema/builtins-ppc-ecc-error.c

diff --git a/clang/test/Sema/PowerPC/builtins-ppc-ecc-error.c b/clang/test/Sema/PowerPC/builtins-ppc-ecc-error.c
new file mode 100644
index 0000000000000..f4ccf591e27da
--- /dev/null
+++ b/clang/test/Sema/PowerPC/builtins-ppc-ecc-error.c
@@ -0,0 +1,66 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-cpu future \
+// RUN:   -target-feature +vsx -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu future \
+// RUN:   -target-feature +vsx -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-cpu pwr10 \
+// RUN:   -target-feature +vsx -fsyntax-only -verify=pwr10 %s
+
+vector unsigned char vuca, vucb, vucc;
+int ia;
+
+void test_xxmulmul() {
+  __builtin_xxmulmul(vuca, vucb, 8);   // expected-error {{argument value 8 is outside the valid range [0, 7]}} \
+                                       // pwr10-error {{'__builtin_xxmulmul' needs target feature isa-future-instructions}}
+  __builtin_xxmulmul(vuca, vucb, -1);  // expected-error {{argument value -1 is outside the valid range [0, 7]}} \
+                                       // pwr10-error {{'__builtin_xxmulmul' needs target feature isa-future-instructions}}
+  __builtin_xxmulmul(vuca, vucb, ia);  // expected-error {{argument to '__builtin_xxmulmul' must be a constant integer}} \
+                                       // pwr10-error {{'__builtin_xxmulmul' needs target feature isa-future-instructions}}
+}
+
+void test_xxmulmulhiadd() {
+  __builtin_xxmulmulhiadd(vuca, vucb, 2, 0, 0);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
+                                                 // pwr10-error {{'__builtin_xxmulmulhiadd' needs target feature isa-future-instructions}}
+  __builtin_xxmulmulhiadd(vuca, vucb, 0, 2, 0);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
+                                                 // pwr10-error {{'__builtin_xxmulmulhiadd' needs target feature isa-future-instructions}}
+  __builtin_xxmulmulhiadd(vuca, vucb, 0, 0, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
+                                                 // pwr10-error {{'__builtin_xxmulmulhiadd' needs target feature isa-future-instructions}}
+  __builtin_xxmulmulhiadd(vuca, vucb, ia, 0, 0); // expected-error {{argument to '__builtin_xxmulmulhiadd' must be a constant integer}} \
+                                                 // pwr10-error {{'__builtin_xxmulmulhiadd' needs target feature isa-future-instructions}}
+}
+
+void test_xxmulmulloadd() {
+  __builtin_xxmulmulloadd(vuca, vucb, 2, 0);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
+                                              // pwr10-error {{'__builtin_xxmulmulloadd' needs target feature isa-future-instructions}}
+  __builtin_xxmulmulloadd(vuca, vucb, 0, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
+                                              // pwr10-error {{'__builtin_xxmulmulloadd' needs target feature isa-future-instructions}}
+  __builtin_xxmulmulloadd(vuca, vucb, ia, 0); // expected-error {{argument to '__builtin_xxmulmulloadd' must be a constant integer}} \
+                                              // pwr10-error {{'__builtin_xxmulmulloadd' needs target feature isa-future-instructions}}
+}
+
+void test_xxssumudm() {
+  __builtin_xxssumudm(vuca, vucb, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
+                                       // pwr10-error {{'__builtin_xxssumudm' needs target feature isa-future-instructions}}
+  __builtin_xxssumudm(vuca, vucb, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} \
+                                       // pwr10-error {{'__builtin_xxssumudm' needs target feature isa-future-instructions}}
+  __builtin_xxssumudm(vuca, vucb, ia); // expected-error {{argument to '__builtin_xxssumudm' must be a constant integer}} \
+                                       // pwr10-error {{'__builtin_xxssumudm' needs target feature isa-future-instructions}}
+}
+
+void test_xxssumudmc() {
+  __builtin_xxssumudmc(vuca, vucb, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
+                                        // pwr10-error {{'__builtin_xxssumudmc' needs target feature isa-future-instructions}}
+  __builtin_xxssumudmc(vuca, vucb, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} \
+                                        // pwr10-error {{'__builtin_xxssumudmc' needs target feature isa-future-instructions}}
+  __builtin_xxssumudmc(vuca, vucb, ia); // expected-error {{argument to '__builtin_xxssumudmc' must be a constant integer}} \
+                                        // pwr10-error {{'__builtin_xxssumudmc' needs target feature isa-future-instructions}}
+}
+
+void test_xxssumudmcext() {
+  __builtin_xxssumudmcext(vuca, vucb, vucc, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
+                                                 // pwr10-error {{'__builtin_xxssumudmcext' needs target feature isa-future-instructions}}
+  __builtin_xxssumudmcext(vuca, vucb, vucc, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} \
+                                                 // pwr10-error {{'__builtin_xxssumudmcext' needs target feature isa-future-instructions}}
+  __builtin_xxssumudmcext(vuca, vucb, vucc, ia); // expected-error {{argument to '__builtin_xxssumudmcext' must be a constant integer}} \
+                                                 // pwr10-error {{'__builtin_xxssumudmcext' needs target feature isa-future-instructions}}
+}
diff --git a/clang/test/Sema/builtins-ppc-ecc-error.c b/clang/test/Sema/builtins-ppc-ecc-error.c
deleted file mode 100644
index 612d40cdf12e4..0000000000000
--- a/clang/test/Sema/builtins-ppc-ecc-error.c
+++ /dev/null
@@ -1,47 +0,0 @@
-// REQUIRES: powerpc-registered-target
-// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-cpu future \
-// RUN:   -target-feature +vsx -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu future \
-// RUN:   -target-feature +vsx -fsyntax-only -verify %s
-
-// AI Generated.
-
-vector unsigned char vuca, vucb, vucc;
-int ia;
-
-void test_xxmulmul() {
-  __builtin_xxmulmul(vuca, vucb, 8);   // expected-error {{argument value 8 is outside the valid range [0, 7]}}
-  __builtin_xxmulmul(vuca, vucb, -1);  // expected-error {{argument value -1 is outside the valid range [0, 7]}}
-  __builtin_xxmulmul(vuca, vucb, ia);  // expected-error {{argument to '__builtin_xxmulmul' must be a constant integer}}
-}
-
-void test_xxmulmulhiadd() {
-  __builtin_xxmulmulhiadd(vuca, vucb, 2, 0, 0);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
-  __builtin_xxmulmulhiadd(vuca, vucb, 0, 2, 0);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
-  __builtin_xxmulmulhiadd(vuca, vucb, 0, 0, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
-  __builtin_xxmulmulhiadd(vuca, vucb, ia, 0, 0); // expected-error {{argument to '__builtin_xxmulmulhiadd' must be a constant integer}}
-}
-
-void test_xxmulmulloadd() {
-  __builtin_xxmulmulloadd(vuca, vucb, 2, 0);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
-  __builtin_xxmulmulloadd(vuca, vucb, 0, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
-  __builtin_xxmulmulloadd(vuca, vucb, ia, 0); // expected-error {{argument to '__builtin_xxmulmulloadd' must be a constant integer}}
-}
-
-void test_xxssumudm() {
-  __builtin_xxssumudm(vuca, vucb, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
-  __builtin_xxssumudm(vuca, vucb, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}}
-  __builtin_xxssumudm(vuca, vucb, ia); // expected-error {{argument to '__builtin_xxssumudm' must be a constant integer}}
-}
-
-void test_xxssumudmc() {
-  __builtin_xxssumudmc(vuca, vucb, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
-  __builtin_xxssumudmc(vuca, vucb, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}}
-  __builtin_xxssumudmc(vuca, vucb, ia); // expected-error {{argument to '__builtin_xxssumudmc' must be a constant integer}}
-}
-
-void test_xxssumudmcext() {
-  __builtin_xxssumudmcext(vuca, vucb, vucc, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
-  __builtin_xxssumudmcext(vuca, vucb, vucc, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}}
-  __builtin_xxssumudmcext(vuca, vucb, vucc, ia); // expected-error {{argument to '__builtin_xxssumudmcext' must be a constant integer}}
-}

>From 7e0402050c1d4c9af65edfced09079e8ce8015b4 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Thu, 26 Mar 2026 12:07:46 -0400
Subject: [PATCH 3/6] update to use future-vector

---
 clang/include/clang/Basic/BuiltinsPPC.def     | 42 ++++++++--------
 clang/lib/Basic/Targets/PPC.cpp               |  4 ++
 clang/lib/Basic/Targets/PPC.h                 |  1 +
 .../{builtins-ppc-ecc.c => builtins-ecc.c}    |  8 ++--
 ...s-ppc-ecc-error.c => builtins-ecc-error.c} | 48 +++++++++----------
 5 files changed, 53 insertions(+), 50 deletions(-)
 rename clang/test/CodeGen/PowerPC/{builtins-ppc-ecc.c => builtins-ecc.c} (97%)
 rename clang/test/Sema/PowerPC/{builtins-ppc-ecc-error.c => builtins-ecc-error.c} (71%)

diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index c11277cc9ff20..8ad7efe5e814d 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1163,27 +1163,27 @@ UNALIASED_CUSTOM_MMA_BUILTIN(mma_pmdmxvf16gerx2, "vW1024*W256Vi255i15i3",
                              "mma,isa-future-instructions")
 
 // Elliptic Curve Cryptography Builtins
-UNALIASED_CUSTOM_BUILTIN(xxmulmul, "VVVi7", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xxmulmulhiadd, "VVVi1i1i1", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xxmulmulloadd, "VVVi1i1", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xxssumudm, "VVVi1", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xxssumudmc, "VVVi1", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xxssumudmcext, "VVVVi1", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xsaddadduqm, "VVV", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xsaddaddsuqm, "VVV", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xsaddsubuqm, "VVV", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xsaddsubsuqm, "VVV", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xsmerge2t1uqm, "VVV", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xsmerge2t2uqm, "VVV", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xsmerge2t3uqm, "VVV", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xsmerge3t1uqm, "VVV", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xsrebase2t1uqm, "VVV", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xsrebase2t2uqm, "VVV", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xsrebase2t3uqm, "VVV", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xsrebase2t4uqm, "VVV", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xsrebase3t1uqm, "VVV", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xsrebase3t2uqm, "VVV", false, "isa-future-instructions")
-UNALIASED_CUSTOM_BUILTIN(xsrebase3t3uqm, "VVV", false, "isa-future-instructions")
+UNALIASED_CUSTOM_BUILTIN(xxmulmul, "VVVi7", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xxmulmulhiadd, "VVVi1i1i1", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xxmulmulloadd, "VVVi1i1", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xxssumudm, "VVVi1", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xxssumudmc, "VVVi1", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xxssumudmcext, "VVVVi1", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xsaddadduqm, "VVV", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xsaddaddsuqm, "VVV", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xsaddsubuqm, "VVV", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xsaddsubsuqm, "VVV", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xsmerge2t1uqm, "VVV", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xsmerge2t2uqm, "VVV", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xsmerge2t3uqm, "VVV", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xsmerge3t1uqm, "VVV", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xsrebase2t1uqm, "VVV", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xsrebase2t2uqm, "VVV", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xsrebase2t3uqm, "VVV", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xsrebase2t4uqm, "VVV", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xsrebase3t1uqm, "VVV", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xsrebase3t2uqm, "VVV", false, "future-vector")
+UNALIASED_CUSTOM_BUILTIN(xsrebase3t3uqm, "VVV", false, "future-vector")
 
 // FIXME: Obviously incomplete.
 
diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index 30ea714fbb6f8..c9a41df806aff 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -59,6 +59,8 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
       HasP9Vector = true;
     } else if (Feature == "+power10-vector") {
       HasP10Vector = true;
+    } else if (Feature == "+future-vector") {
+      HasFutureVector = true;
     } else if (Feature == "+pcrelative-memops") {
       HasPCRelativeMemops = true;
     } else if (Feature == "+spe" || Feature == "+efpu2") {
@@ -434,6 +436,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
     Builder.defineMacro("__POWER10_VECTOR__");
   if (HasPCRelativeMemops)
     Builder.defineMacro("__PCREL__");
+  if (HasFutureVector)
+    Builder.defineMacro("__FUTURE_VECTOR__");
 
   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h
index 6f90ff1f5d57c..a9f49aa3aebe1 100644
--- a/clang/lib/Basic/Targets/PPC.h
+++ b/clang/lib/Basic/Targets/PPC.h
@@ -69,6 +69,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
   bool HasFrsqrte = false;
   bool HasFrsqrtes = false;
   bool HasP10Vector = false;
+  bool HasFutureVector = false;
   bool HasPCRelativeMemops = false;
   bool HasQuadwordAtomics = false;
   bool UseLongCalls = false;
diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-ecc.c b/clang/test/CodeGen/PowerPC/builtins-ecc.c
similarity index 97%
rename from clang/test/CodeGen/PowerPC/builtins-ppc-ecc.c
rename to clang/test/CodeGen/PowerPC/builtins-ecc.c
index d5389ca9cccff..cfce1dee64820 100644
--- a/clang/test/CodeGen/PowerPC/builtins-ppc-ecc.c
+++ b/clang/test/CodeGen/PowerPC/builtins-ecc.c
@@ -1,11 +1,9 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
 // REQUIRES: powerpc-registered-target
-// RUN: %clang_cc1 -flax-vector-conversions=none -triple powerpc64-unknown-unknown \
-// RUN:   -target-cpu future -target-feature +vsx \
-// RUN:   -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -flax-vector-conversions=none -triple powerpc-unknown-unknown \
+// RUN:   -target-cpu future -emit-llvm %s -o - | FileCheck %s
 // RUN: %clang_cc1 -flax-vector-conversions=none -triple powerpc64le-unknown-unknown \
-// RUN:   -target-cpu future -target-feature +vsx \
-// RUN:   -emit-llvm %s -o - | FileCheck %s
+// RUN:   -target-cpu future -emit-llvm %s -o - | FileCheck %s
 
 // AI Generated.
 
diff --git a/clang/test/Sema/PowerPC/builtins-ppc-ecc-error.c b/clang/test/Sema/PowerPC/builtins-ecc-error.c
similarity index 71%
rename from clang/test/Sema/PowerPC/builtins-ppc-ecc-error.c
rename to clang/test/Sema/PowerPC/builtins-ecc-error.c
index f4ccf591e27da..e56c7a11017e0 100644
--- a/clang/test/Sema/PowerPC/builtins-ppc-ecc-error.c
+++ b/clang/test/Sema/PowerPC/builtins-ecc-error.c
@@ -1,66 +1,66 @@
 // REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-cpu future \
-// RUN:   -target-feature +vsx -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu future \
-// RUN:   -target-feature +vsx -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-cpu pwr10 \
-// RUN:   -target-feature +vsx -fsyntax-only -verify=pwr10 %s
+// RUN:   -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple powerpc-unknown-unknown -target-cpu future \
+// RUN:   -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr10 \
+// RUN:   -fsyntax-only -verify=pwr10 %s
 
 vector unsigned char vuca, vucb, vucc;
 int ia;
 
 void test_xxmulmul() {
   __builtin_xxmulmul(vuca, vucb, 8);   // expected-error {{argument value 8 is outside the valid range [0, 7]}} \
-                                       // pwr10-error {{'__builtin_xxmulmul' needs target feature isa-future-instructions}}
+                                       // pwr10-error {{'__builtin_xxmulmul' needs target feature future-vector}}
   __builtin_xxmulmul(vuca, vucb, -1);  // expected-error {{argument value -1 is outside the valid range [0, 7]}} \
-                                       // pwr10-error {{'__builtin_xxmulmul' needs target feature isa-future-instructions}}
+                                       // pwr10-error {{'__builtin_xxmulmul' needs target feature future-vector}}
   __builtin_xxmulmul(vuca, vucb, ia);  // expected-error {{argument to '__builtin_xxmulmul' must be a constant integer}} \
-                                       // pwr10-error {{'__builtin_xxmulmul' needs target feature isa-future-instructions}}
+                                       // pwr10-error {{'__builtin_xxmulmul' needs target feature future-vector}}
 }
 
 void test_xxmulmulhiadd() {
   __builtin_xxmulmulhiadd(vuca, vucb, 2, 0, 0);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
-                                                 // pwr10-error {{'__builtin_xxmulmulhiadd' needs target feature isa-future-instructions}}
+                                                 // pwr10-error {{'__builtin_xxmulmulhiadd' needs target feature future-vector}}
   __builtin_xxmulmulhiadd(vuca, vucb, 0, 2, 0);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
-                                                 // pwr10-error {{'__builtin_xxmulmulhiadd' needs target feature isa-future-instructions}}
+                                                 // pwr10-error {{'__builtin_xxmulmulhiadd' needs target feature future-vector}}
   __builtin_xxmulmulhiadd(vuca, vucb, 0, 0, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
-                                                 // pwr10-error {{'__builtin_xxmulmulhiadd' needs target feature isa-future-instructions}}
+                                                 // pwr10-error {{'__builtin_xxmulmulhiadd' needs target feature future-vector}}
   __builtin_xxmulmulhiadd(vuca, vucb, ia, 0, 0); // expected-error {{argument to '__builtin_xxmulmulhiadd' must be a constant integer}} \
-                                                 // pwr10-error {{'__builtin_xxmulmulhiadd' needs target feature isa-future-instructions}}
+                                                 // pwr10-error {{'__builtin_xxmulmulhiadd' needs target feature future-vector}}
 }
 
 void test_xxmulmulloadd() {
   __builtin_xxmulmulloadd(vuca, vucb, 2, 0);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
-                                              // pwr10-error {{'__builtin_xxmulmulloadd' needs target feature isa-future-instructions}}
+                                              // pwr10-error {{'__builtin_xxmulmulloadd' needs target feature future-vector}}
   __builtin_xxmulmulloadd(vuca, vucb, 0, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
-                                              // pwr10-error {{'__builtin_xxmulmulloadd' needs target feature isa-future-instructions}}
+                                              // pwr10-error {{'__builtin_xxmulmulloadd' needs target feature future-vector}}
   __builtin_xxmulmulloadd(vuca, vucb, ia, 0); // expected-error {{argument to '__builtin_xxmulmulloadd' must be a constant integer}} \
-                                              // pwr10-error {{'__builtin_xxmulmulloadd' needs target feature isa-future-instructions}}
+                                              // pwr10-error {{'__builtin_xxmulmulloadd' needs target feature future-vector}}
 }
 
 void test_xxssumudm() {
   __builtin_xxssumudm(vuca, vucb, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
-                                       // pwr10-error {{'__builtin_xxssumudm' needs target feature isa-future-instructions}}
+                                       // pwr10-error {{'__builtin_xxssumudm' needs target feature future-vector}}
   __builtin_xxssumudm(vuca, vucb, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} \
-                                       // pwr10-error {{'__builtin_xxssumudm' needs target feature isa-future-instructions}}
+                                       // pwr10-error {{'__builtin_xxssumudm' needs target feature future-vector}}
   __builtin_xxssumudm(vuca, vucb, ia); // expected-error {{argument to '__builtin_xxssumudm' must be a constant integer}} \
-                                       // pwr10-error {{'__builtin_xxssumudm' needs target feature isa-future-instructions}}
+                                       // pwr10-error {{'__builtin_xxssumudm' needs target feature future-vector}}
 }
 
 void test_xxssumudmc() {
   __builtin_xxssumudmc(vuca, vucb, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
-                                        // pwr10-error {{'__builtin_xxssumudmc' needs target feature isa-future-instructions}}
+                                        // pwr10-error {{'__builtin_xxssumudmc' needs target feature future-vector}}
   __builtin_xxssumudmc(vuca, vucb, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} \
-                                        // pwr10-error {{'__builtin_xxssumudmc' needs target feature isa-future-instructions}}
+                                        // pwr10-error {{'__builtin_xxssumudmc' needs target feature future-vector}}
   __builtin_xxssumudmc(vuca, vucb, ia); // expected-error {{argument to '__builtin_xxssumudmc' must be a constant integer}} \
-                                        // pwr10-error {{'__builtin_xxssumudmc' needs target feature isa-future-instructions}}
+                                        // pwr10-error {{'__builtin_xxssumudmc' needs target feature future-vector}}
 }
 
 void test_xxssumudmcext() {
   __builtin_xxssumudmcext(vuca, vucb, vucc, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}} \
-                                                 // pwr10-error {{'__builtin_xxssumudmcext' needs target feature isa-future-instructions}}
+                                                 // pwr10-error {{'__builtin_xxssumudmcext' needs target feature future-vector}}
   __builtin_xxssumudmcext(vuca, vucb, vucc, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} \
-                                                 // pwr10-error {{'__builtin_xxssumudmcext' needs target feature isa-future-instructions}}
+                                                 // pwr10-error {{'__builtin_xxssumudmcext' needs target feature future-vector}}
   __builtin_xxssumudmcext(vuca, vucb, vucc, ia); // expected-error {{argument to '__builtin_xxssumudmcext' must be a constant integer}} \
-                                                 // pwr10-error {{'__builtin_xxssumudmcext' needs target feature isa-future-instructions}}
+                                                 // pwr10-error {{'__builtin_xxssumudmcext' needs target feature future-vector}}
 }

>From a4ac640c88b256c2a19cd066a6ec58ab93090bda Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Thu, 26 Mar 2026 12:09:38 -0400
Subject: [PATCH 4/6] remove unrelated update

---
 llvm/lib/Target/PowerPC/PPCInstrFuture.td | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCInstrFuture.td b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
index 7a75984a553bb..2b889ee0b76df 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrFuture.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
@@ -657,9 +657,9 @@ let Predicates = [HasVSX, HasFutureVector] in {
 
 //---------------------------- Instruction aliases ---------------------------//
 // Predicate combinations available:
-// [HasVSX, HasFutureVector]
+// [HasVSX, IsISAFuture]
 
-let Predicates = [HasVSX, HasFutureVector] in {
+let Predicates = [HasFutureVector] in {
   def : InstAlias<"xxaes128encp $XTp, $XAp, $XBp",
                   (XXAESENCP vsrprc:$XTp, vsrprc:$XAp, vsrprc:$XBp, 0)>;
   def : InstAlias<"xxaes192encp $XTp, $XAp, $XBp",

>From 4a7f833edc78ff35718ac55e367e2781c146abd6 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Thu, 26 Mar 2026 12:10:59 -0400
Subject: [PATCH 5/6] remove unrelated update

---
 llvm/lib/Target/PowerPC/PPCInstrFuture.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/PowerPC/PPCInstrFuture.td b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
index 2b889ee0b76df..8aee852abe2be 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrFuture.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
@@ -607,7 +607,7 @@ let Predicates = [HasFutureVector, PairedVectorMemops] in {
   def : Pat<(store v256i1:$XSp, xoaddr:$dst), (STXVPX $XSp, xoaddr:$dst)>;
 }
 
-let Predicates = [HasVSX, HasFutureVector] in {
+let Predicates = [HasFutureVector] in {
   def : Pat<(v4i32 (rotl v4i32:$vA, v4i32:$vB)), (v4i32 (XVRLW v4i32:$vA,
                                                      v4i32:$vB))>;
   // Elliptic Curve Cryptography Patterns

>From 8c15a0e98d6b48e03f1225b517be50934b97f181 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Thu, 26 Mar 2026 12:13:50 -0400
Subject: [PATCH 6/6] rename

---
 .../test/CodeGen/PowerPC/{builtins-ppc-ecc.ll => builtins-ecc.ll} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename llvm/test/CodeGen/PowerPC/{builtins-ppc-ecc.ll => builtins-ecc.ll} (100%)

diff --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-ecc.ll b/llvm/test/CodeGen/PowerPC/builtins-ecc.ll
similarity index 100%
rename from llvm/test/CodeGen/PowerPC/builtins-ppc-ecc.ll
rename to llvm/test/CodeGen/PowerPC/builtins-ecc.ll



More information about the cfe-commits mailing list