https://github.com/tclin914 updated 
https://github.com/llvm/llvm-project/pull/147018

>From a7da278e7831ba3e5bd95c587083c50c600c9950 Mon Sep 17 00:00:00 2001
From: Jim Lin <j...@andestech.com>
Date: Mon, 5 May 2025 13:58:59 +0800
Subject: [PATCH 1/4] [RISCV] Implement Clang Builtins for XAndesPerf Extension

This patch adds the Clang builtins for byte comparision instructions in
XAndesPerf Extension. These instructions are hardly generated by
compiler. So we provide the Clang builtins for the user.
---
 .../clang/Basic/BuiltinsRISCVXAndes.td        |   9 +
 clang/lib/CodeGen/TargetBuiltins/RISCV.cpp    |  18 ++
 clang/lib/Headers/CMakeLists.txt              |   1 +
 clang/lib/Headers/riscv_nds.h                 |  26 +++
 .../CodeGen/RISCV/riscv-xandesperf-c-api.c    | 159 ++++++++++++++++++
 clang/test/CodeGen/RISCV/riscv-xandesperf.c   | 109 ++++++++++++
 llvm/include/llvm/IR/IntrinsicsRISCVXAndes.td |  14 ++
 llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td |  11 ++
 llvm/test/CodeGen/RISCV/rv32xandesperf.ll     |  47 ++++++
 llvm/test/CodeGen/RISCV/rv64xandesperf.ll     |  47 ++++++
 10 files changed, 441 insertions(+)
 create mode 100644 clang/test/CodeGen/RISCV/riscv-xandesperf-c-api.c
 create mode 100644 clang/test/CodeGen/RISCV/riscv-xandesperf.c

diff --git a/clang/include/clang/Basic/BuiltinsRISCVXAndes.td 
b/clang/include/clang/Basic/BuiltinsRISCVXAndes.td
index ea9a7166bc6e8..789eb0ad8172d 100644
--- a/clang/include/clang/Basic/BuiltinsRISCVXAndes.td
+++ b/clang/include/clang/Basic/BuiltinsRISCVXAndes.td
@@ -18,6 +18,15 @@ class RISCVXAndesBuiltin<string prototype, string features = 
""> : TargetBuiltin
 }
 
 let Attributes = [NoThrow, Const] in {
+//===----------------------------------------------------------------------===//
+// XAndesPerf extension.
+//===----------------------------------------------------------------------===//
+
+def ffb     : RISCVXAndesBuiltin<"long int(unsigned long int, unsigned long 
int)", "xandesperf">;
+def ffzmism : RISCVXAndesBuiltin<"long int(unsigned long int, unsigned long 
int)", "xandesperf">;
+def ffmism  : RISCVXAndesBuiltin<"long int(unsigned long int, unsigned long 
int)", "xandesperf">;
+def flmism  : RISCVXAndesBuiltin<"long int(unsigned long int, unsigned long 
int)", "xandesperf">;
+
 
//===----------------------------------------------------------------------===//
 // XAndesBFHCvt extension.
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp 
b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
index b08a0588c5ac1..3f3192edb51fc 100644
--- a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
@@ -413,6 +413,24 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned 
BuiltinID,
     ID = Intrinsic::riscv_cv_alu_subuRN;
     break;
 
+  // XAndesPerf
+  case RISCV::BI__builtin_riscv_nds_ffb:
+    IntrinsicTypes = {ResultType};
+    ID = Intrinsic::riscv_nds_ffb;
+    break;
+  case RISCV::BI__builtin_riscv_nds_ffzmism:
+    IntrinsicTypes = {ResultType};
+    ID = Intrinsic::riscv_nds_ffzmism;
+    break;
+  case RISCV::BI__builtin_riscv_nds_ffmism:
+    IntrinsicTypes = {ResultType};
+    ID = Intrinsic::riscv_nds_ffmism;
+    break;
+  case RISCV::BI__builtin_riscv_nds_flmism:
+    IntrinsicTypes = {ResultType};
+    ID = Intrinsic::riscv_nds_flmism;
+    break;
+
   // XAndesBFHCvt
   case RISCV::BI__builtin_riscv_nds_fcvt_s_bf16:
     return Builder.CreateFPExt(Ops[0], FloatTy);
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index dd52498bbef4c..71c0ebbbe55bf 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -126,6 +126,7 @@ set(ppc_htm_files
 set(riscv_files
   riscv_bitmanip.h
   riscv_corev_alu.h
+  riscv_nds.h
   riscv_crypto.h
   riscv_nds.h
   riscv_ntlh.h
diff --git a/clang/lib/Headers/riscv_nds.h b/clang/lib/Headers/riscv_nds.h
index 5ccef00e332ed..bd1ea805dcbc8 100644
--- a/clang/lib/Headers/riscv_nds.h
+++ b/clang/lib/Headers/riscv_nds.h
@@ -14,6 +14,32 @@
 extern "C" {
 #endif
 
+#if defined(__riscv_xandesperf)
+
+#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_nds_ffb(unsigned long a,
+                                                          unsigned long b) {
+  return __builtin_riscv_nds_ffb(a, b);
+}
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_nds_ffzmism(unsigned long a,
+                                                              unsigned long b) 
{
+  return __builtin_riscv_nds_ffzmism(a, b);
+}
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_nds_ffmism(unsigned long a,
+                                                             unsigned long b) {
+  return __builtin_riscv_nds_ffmism(a, b);
+}
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_nds_flmism(unsigned long a,
+                                                             unsigned long b) {
+  return __builtin_riscv_nds_flmism(a, b);
+}
+
+#endif // defined(__riscv_xandesperf)
+
 #if defined(__riscv_xandesbfhcvt)
 
 #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
diff --git a/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api.c 
b/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api.c
new file mode 100644
index 0000000000000..ab872d13cc1ea
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api.c
@@ -0,0 +1,159 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple riscv32 -target-feature +xandesperf -emit-llvm %s 
-o - \
+// RUN:     | FileCheck %s --check-prefix=CHECK-RV32
+// RUN: %clang_cc1 -triple riscv64 -target-feature +xandesperf -emit-llvm %s 
-o - \
+// RUN:     | FileCheck %s --check-prefix=CHECK-RV64
+
+#include <riscv_nds.h>
+
+// CHECK-RV32-LABEL: @test_ffb(
+// CHECK-RV32-NEXT:  entry:
+// CHECK-RV32-NEXT:    [[A_ADDR_I:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[B_ADDR_I:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    store i32 [[TMP0]], ptr [[A_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    store i32 [[TMP1]], ptr [[B_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    [[TMP2:%.*]] = load i32, ptr [[A_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    [[TMP3:%.*]] = load i32, ptr [[B_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    [[TMP4:%.*]] = call i32 @llvm.riscv.nds.ffb.i32(i32 
[[TMP2]], i32 [[TMP3]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP4]]
+//
+// CHECK-RV64-LABEL: @test_ffb(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[A_ADDR_I:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[B_ADDR_I:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    store i64 [[TMP0]], ptr [[A_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    store i64 [[TMP1]], ptr [[B_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    [[TMP2:%.*]] = load i64, ptr [[A_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    [[TMP3:%.*]] = load i64, ptr [[B_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    [[TMP4:%.*]] = call i64 @llvm.riscv.nds.ffb.i64(i64 
[[TMP2]], i64 [[TMP3]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP4]]
+//
+long test_ffb(unsigned long a, unsigned long b) {
+  return __riscv_nds_ffb(a, b);
+}
+
+// CHECK-RV32-LABEL: @test_ffzmism(
+// CHECK-RV32-NEXT:  entry:
+// CHECK-RV32-NEXT:    [[A_ADDR_I:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[B_ADDR_I:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    store i32 [[TMP0]], ptr [[A_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    store i32 [[TMP1]], ptr [[B_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    [[TMP2:%.*]] = load i32, ptr [[A_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    [[TMP3:%.*]] = load i32, ptr [[B_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    [[TMP4:%.*]] = call i32 @llvm.riscv.nds.ffzmism.i32(i32 
[[TMP2]], i32 [[TMP3]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP4]]
+//
+// CHECK-RV64-LABEL: @test_ffzmism(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[A_ADDR_I:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[B_ADDR_I:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    store i64 [[TMP0]], ptr [[A_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    store i64 [[TMP1]], ptr [[B_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    [[TMP2:%.*]] = load i64, ptr [[A_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    [[TMP3:%.*]] = load i64, ptr [[B_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    [[TMP4:%.*]] = call i64 @llvm.riscv.nds.ffzmism.i64(i64 
[[TMP2]], i64 [[TMP3]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP4]]
+//
+long test_ffzmism(unsigned long a, unsigned long b) {
+  return __riscv_nds_ffzmism(a, b);
+}
+
+// CHECK-RV32-LABEL: @test_ffmism(
+// CHECK-RV32-NEXT:  entry:
+// CHECK-RV32-NEXT:    [[A_ADDR_I:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[B_ADDR_I:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    store i32 [[TMP0]], ptr [[A_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    store i32 [[TMP1]], ptr [[B_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    [[TMP2:%.*]] = load i32, ptr [[A_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    [[TMP3:%.*]] = load i32, ptr [[B_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    [[TMP4:%.*]] = call i32 @llvm.riscv.nds.ffmism.i32(i32 
[[TMP2]], i32 [[TMP3]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP4]]
+//
+// CHECK-RV64-LABEL: @test_ffmism(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[A_ADDR_I:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[B_ADDR_I:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    store i64 [[TMP0]], ptr [[A_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    store i64 [[TMP1]], ptr [[B_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    [[TMP2:%.*]] = load i64, ptr [[A_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    [[TMP3:%.*]] = load i64, ptr [[B_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    [[TMP4:%.*]] = call i64 @llvm.riscv.nds.ffmism.i64(i64 
[[TMP2]], i64 [[TMP3]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP4]]
+//
+long test_ffmism(unsigned long a, unsigned long b) {
+  return __riscv_nds_ffmism(a, b);
+}
+
+// CHECK-RV32-LABEL: @test_flmism(
+// CHECK-RV32-NEXT:  entry:
+// CHECK-RV32-NEXT:    [[A_ADDR_I:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[B_ADDR_I:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    store i32 [[TMP0]], ptr [[A_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    store i32 [[TMP1]], ptr [[B_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    [[TMP2:%.*]] = load i32, ptr [[A_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    [[TMP3:%.*]] = load i32, ptr [[B_ADDR_I]], align 4
+// CHECK-RV32-NEXT:    [[TMP4:%.*]] = call i32 @llvm.riscv.nds.flmism.i32(i32 
[[TMP2]], i32 [[TMP3]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP4]]
+//
+// CHECK-RV64-LABEL: @test_flmism(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[A_ADDR_I:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[B_ADDR_I:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    store i64 [[TMP0]], ptr [[A_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    store i64 [[TMP1]], ptr [[B_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    [[TMP2:%.*]] = load i64, ptr [[A_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    [[TMP3:%.*]] = load i64, ptr [[B_ADDR_I]], align 8
+// CHECK-RV64-NEXT:    [[TMP4:%.*]] = call i64 @llvm.riscv.nds.flmism.i64(i64 
[[TMP2]], i64 [[TMP3]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP4]]
+//
+long test_flmism(unsigned long a, unsigned long b) {
+  return __riscv_nds_flmism(a, b);
+}
diff --git a/clang/test/CodeGen/RISCV/riscv-xandesperf.c 
b/clang/test/CodeGen/RISCV/riscv-xandesperf.c
new file mode 100644
index 0000000000000..d4273b295ed46
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/riscv-xandesperf.c
@@ -0,0 +1,109 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple riscv32 -target-feature +xandesperf -emit-llvm %s 
-o - \
+// RUN:     | FileCheck %s --check-prefix=CHECK-RV32
+// RUN: %clang_cc1 -triple riscv64 -target-feature +xandesperf -emit-llvm %s 
-o - \
+// RUN:     | FileCheck %s --check-prefix=CHECK-RV64
+
+// CHECK-RV32-LABEL: @test_ffb(
+// CHECK-RV32-NEXT:  entry:
+// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.nds.ffb.i32(i32 
[[TMP0]], i32 [[TMP1]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP2]]
+//
+// CHECK-RV64-LABEL: @test_ffb(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP2:%.*]] = call i64 @llvm.riscv.nds.ffb.i64(i64 
[[TMP0]], i64 [[TMP1]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP2]]
+//
+long test_ffb(unsigned long a, unsigned long b) {
+  return __builtin_riscv_nds_ffb(a, b);
+}
+
+// CHECK-RV32-LABEL: @test_ffzmism(
+// CHECK-RV32-NEXT:  entry:
+// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.nds.ffzmism.i32(i32 
[[TMP0]], i32 [[TMP1]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP2]]
+//
+// CHECK-RV64-LABEL: @test_ffzmism(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP2:%.*]] = call i64 @llvm.riscv.nds.ffzmism.i64(i64 
[[TMP0]], i64 [[TMP1]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP2]]
+//
+long test_ffzmism(unsigned long a, unsigned long b) {
+  return __builtin_riscv_nds_ffzmism(a, b);
+}
+
+// CHECK-RV32-LABEL: @test_ffmism(
+// CHECK-RV32-NEXT:  entry:
+// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.nds.ffmism.i32(i32 
[[TMP0]], i32 [[TMP1]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP2]]
+//
+// CHECK-RV64-LABEL: @test_ffmism(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP2:%.*]] = call i64 @llvm.riscv.nds.ffmism.i64(i64 
[[TMP0]], i64 [[TMP1]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP2]]
+//
+long test_ffmism(unsigned long a, unsigned long b) {
+  return __builtin_riscv_nds_ffmism(a, b);
+}
+
+// CHECK-RV32-LABEL: @test_flmism(
+// CHECK-RV32-NEXT:  entry:
+// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-RV32-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.nds.flmism.i32(i32 
[[TMP0]], i32 [[TMP1]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP2]]
+//
+// CHECK-RV64-LABEL: @test_flmism(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
+// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
+// CHECK-RV64-NEXT:    [[TMP2:%.*]] = call i64 @llvm.riscv.nds.flmism.i64(i64 
[[TMP0]], i64 [[TMP1]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP2]]
+//
+long test_flmism(unsigned long a, unsigned long b) {
+  return __builtin_riscv_nds_flmism(a, b);
+}
diff --git a/llvm/include/llvm/IR/IntrinsicsRISCVXAndes.td 
b/llvm/include/llvm/IR/IntrinsicsRISCVXAndes.td
index 43f7f7e22fe94..9b7c7e7d4c73c 100644
--- a/llvm/include/llvm/IR/IntrinsicsRISCVXAndes.td
+++ b/llvm/include/llvm/IR/IntrinsicsRISCVXAndes.td
@@ -11,6 +11,20 @@
 
//===----------------------------------------------------------------------===//
 
 let TargetPrefix = "riscv" in {
+  // Andes Performance Extension
+  def int_riscv_nds_ffb     : Intrinsic<[llvm_anyint_ty],
+                                        [LLVMMatchType<0>, LLVMMatchType<0>],
+                                        [IntrNoMem, IntrSpeculatable]>;
+  def int_riscv_nds_ffzmism : Intrinsic<[llvm_anyint_ty],
+                                        [LLVMMatchType<0>, LLVMMatchType<0>],
+                                        [IntrNoMem, IntrSpeculatable]>;
+  def int_riscv_nds_ffmism  : Intrinsic<[llvm_anyint_ty],
+                                        [LLVMMatchType<0>, LLVMMatchType<0>],
+                                        [IntrNoMem, IntrSpeculatable]>;
+  def int_riscv_nds_flmism  : Intrinsic<[llvm_anyint_ty],
+                                        [LLVMMatchType<0>, LLVMMatchType<0>],
+                                        [IntrNoMem, IntrSpeculatable]>;
+
   // Andes Vector BFloat16 Conversion Extension
   def int_riscv_nds_vfwcvt_s_bf16 : RISCVConversionUnMasked;
   def int_riscv_nds_vfncvt_bf16_s : RISCVConversionUnMaskedRoundingMode;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td 
b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
index c75addd95b149..ab2eddf009817 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
@@ -780,6 +780,17 @@ def : Sh2AddPat<NDS_LEA_W_ZE>;
 def : Sh3AddPat<NDS_LEA_D_ZE>;
 } // Predicates = [HasVendorXAndesPerf, IsRV64]
 
+let Predicates = [HasVendorXAndesPerf] in {
+def : Pat<(XLenVT (int_riscv_nds_ffb (XLenVT GPR:$rs1), (XLenVT GPR:$rs2))),
+          (NDS_FFB GPR:$rs1, GPR:$rs2)>;
+def : Pat<(XLenVT (int_riscv_nds_ffzmism (XLenVT GPR:$rs1), (XLenVT 
GPR:$rs2))),
+          (NDS_FFZMISM GPR:$rs1, GPR:$rs2)>;
+def : Pat<(XLenVT (int_riscv_nds_ffmism (XLenVT GPR:$rs1), (XLenVT GPR:$rs2))),
+          (NDS_FFMISM GPR:$rs1, GPR:$rs2)>;
+def : Pat<(XLenVT (int_riscv_nds_flmism (XLenVT GPR:$rs1), (XLenVT GPR:$rs2))),
+          (NDS_FLMISM GPR:$rs1, GPR:$rs2)>;
+} // Predicates = [HasVendorXAndesPerf]
+
 let Predicates = [HasVendorXAndesBFHCvt] in {
 def : Pat<(fpextend (bf16 FPR16:$rs)),
           (NDS_FCVT_S_BF16 (bf16 FPR16:$rs))>;
diff --git a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll 
b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
index 5cabb8c53e261..4c8fd5617abc1 100644
--- a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
@@ -492,3 +492,50 @@ define i64 @sexti32_i64_2(i32 %a) {
   %1 = sext i32 %a to i64
   ret i64 %1
 }
+
+; NDS.FFB/NDS.FFZMISM/NDS.FFMISM/NDS.FLMISM
+
+declare i32 @llvm.riscv.nds.ffb.i32(i32, i32)
+declare i32 @llvm.riscv.nds.ffzmism.i32(i32, i32)
+declare i32 @llvm.riscv.nds.ffmism.i32(i32, i32)
+declare i32 @llvm.riscv.nds.flmism.i32(i32, i32)
+
+define i32 @ffb(i32 %a, i32 %b) nounwind {
+; CHECK-LABEL: ffb:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    nds.ffb a0, a0, a1
+; CHECK-NEXT:    ret
+entry:
+  %0 = call i32 @llvm.riscv.nds.ffb.i32(i32 %a, i32 %b)
+  ret i32 %0
+}
+
+define i32 @ffzmism(i32 %a, i32 %b) nounwind {
+; CHECK-LABEL: ffzmism:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    nds.ffzmism a0, a0, a1
+; CHECK-NEXT:    ret
+entry:
+  %0 = call i32 @llvm.riscv.nds.ffzmism.i32(i32 %a, i32 %b)
+  ret i32 %0
+}
+
+define i32 @ffmism(i32 %a, i32 %b) nounwind {
+; CHECK-LABEL: ffmism:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    nds.ffmism a0, a0, a1
+; CHECK-NEXT:    ret
+entry:
+  %0 = call i32 @llvm.riscv.nds.ffmism.i32(i32 %a, i32 %b)
+  ret i32 %0
+}
+
+define i32 @flmism(i32 %a, i32 %b) nounwind {
+; CHECK-LABEL: flmism:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    nds.flmism a0, a0, a1
+; CHECK-NEXT:    ret
+entry:
+  %0 = call i32 @llvm.riscv.nds.flmism.i32(i32 %a, i32 %b)
+  ret i32 %0
+}
diff --git a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll 
b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
index 98cda42665169..09815b81c1a48 100644
--- a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
@@ -389,3 +389,50 @@ define i64 @sexti32_i64_2(i32 signext %a) {
   %1 = sext i32 %a to i64
   ret i64 %1
 }
+
+; NDS.FFB/NDS.FFZMISM/NDS.FFMISM/NDS.FLMISM
+
+declare i64 @llvm.riscv.nds.ffb.i64(i64, i64)
+declare i64 @llvm.riscv.nds.ffzmism.i64(i64, i64)
+declare i64 @llvm.riscv.nds.ffmism.i64(i64, i64)
+declare i64 @llvm.riscv.nds.flmism.i64(i64, i64)
+
+define i64 @ffb(i64 %a, i64 %b) nounwind {
+; CHECK-LABEL: ffb:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    nds.ffb a0, a0, a1
+; CHECK-NEXT:    ret
+entry:
+  %0 = call i64 @llvm.riscv.nds.ffb.i64(i64 %a, i64 %b)
+  ret i64 %0
+}
+
+define i64 @ffzmism(i64 %a, i64 %b) nounwind {
+; CHECK-LABEL: ffzmism:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    nds.ffzmism a0, a0, a1
+; CHECK-NEXT:    ret
+entry:
+  %0 = call i64 @llvm.riscv.nds.ffzmism.i64(i64 %a, i64 %b)
+  ret i64 %0
+}
+
+define i64 @ffmism(i64 %a, i64 %b) nounwind {
+; CHECK-LABEL: ffmism:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    nds.ffmism a0, a0, a1
+; CHECK-NEXT:    ret
+entry:
+  %0 = call i64 @llvm.riscv.nds.ffmism.i64(i64 %a, i64 %b)
+  ret i64 %0
+}
+
+define i64 @flmism(i64 %a, i64 %b) nounwind {
+; CHECK-LABEL: flmism:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    nds.flmism a0, a0, a1
+; CHECK-NEXT:    ret
+entry:
+  %0 = call i64 @llvm.riscv.nds.flmism.i64(i64 %a, i64 %b)
+  ret i64 %0
+}

>From 97448a6fbe6c5e0f7e1be386216babb8494b0e76 Mon Sep 17 00:00:00 2001
From: Jim Lin <j...@andestech.com>
Date: Mon, 7 Jul 2025 13:19:38 +0800
Subject: [PATCH 2/4] Run mem2reg pass

---
 .../CodeGen/RISCV/riscv-xandesperf-c-api.c    | 130 +++---------------
 clang/test/CodeGen/RISCV/riscv-xandesperf.c   |  82 +++--------
 2 files changed, 36 insertions(+), 176 deletions(-)

diff --git a/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api.c 
b/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api.c
index ab872d13cc1ea..56a0dfacb80b5 100644
--- a/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api.c
+++ b/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api.c
@@ -1,44 +1,22 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
 // RUN: %clang_cc1 -triple riscv32 -target-feature +xandesperf -emit-llvm %s 
-o - \
+// RUN:     -disable-O0-optnone | opt -S -passes=mem2reg \
 // RUN:     | FileCheck %s --check-prefix=CHECK-RV32
 // RUN: %clang_cc1 -triple riscv64 -target-feature +xandesperf -emit-llvm %s 
-o - \
+// RUN:     -disable-O0-optnone | opt -S -passes=mem2reg \
 // RUN:     | FileCheck %s --check-prefix=CHECK-RV64
 
 #include <riscv_nds.h>
 
 // CHECK-RV32-LABEL: @test_ffb(
 // CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[A_ADDR_I:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[B_ADDR_I:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    store i32 [[TMP0]], ptr [[A_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    store i32 [[TMP1]], ptr [[B_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    [[TMP2:%.*]] = load i32, ptr [[A_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    [[TMP3:%.*]] = load i32, ptr [[B_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    [[TMP4:%.*]] = call i32 @llvm.riscv.nds.ffb.i32(i32 
[[TMP2]], i32 [[TMP3]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP4]]
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffb.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
 //
 // CHECK-RV64-LABEL: @test_ffb(
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[A_ADDR_I:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[B_ADDR_I:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    store i64 [[TMP0]], ptr [[A_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    store i64 [[TMP1]], ptr [[B_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    [[TMP2:%.*]] = load i64, ptr [[A_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    [[TMP3:%.*]] = load i64, ptr [[B_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    [[TMP4:%.*]] = call i64 @llvm.riscv.nds.ffb.i64(i64 
[[TMP2]], i64 [[TMP3]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP4]]
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffb.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
 //
 long test_ffb(unsigned long a, unsigned long b) {
   return __riscv_nds_ffb(a, b);
@@ -46,37 +24,13 @@ long test_ffb(unsigned long a, unsigned long b) {
 
 // CHECK-RV32-LABEL: @test_ffzmism(
 // CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[A_ADDR_I:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[B_ADDR_I:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    store i32 [[TMP0]], ptr [[A_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    store i32 [[TMP1]], ptr [[B_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    [[TMP2:%.*]] = load i32, ptr [[A_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    [[TMP3:%.*]] = load i32, ptr [[B_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    [[TMP4:%.*]] = call i32 @llvm.riscv.nds.ffzmism.i32(i32 
[[TMP2]], i32 [[TMP3]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP4]]
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffzmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
 //
 // CHECK-RV64-LABEL: @test_ffzmism(
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[A_ADDR_I:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[B_ADDR_I:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    store i64 [[TMP0]], ptr [[A_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    store i64 [[TMP1]], ptr [[B_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    [[TMP2:%.*]] = load i64, ptr [[A_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    [[TMP3:%.*]] = load i64, ptr [[B_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    [[TMP4:%.*]] = call i64 @llvm.riscv.nds.ffzmism.i64(i64 
[[TMP2]], i64 [[TMP3]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP4]]
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffzmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
 //
 long test_ffzmism(unsigned long a, unsigned long b) {
   return __riscv_nds_ffzmism(a, b);
@@ -84,37 +38,13 @@ long test_ffzmism(unsigned long a, unsigned long b) {
 
 // CHECK-RV32-LABEL: @test_ffmism(
 // CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[A_ADDR_I:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[B_ADDR_I:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    store i32 [[TMP0]], ptr [[A_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    store i32 [[TMP1]], ptr [[B_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    [[TMP2:%.*]] = load i32, ptr [[A_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    [[TMP3:%.*]] = load i32, ptr [[B_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    [[TMP4:%.*]] = call i32 @llvm.riscv.nds.ffmism.i32(i32 
[[TMP2]], i32 [[TMP3]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP4]]
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
 //
 // CHECK-RV64-LABEL: @test_ffmism(
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[A_ADDR_I:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[B_ADDR_I:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    store i64 [[TMP0]], ptr [[A_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    store i64 [[TMP1]], ptr [[B_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    [[TMP2:%.*]] = load i64, ptr [[A_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    [[TMP3:%.*]] = load i64, ptr [[B_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    [[TMP4:%.*]] = call i64 @llvm.riscv.nds.ffmism.i64(i64 
[[TMP2]], i64 [[TMP3]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP4]]
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
 //
 long test_ffmism(unsigned long a, unsigned long b) {
   return __riscv_nds_ffmism(a, b);
@@ -122,37 +52,13 @@ long test_ffmism(unsigned long a, unsigned long b) {
 
 // CHECK-RV32-LABEL: @test_flmism(
 // CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[A_ADDR_I:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[B_ADDR_I:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    store i32 [[TMP0]], ptr [[A_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    store i32 [[TMP1]], ptr [[B_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    [[TMP2:%.*]] = load i32, ptr [[A_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    [[TMP3:%.*]] = load i32, ptr [[B_ADDR_I]], align 4
-// CHECK-RV32-NEXT:    [[TMP4:%.*]] = call i32 @llvm.riscv.nds.flmism.i32(i32 
[[TMP2]], i32 [[TMP3]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP4]]
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.flmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
 //
 // CHECK-RV64-LABEL: @test_flmism(
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[A_ADDR_I:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[B_ADDR_I:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    store i64 [[TMP0]], ptr [[A_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    store i64 [[TMP1]], ptr [[B_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    [[TMP2:%.*]] = load i64, ptr [[A_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    [[TMP3:%.*]] = load i64, ptr [[B_ADDR_I]], align 8
-// CHECK-RV64-NEXT:    [[TMP4:%.*]] = call i64 @llvm.riscv.nds.flmism.i64(i64 
[[TMP2]], i64 [[TMP3]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP4]]
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.flmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
 //
 long test_flmism(unsigned long a, unsigned long b) {
   return __riscv_nds_flmism(a, b);
diff --git a/clang/test/CodeGen/RISCV/riscv-xandesperf.c 
b/clang/test/CodeGen/RISCV/riscv-xandesperf.c
index d4273b295ed46..4946c14709c80 100644
--- a/clang/test/CodeGen/RISCV/riscv-xandesperf.c
+++ b/clang/test/CodeGen/RISCV/riscv-xandesperf.c
@@ -1,30 +1,20 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
 // RUN: %clang_cc1 -triple riscv32 -target-feature +xandesperf -emit-llvm %s 
-o - \
+// RUN:     -disable-O0-optnone | opt -S -passes=mem2reg \
 // RUN:     | FileCheck %s --check-prefix=CHECK-RV32
 // RUN: %clang_cc1 -triple riscv64 -target-feature +xandesperf -emit-llvm %s 
-o - \
+// RUN:     -disable-O0-optnone | opt -S -passes=mem2reg \
 // RUN:     | FileCheck %s --check-prefix=CHECK-RV64
 
 // CHECK-RV32-LABEL: @test_ffb(
 // CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.nds.ffb.i32(i32 
[[TMP0]], i32 [[TMP1]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP2]]
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffb.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
 //
 // CHECK-RV64-LABEL: @test_ffb(
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP2:%.*]] = call i64 @llvm.riscv.nds.ffb.i64(i64 
[[TMP0]], i64 [[TMP1]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP2]]
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffb.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
 //
 long test_ffb(unsigned long a, unsigned long b) {
   return __builtin_riscv_nds_ffb(a, b);
@@ -32,25 +22,13 @@ long test_ffb(unsigned long a, unsigned long b) {
 
 // CHECK-RV32-LABEL: @test_ffzmism(
 // CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.nds.ffzmism.i32(i32 
[[TMP0]], i32 [[TMP1]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP2]]
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffzmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
 //
 // CHECK-RV64-LABEL: @test_ffzmism(
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP2:%.*]] = call i64 @llvm.riscv.nds.ffzmism.i64(i64 
[[TMP0]], i64 [[TMP1]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP2]]
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffzmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
 //
 long test_ffzmism(unsigned long a, unsigned long b) {
   return __builtin_riscv_nds_ffzmism(a, b);
@@ -58,25 +36,13 @@ long test_ffzmism(unsigned long a, unsigned long b) {
 
 // CHECK-RV32-LABEL: @test_ffmism(
 // CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.nds.ffmism.i32(i32 
[[TMP0]], i32 [[TMP1]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP2]]
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
 //
 // CHECK-RV64-LABEL: @test_ffmism(
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP2:%.*]] = call i64 @llvm.riscv.nds.ffmism.i64(i64 
[[TMP0]], i64 [[TMP1]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP2]]
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
 //
 long test_ffmism(unsigned long a, unsigned long b) {
   return __builtin_riscv_nds_ffmism(a, b);
@@ -84,25 +50,13 @@ long test_ffmism(unsigned long a, unsigned long b) {
 
 // CHECK-RV32-LABEL: @test_flmism(
 // CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
-// CHECK-RV32-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
-// CHECK-RV32-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.nds.flmism.i32(i32 
[[TMP0]], i32 [[TMP1]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP2]]
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.flmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
 //
 // CHECK-RV64-LABEL: @test_flmism(
 // CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    [[B_ADDR:%.*]] = alloca i64, align 8
-// CHECK-RV64-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    store i64 [[B:%.*]], ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[B_ADDR]], align 8
-// CHECK-RV64-NEXT:    [[TMP2:%.*]] = call i64 @llvm.riscv.nds.flmism.i64(i64 
[[TMP0]], i64 [[TMP1]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP2]]
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.flmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
 //
 long test_flmism(unsigned long a, unsigned long b) {
   return __builtin_riscv_nds_flmism(a, b);

>From ebdfb49ec4a5173ca139b5fd4c2924e538e2a185 Mon Sep 17 00:00:00 2001
From: Jim Lin <j...@andestech.com>
Date: Wed, 9 Jul 2025 09:16:23 +0800
Subject: [PATCH 3/4] Alphabetize the order of .h files

---
 clang/lib/Headers/CMakeLists.txt | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index 71c0ebbbe55bf..dd52498bbef4c 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -126,7 +126,6 @@ set(ppc_htm_files
 set(riscv_files
   riscv_bitmanip.h
   riscv_corev_alu.h
-  riscv_nds.h
   riscv_crypto.h
   riscv_nds.h
   riscv_ntlh.h

>From cb1cb36f3a53f942897ebf7709495cab3822b91b Mon Sep 17 00:00:00 2001
From: Jim Lin <j...@andestech.com>
Date: Tue, 5 Aug 2025 15:06:03 +0800
Subject: [PATCH 4/4] Update the prototypes for RV32 with uint32_t and for RV64
 with uint64_t

---
 .../clang/Basic/BuiltinsRISCVXAndes.td        | 17 +++--
 clang/lib/CodeGen/TargetBuiltins/RISCV.cpp    | 12 ++--
 clang/lib/Headers/riscv_nds.h                 | 58 ++++++++++++-----
 .../RISCV/riscv-xandesperf-c-api-rv32.c       | 43 ++++++++++++
 .../RISCV/riscv-xandesperf-c-api-rv64.c       | 43 ++++++++++++
 .../CodeGen/RISCV/riscv-xandesperf-c-api.c    | 65 -------------------
 .../CodeGen/RISCV/riscv-xandesperf-rv32.c     | 42 ++++++++++++
 .../CodeGen/RISCV/riscv-xandesperf-rv64.c     | 42 ++++++++++++
 clang/test/CodeGen/RISCV/riscv-xandesperf.c   | 63 ------------------
 9 files changed, 234 insertions(+), 151 deletions(-)
 create mode 100644 clang/test/CodeGen/RISCV/riscv-xandesperf-c-api-rv32.c
 create mode 100644 clang/test/CodeGen/RISCV/riscv-xandesperf-c-api-rv64.c
 delete mode 100644 clang/test/CodeGen/RISCV/riscv-xandesperf-c-api.c
 create mode 100644 clang/test/CodeGen/RISCV/riscv-xandesperf-rv32.c
 create mode 100644 clang/test/CodeGen/RISCV/riscv-xandesperf-rv64.c
 delete mode 100644 clang/test/CodeGen/RISCV/riscv-xandesperf.c

diff --git a/clang/include/clang/Basic/BuiltinsRISCVXAndes.td 
b/clang/include/clang/Basic/BuiltinsRISCVXAndes.td
index 789eb0ad8172d..7dda1b8d580d3 100644
--- a/clang/include/clang/Basic/BuiltinsRISCVXAndes.td
+++ b/clang/include/clang/Basic/BuiltinsRISCVXAndes.td
@@ -22,10 +22,19 @@ let Attributes = [NoThrow, Const] in {
 // XAndesPerf extension.
 
//===----------------------------------------------------------------------===//
 
-def ffb     : RISCVXAndesBuiltin<"long int(unsigned long int, unsigned long 
int)", "xandesperf">;
-def ffzmism : RISCVXAndesBuiltin<"long int(unsigned long int, unsigned long 
int)", "xandesperf">;
-def ffmism  : RISCVXAndesBuiltin<"long int(unsigned long int, unsigned long 
int)", "xandesperf">;
-def flmism  : RISCVXAndesBuiltin<"long int(unsigned long int, unsigned long 
int)", "xandesperf">;
+let Features = "xandesperf,32bit" in {
+def ffb_32     : RISCVXAndesBuiltin<"int32_t(uint32_t, uint32_t)">;
+def ffzmism_32 : RISCVXAndesBuiltin<"int32_t(uint32_t, uint32_t)">;
+def ffmism_32  : RISCVXAndesBuiltin<"int32_t(uint32_t, uint32_t)">;
+def flmism_32  : RISCVXAndesBuiltin<"int32_t(uint32_t, uint32_t)">;
+}
+
+let Features = "xandesperf,64bit" in {
+def ffb_64     : RISCVXAndesBuiltin<"int64_t(uint64_t, uint64_t)">;
+def ffzmism_64 : RISCVXAndesBuiltin<"int64_t(uint64_t, uint64_t)">;
+def ffmism_64  : RISCVXAndesBuiltin<"int64_t(uint64_t, uint64_t)">;
+def flmism_64  : RISCVXAndesBuiltin<"int64_t(uint64_t, uint64_t)">;
+}
 
 
//===----------------------------------------------------------------------===//
 // XAndesBFHCvt extension.
diff --git a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp 
b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
index 3f3192edb51fc..3ac2b91098f7a 100644
--- a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
@@ -414,19 +414,23 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned 
BuiltinID,
     break;
 
   // XAndesPerf
-  case RISCV::BI__builtin_riscv_nds_ffb:
+  case RISCV::BI__builtin_riscv_nds_ffb_32:
+  case RISCV::BI__builtin_riscv_nds_ffb_64:
     IntrinsicTypes = {ResultType};
     ID = Intrinsic::riscv_nds_ffb;
     break;
-  case RISCV::BI__builtin_riscv_nds_ffzmism:
+  case RISCV::BI__builtin_riscv_nds_ffzmism_32:
+  case RISCV::BI__builtin_riscv_nds_ffzmism_64:
     IntrinsicTypes = {ResultType};
     ID = Intrinsic::riscv_nds_ffzmism;
     break;
-  case RISCV::BI__builtin_riscv_nds_ffmism:
+  case RISCV::BI__builtin_riscv_nds_ffmism_32:
+  case RISCV::BI__builtin_riscv_nds_ffmism_64:
     IntrinsicTypes = {ResultType};
     ID = Intrinsic::riscv_nds_ffmism;
     break;
-  case RISCV::BI__builtin_riscv_nds_flmism:
+  case RISCV::BI__builtin_riscv_nds_flmism_32:
+  case RISCV::BI__builtin_riscv_nds_flmism_64:
     IntrinsicTypes = {ResultType};
     ID = Intrinsic::riscv_nds_flmism;
     break;
diff --git a/clang/lib/Headers/riscv_nds.h b/clang/lib/Headers/riscv_nds.h
index bd1ea805dcbc8..752dc3600587a 100644
--- a/clang/lib/Headers/riscv_nds.h
+++ b/clang/lib/Headers/riscv_nds.h
@@ -10,40 +10,68 @@
 #ifndef __RISCV_NDS_H
 #define __RISCV_NDS_H
 
+#include <stdint.h>
+
 #if defined(__cplusplus)
 extern "C" {
 #endif
 
+#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
+
 #if defined(__riscv_xandesperf)
 
-#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
+#if __riscv_xlen == 32
+
+static __inline__ int32_t __DEFAULT_FN_ATTRS __riscv_nds_ffb_32(uint32_t a,
+                                                                uint32_t b) {
+  return __builtin_riscv_nds_ffb_32(a, b);
+}
 
-static __inline__ long __DEFAULT_FN_ATTRS __riscv_nds_ffb(unsigned long a,
-                                                          unsigned long b) {
-  return __builtin_riscv_nds_ffb(a, b);
+static __inline__ int32_t __DEFAULT_FN_ATTRS __riscv_nds_ffzmism_32(uint32_t a,
+                                                                    uint32_t 
b) {
+  return __builtin_riscv_nds_ffzmism_32(a, b);
 }
 
-static __inline__ long __DEFAULT_FN_ATTRS __riscv_nds_ffzmism(unsigned long a,
-                                                              unsigned long b) 
{
-  return __builtin_riscv_nds_ffzmism(a, b);
+static __inline__ int32_t __DEFAULT_FN_ATTRS __riscv_nds_ffmism_32(uint32_t a,
+                                                                   uint32_t b) 
{
+  return __builtin_riscv_nds_ffmism_32(a, b);
 }
 
-static __inline__ long __DEFAULT_FN_ATTRS __riscv_nds_ffmism(unsigned long a,
-                                                             unsigned long b) {
-  return __builtin_riscv_nds_ffmism(a, b);
+static __inline__ int32_t __DEFAULT_FN_ATTRS __riscv_nds_flmism_32(uint32_t a,
+                                                                   uint32_t b) 
{
+  return __builtin_riscv_nds_flmism_32(a, b);
 }
 
-static __inline__ long __DEFAULT_FN_ATTRS __riscv_nds_flmism(unsigned long a,
-                                                             unsigned long b) {
-  return __builtin_riscv_nds_flmism(a, b);
+#endif
+
+#if __riscv_xlen == 64
+
+static __inline__ int64_t __DEFAULT_FN_ATTRS __riscv_nds_ffb_64(uint64_t a,
+                                                                uint64_t b) {
+  return __builtin_riscv_nds_ffb_64(a, b);
 }
 
+static __inline__ int64_t __DEFAULT_FN_ATTRS __riscv_nds_ffzmism_64(uint64_t a,
+                                                                    uint64_t 
b) {
+  return __builtin_riscv_nds_ffzmism_64(a, b);
+}
+
+static __inline__ int64_t __DEFAULT_FN_ATTRS __riscv_nds_ffmism_64(uint64_t a,
+                                                                   uint64_t b) 
{
+  return __builtin_riscv_nds_ffmism_64(a, b);
+}
+
+static __inline__ int64_t __DEFAULT_FN_ATTRS __riscv_nds_flmism_64(uint64_t a,
+                                                                   uint64_t b) 
{
+  return __builtin_riscv_nds_flmism_64(a, b);
+}
+
+#endif
+
 #endif // defined(__riscv_xandesperf)
 
 #if defined(__riscv_xandesbfhcvt)
 
-#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
-
 static __inline__ float __DEFAULT_FN_ATTRS __riscv_nds_fcvt_s_bf16(__bf16 bf) {
   return __builtin_riscv_nds_fcvt_s_bf16(bf);
 }
diff --git a/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api-rv32.c 
b/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api-rv32.c
new file mode 100644
index 0000000000000..0ca9947ebb1ea
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api-rv32.c
@@ -0,0 +1,43 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple riscv32 -target-feature +xandesperf -emit-llvm %s 
-o - \
+// RUN:     -disable-O0-optnone | opt -S -passes=mem2reg \
+// RUN:     | FileCheck %s
+
+#include <stdint.h>
+#include <riscv_nds.h>
+
+// CHECK-LABEL: @test_ffb(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffb.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-NEXT:    ret i32 [[TMP0]]
+//
+int32_t test_ffb(uint32_t a, uint32_t b) {
+  return __riscv_nds_ffb_32(a, b);
+}
+
+// CHECK-LABEL: @test_ffzmism(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffzmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-NEXT:    ret i32 [[TMP0]]
+//
+int32_t test_ffzmism(uint32_t a, uint32_t b) {
+  return __riscv_nds_ffzmism_32(a, b);
+}
+
+// CHECK-LABEL: @test_ffmism(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-NEXT:    ret i32 [[TMP0]]
+//
+int32_t test_ffmism(uint32_t a, uint32_t b) {
+  return __riscv_nds_ffmism_32(a, b);
+}
+
+// CHECK-LABEL: @test_flmism(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.flmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-NEXT:    ret i32 [[TMP0]]
+//
+int32_t test_flmism(uint32_t a, uint32_t b) {
+  return __riscv_nds_flmism_32(a, b);
+}
diff --git a/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api-rv64.c 
b/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api-rv64.c
new file mode 100644
index 0000000000000..8e507724e2fbc
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api-rv64.c
@@ -0,0 +1,43 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple riscv64 -target-feature +xandesperf -emit-llvm %s 
-o - \
+// RUN:     -disable-O0-optnone | opt -S -passes=mem2reg \
+// RUN:     | FileCheck %s
+
+#include <stdint.h>
+#include <riscv_nds.h>
+
+// CHECK-LABEL: @test_ffb(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffb.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-NEXT:    ret i64 [[TMP0]]
+//
+int64_t test_ffb(uint64_t a, uint64_t b) {
+  return __riscv_nds_ffb_64(a, b);
+}
+
+// CHECK-LABEL: @test_ffzmism(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffzmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-NEXT:    ret i64 [[TMP0]]
+//
+int64_t test_ffzmism(uint64_t a, uint64_t b) {
+  return __riscv_nds_ffzmism_64(a, b);
+}
+
+// CHECK-LABEL: @test_ffmism(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-NEXT:    ret i64 [[TMP0]]
+//
+int64_t test_ffmism(uint64_t a, uint64_t b) {
+  return __riscv_nds_ffmism_64(a, b);
+}
+
+// CHECK-LABEL: @test_flmism(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.flmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-NEXT:    ret i64 [[TMP0]]
+//
+int64_t test_flmism(uint64_t a, uint64_t b) {
+  return __riscv_nds_flmism_64(a, b);
+}
diff --git a/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api.c 
b/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api.c
deleted file mode 100644
index 56a0dfacb80b5..0000000000000
--- a/clang/test/CodeGen/RISCV/riscv-xandesperf-c-api.c
+++ /dev/null
@@ -1,65 +0,0 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
-// RUN: %clang_cc1 -triple riscv32 -target-feature +xandesperf -emit-llvm %s 
-o - \
-// RUN:     -disable-O0-optnone | opt -S -passes=mem2reg \
-// RUN:     | FileCheck %s --check-prefix=CHECK-RV32
-// RUN: %clang_cc1 -triple riscv64 -target-feature +xandesperf -emit-llvm %s 
-o - \
-// RUN:     -disable-O0-optnone | opt -S -passes=mem2reg \
-// RUN:     | FileCheck %s --check-prefix=CHECK-RV64
-
-#include <riscv_nds.h>
-
-// CHECK-RV32-LABEL: @test_ffb(
-// CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffb.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
-//
-// CHECK-RV64-LABEL: @test_ffb(
-// CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffb.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
-//
-long test_ffb(unsigned long a, unsigned long b) {
-  return __riscv_nds_ffb(a, b);
-}
-
-// CHECK-RV32-LABEL: @test_ffzmism(
-// CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffzmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
-//
-// CHECK-RV64-LABEL: @test_ffzmism(
-// CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffzmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
-//
-long test_ffzmism(unsigned long a, unsigned long b) {
-  return __riscv_nds_ffzmism(a, b);
-}
-
-// CHECK-RV32-LABEL: @test_ffmism(
-// CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
-//
-// CHECK-RV64-LABEL: @test_ffmism(
-// CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
-//
-long test_ffmism(unsigned long a, unsigned long b) {
-  return __riscv_nds_ffmism(a, b);
-}
-
-// CHECK-RV32-LABEL: @test_flmism(
-// CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.flmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
-//
-// CHECK-RV64-LABEL: @test_flmism(
-// CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.flmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
-//
-long test_flmism(unsigned long a, unsigned long b) {
-  return __riscv_nds_flmism(a, b);
-}
diff --git a/clang/test/CodeGen/RISCV/riscv-xandesperf-rv32.c 
b/clang/test/CodeGen/RISCV/riscv-xandesperf-rv32.c
new file mode 100644
index 0000000000000..ee21879cd8d02
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/riscv-xandesperf-rv32.c
@@ -0,0 +1,42 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple riscv32 -target-feature +xandesperf -emit-llvm %s 
-o - \
+// RUN:     -disable-O0-optnone | opt -S -passes=mem2reg \
+// RUN:     | FileCheck %s --check-prefix=CHECK-RV32
+
+#include <stdint.h>
+
+// CHECK-RV32-LABEL: @test_ffb(
+// CHECK-RV32-NEXT:  entry:
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffb.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
+//
+int32_t test_ffb(uint32_t a, uint32_t b) {
+  return __builtin_riscv_nds_ffb_32(a, b);
+}
+
+// CHECK-RV32-LABEL: @test_ffzmism(
+// CHECK-RV32-NEXT:  entry:
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffzmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
+//
+int32_t test_ffzmism(uint32_t a, uint32_t b) {
+  return __builtin_riscv_nds_ffzmism_32(a, b);
+}
+
+// CHECK-RV32-LABEL: @test_ffmism(
+// CHECK-RV32-NEXT:  entry:
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
+//
+int32_t test_ffmism(uint32_t a, uint32_t b) {
+  return __builtin_riscv_nds_ffmism_32(a, b);
+}
+
+// CHECK-RV32-LABEL: @test_flmism(
+// CHECK-RV32-NEXT:  entry:
+// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.flmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
+// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
+//
+int32_t test_flmism(uint32_t a, uint32_t b) {
+  return __builtin_riscv_nds_flmism_32(a, b);
+}
diff --git a/clang/test/CodeGen/RISCV/riscv-xandesperf-rv64.c 
b/clang/test/CodeGen/RISCV/riscv-xandesperf-rv64.c
new file mode 100644
index 0000000000000..9cb215aced359
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/riscv-xandesperf-rv64.c
@@ -0,0 +1,42 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple riscv64 -target-feature +xandesperf -emit-llvm %s 
-o - \
+// RUN:     -disable-O0-optnone | opt -S -passes=mem2reg \
+// RUN:     | FileCheck %s --check-prefix=CHECK-RV64
+
+#include <stdint.h>
+
+// CHECK-RV64-LABEL: @test_ffb(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffb.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
+//
+int64_t test_ffb(uint64_t a, uint64_t b) {
+  return __builtin_riscv_nds_ffb_64(a, b);
+}
+
+// CHECK-RV64-LABEL: @test_ffzmism(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffzmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
+//
+int64_t test_ffzmism(uint64_t a, uint64_t b) {
+  return __builtin_riscv_nds_ffzmism_64(a, b);
+}
+
+// CHECK-RV64-LABEL: @test_ffmism(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
+//
+int64_t test_ffmism(uint64_t a, uint64_t b) {
+  return __builtin_riscv_nds_ffmism_64(a, b);
+}
+
+// CHECK-RV64-LABEL: @test_flmism(
+// CHECK-RV64-NEXT:  entry:
+// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.flmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
+// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
+//
+int64_t test_flmism(uint64_t a, uint64_t b) {
+  return __builtin_riscv_nds_flmism_64(a, b);
+}
diff --git a/clang/test/CodeGen/RISCV/riscv-xandesperf.c 
b/clang/test/CodeGen/RISCV/riscv-xandesperf.c
deleted file mode 100644
index 4946c14709c80..0000000000000
--- a/clang/test/CodeGen/RISCV/riscv-xandesperf.c
+++ /dev/null
@@ -1,63 +0,0 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
-// RUN: %clang_cc1 -triple riscv32 -target-feature +xandesperf -emit-llvm %s 
-o - \
-// RUN:     -disable-O0-optnone | opt -S -passes=mem2reg \
-// RUN:     | FileCheck %s --check-prefix=CHECK-RV32
-// RUN: %clang_cc1 -triple riscv64 -target-feature +xandesperf -emit-llvm %s 
-o - \
-// RUN:     -disable-O0-optnone | opt -S -passes=mem2reg \
-// RUN:     | FileCheck %s --check-prefix=CHECK-RV64
-
-// CHECK-RV32-LABEL: @test_ffb(
-// CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffb.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
-//
-// CHECK-RV64-LABEL: @test_ffb(
-// CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffb.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
-//
-long test_ffb(unsigned long a, unsigned long b) {
-  return __builtin_riscv_nds_ffb(a, b);
-}
-
-// CHECK-RV32-LABEL: @test_ffzmism(
-// CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffzmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
-//
-// CHECK-RV64-LABEL: @test_ffzmism(
-// CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffzmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
-//
-long test_ffzmism(unsigned long a, unsigned long b) {
-  return __builtin_riscv_nds_ffzmism(a, b);
-}
-
-// CHECK-RV32-LABEL: @test_ffmism(
-// CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.ffmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
-//
-// CHECK-RV64-LABEL: @test_ffmism(
-// CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.ffmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
-//
-long test_ffmism(unsigned long a, unsigned long b) {
-  return __builtin_riscv_nds_ffmism(a, b);
-}
-
-// CHECK-RV32-LABEL: @test_flmism(
-// CHECK-RV32-NEXT:  entry:
-// CHECK-RV32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.riscv.nds.flmism.i32(i32 
[[A:%.*]], i32 [[B:%.*]])
-// CHECK-RV32-NEXT:    ret i32 [[TMP0]]
-//
-// CHECK-RV64-LABEL: @test_flmism(
-// CHECK-RV64-NEXT:  entry:
-// CHECK-RV64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.riscv.nds.flmism.i64(i64 
[[A:%.*]], i64 [[B:%.*]])
-// CHECK-RV64-NEXT:    ret i64 [[TMP0]]
-//
-long test_flmism(unsigned long a, unsigned long b) {
-  return __builtin_riscv_nds_flmism(a, b);
-}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to