[clang] [clang][clangIR]: Implement builtin x86 arch cpu detection. (PR #212143)

Lucas Ribeiro via cfe-commits cfe-commits at lists.llvm.org
Sun Jul 26 11:56:08 PDT 2026


https://github.com/lucaslive974 created https://github.com/llvm/llvm-project/pull/212143

This PR implements x86 CPU feature detection builtins for ClangIR.

Adresses #167765


>From d753ffccce3c7536e83c838d79a02796063826b7 Mon Sep 17 00:00:00 2001
From: lucaslive974 <lucasribeirolima974 at gmail.com>
Date: Fri, 24 Jul 2026 16:32:52 -0300
Subject: [PATCH] [clang][clangIR]: Implement builtin x86 arch cpu detection.

---
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp    |  174 +-
 .../X86/builtin-cpu-is-cputype.c              |  440 ++++
 .../X86/builtin-cpu-is-subtype.c              |  792 ++++++
 .../X86/builtin-cpu-is-vendor.c               |   71 +
 .../X86/builtin-cpu-supports-all.c            | 2193 +++++++++++++++++
 .../X86/builtin-cpu-supports.c                |  222 ++
 6 files changed, 3880 insertions(+), 12 deletions(-)
 create mode 100644 clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-is-cputype.c
 create mode 100644 clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-is-subtype.c
 create mode 100644 clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-is-vendor.c
 create mode 100644 clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-supports-all.c
 create mode 100644 clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-supports.c

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 2369c654833cf..9f7307f3cb1e5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -26,6 +26,7 @@
 #include "clang/CIR/MissingFeatures.h"
 #include "llvm/ADT/Sequence.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/TargetParser/X86TargetParser.h"
 #include <string>
 
 using namespace clang;
@@ -908,21 +909,170 @@ static mlir::Value emitX86PackedByteShift(CIRGenBuilderTy &builder,
   return shuffleResult;
 }
 
-std::optional<mlir::Value>
-CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) {
-  if (builtinID == Builtin::BI__builtin_cpu_is) {
-    cgm.errorNYI(expr->getSourceRange(), "__builtin_cpu_is");
-    return mlir::Value{};
-  }
-  if (builtinID == Builtin::BI__builtin_cpu_supports) {
-    cgm.errorNYI(expr->getSourceRange(), "__builtin_cpu_supports");
-    return mlir::Value{};
+static mlir::Value emitX86CpuInit(CIRGenModule &module,
+                                  CIRGenBuilderTy &builder,
+                                  mlir::Location loc) {
+  cir::VoidType voidTy = builder.getVoidTy();
+  cir::FuncType fnTy = builder.getFuncType({}, voidTy);
+
+  cir::FuncOp fn = module.createRuntimeFunction(fnTy, "__cpu_indicator_init");
+  fn.setDsoLocal(true);
+  fn.setBuiltin(true);
+
+  return builder.createCallOp(loc, fn, mlir::ValueRange{}).getResult();
+}
+
+// Matching the struct layout from the compiler-rt/libgcc structure that is
+// filled in:
+// unsigned int __cpu_vendor;
+// unsigned int __cpu_type;
+// unsigned int __cpu_subtype;
+// unsigned int __cpu_features[1];
+static cir::GetGlobalOp getX86CpuModelGlobalRecord(CIRGenModule &module,
+                                                   CIRGenBuilderTy &builder,
+                                                   mlir::Location loc) {
+  auto u32iTy = builder.getUInt32Ty();
+  auto arrTy = cir::ArrayType::get(u32iTy, /**size=*/1);
+  cir::StructType sTy =
+      builder.getAnonRecordTy({u32iTy, u32iTy, u32iTy, arrTy});
+
+  cir::GlobalOp cpuModel;
+  if (auto it = module.symbolLookupCache.find("__cpu_model");
+      it == module.symbolLookupCache.end()) {
+    cpuModel = module.createGlobalOp(loc, "__cpu_model", sTy);
+    cpuModel.setDSOLocal(true);
+  } else
+    cpuModel = cast<cir::GlobalOp>(it->second);
+
+  return builder.createGetGlobal(cpuModel);
+}
+
+static mlir::Value emitX86CpuIs(CIRGenModule &module, CIRGenBuilderTy &builder,
+                                mlir::Location loc, llvm::StringRef cpuStr) {
+  // Calculate the index needed to access the correct field based on the
+  // range. ABI_VALUE matches with compiler-rt/libgcc values.
+  auto [index, abiValue, member] =
+      mlir::StringSwitch<std::tuple<unsigned, unsigned, llvm::StringRef>>(
+          cpuStr)
+#define X86_VENDOR(ENUM, STR, ABI_VALUE)                                       \
+  .Case(STR, {0u, ABI_VALUE, "__cpu_vendor"})
+#define X86_CPU_TYPE(ENUM, STR, ABI_VALUE)                                     \
+  .Case(STR, {1u, ABI_VALUE, "__cpu_type"})
+#define X86_CPU_SUBTYPE(ENUM, STR, ABI_VALUE)                                  \
+  .Case(STR, {2u, ABI_VALUE, "__cpu_subtype"})
+#include "llvm/TargetParser/X86TargetParser.def"
+          .Default({0, 0, ""});
+  assert(abiValue != 0 && "Invalid CPUStr passed to CpuIs");
+
+  auto u32iTy = builder.getUInt32Ty();
+
+  cir::GetGlobalOp cpuModel = getX86CpuModelGlobalRecord(module, builder, loc);
+  cir::GetMemberOp cpuValue = builder.createGetMember(
+      loc, builder.getPointerTo(u32iTy), cpuModel, member, index);
+  mlir::Value value = builder.createAlignedLoad(loc, u32iTy, cpuValue,
+                                                CharUnits::fromQuantity(4));
+
+  return builder.createCompare(loc, cir::CmpOpKind::eq, value,
+                               /**rhs=*/builder.getUInt32(abiValue, loc));
+}
+
+// Matching the struct layout from the compiler-rt/libgcc structure that is
+// filled in:
+// unsigned int __features2[3];
+static cir::GetGlobalOp getX86CpuFeature2GlobalRecord(CIRGenModule &module,
+                                                      CIRGenBuilderTy &builder,
+                                                      mlir::Location loc) {
+  auto u32iTy = builder.getUInt32Ty();
+  auto arrTy = cir::ArrayType::get(u32iTy, /**size=*/3);
+
+  cir::GlobalOp cpuFeatures;
+  if (auto it = module.symbolLookupCache.find("__cpu_features2");
+      it == module.symbolLookupCache.end()) {
+    cpuFeatures = module.createGlobalOp(loc, "__cpu_features2", arrTy);
+    cpuFeatures.setDSOLocal(true);
+  } else
+    cpuFeatures = cast<cir::GlobalOp>(it->second);
+
+  return builder.createGetGlobal(cpuFeatures);
+}
+
+static mlir::Value emitX86CpuSupports(CIRGenModule &module,
+                                      CIRGenBuilderTy &builder,
+                                      mlir::Location loc,
+                                      llvm::StringRef featureStr) {
+  if (!module.getASTContext().getTargetInfo().validateCpuSupports(featureStr))
+    return builder.getFalse(loc);
+
+  std::array<uint32_t, 4> cpuSupportMask =
+      llvm::X86::getCpuSupportsMask(featureStr);
+
+  auto u32iTy = builder.getUInt32Ty();
+  auto arrTy = cir::ArrayType::get(u32iTy, 1);
+  auto aligmentUnit = CharUnits::fromQuantity(4);
+
+  mlir::Value result = builder.getTrue(loc);
+  if (cpuSupportMask[0] != 0) {
+    cir::GetGlobalOp cpuModel =
+        getX86CpuModelGlobalRecord(module, builder, loc);
+    cir::GetMemberOp cpuFeatureArr = builder.createGetMember(
+        loc, builder.getPointerTo(arrTy), cpuModel, "__cpu_feature", 3);
+
+    mlir::Value feature0Ptr =
+        builder.getArrayElement(loc, loc, cpuFeatureArr, u32iTy,
+                                /**idx=*/builder.getUInt32(0, loc),
+                                /**shouldDecay=*/false);
+    cir::LoadOp feature0 =
+        builder.createAlignedLoad(loc, u32iTy, feature0Ptr, aligmentUnit);
+
+    cir::ConstantOp mask = builder.getUInt32(cpuSupportMask[0], loc);
+    mlir::Value bitset = builder.createAnd(loc, feature0, mask);
+    mlir::Value cmp =
+        builder.createCompare(loc, cir::CmpOpKind::eq, bitset, mask);
+
+    result = builder.createAnd(loc, result, cmp);
   }
-  if (builtinID == Builtin::BI__builtin_cpu_init) {
-    cgm.errorNYI(expr->getSourceRange(), "__builtin_cpu_init");
-    return mlir::Value{};
+
+  cir::GetGlobalOp cpuFeature2Arr =
+      getX86CpuFeature2GlobalRecord(module, builder, loc);
+  for (unsigned idx : llvm::seq(1, 4)) {
+    const uint32_t featureMask = cpuSupportMask[idx];
+    if (!featureMask)
+      continue;
+
+    auto featurePtr =
+        builder.getArrayElement(loc, loc, cpuFeature2Arr, u32iTy,
+                                /**idx=*/builder.getUInt32(idx - 1, loc),
+                                /**shouldDecay=*/true);
+    mlir::Value feature =
+        builder.createAlignedLoad(loc, u32iTy, featurePtr, aligmentUnit);
+
+    cir::ConstantOp mask = builder.getUInt32(featureMask, loc);
+    mlir::Value bitset = builder.createAnd(loc, feature, mask);
+    mlir::Value cmp =
+        builder.createCompare(loc, cir::CmpOpKind::eq, bitset, mask);
+
+    result = builder.createAnd(loc, result, cmp);
   }
 
+  return result;
+}
+
+static llvm::StringRef getX86CpuString(const CallExpr *expr) {
+  const Expr *cpuExpr = expr->getArg(0)->IgnoreParenCasts();
+  return cast<clang::StringLiteral>(cpuExpr)->getString();
+}
+
+std::optional<mlir::Value>
+CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) {
+  if (builtinID == Builtin::BI__builtin_cpu_is)
+    return emitX86CpuIs(cgm, builder, getLoc(expr->getExprLoc()),
+                        getX86CpuString(expr));
+  if (builtinID == Builtin::BI__builtin_cpu_supports)
+    return emitX86CpuSupports(cgm, builder, getLoc(expr->getExprLoc()),
+                              getX86CpuString(expr));
+  if (builtinID == Builtin::BI__builtin_cpu_init)
+    return emitX86CpuInit(cgm, builder, getLoc(expr->getExprLoc()));
+
   // Handle MSVC intrinsics before argument evaluation to prevent double
   // evaluation.
   assert(!cir::MissingFeatures::msvcBuiltins());
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-is-cputype.c b/clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-is-cputype.c
new file mode 100644
index 0000000000000..2920120f0e521
--- /dev/null
+++ b/clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-is-cputype.c
@@ -0,0 +1,440 @@
+// RUN: %clang_cc1 -x c -ffreestanding -triple x86_64-unknown-linux -Wno-implicit-function-declaration -fclangir -emit-cir -o %t.cir %s
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+
+// RUN: %clang_cc1 -x c -ffreestanding -triple x86_64-unknown-linux -Wno-implicit-function-declaration -fclangir -emit-llvm -o %t.ll %s
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
+
+// RUN: %clang_cc1 -ffreestanding -triple=x86_64-pc-linux-gnu -emit-llvm -Wall -Werror %s -o - | FileCheck %s -check-prefix=OGCG
+
+// Test that __builtin_cpu_is emits the correct ABI value for every CPU type,
+// in llvm/include/llvm/TargetParser/X86TargetParser.def.
+extern void a(const char *);
+
+// CIR: !rec_anon_struct = !cir.struct<{!u32i, !u32i, !u32i, !cir.array<!u32i x 1>}>
+// CIR: cir.global "private" external dso_local @__cpu_model : !rec_anon_struct
+// LLVM: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
+// OGCG: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
+
+#define TEST_CPU_IS(NAME, STR)                                                 \
+  void test_##NAME(void) {                                                     \
+    if (__builtin_cpu_is(STR))                                                 \
+      a(STR);                                                                  \
+  }
+
+// CIR-LABEL: cir.func no_inline dso_local @test_bonnell(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_bonnell(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 1
+
+// OGCG-LABEL: define{{.*}} void @test_bonnell(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 1
+TEST_CPU_IS(bonnell, "bonnell")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_core2(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_core2(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 2
+
+// OGCG-LABEL: define{{.*}} void @test_core2(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 2
+TEST_CPU_IS(core2, "core2")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_corei7(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<3> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_corei7(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 3
+
+// OGCG-LABEL: define{{.*}} void @test_corei7(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 3
+TEST_CPU_IS(corei7, "corei7")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amdfam10h(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<4> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_amdfam10h(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 4
+
+// OGCG-LABEL: define{{.*}} void @test_amdfam10h(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 4
+TEST_CPU_IS(amdfam10h, "amdfam10h")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amdfam15h(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<5> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_amdfam15h(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 5
+
+// OGCG-LABEL: define{{.*}} void @test_amdfam15h(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 5
+TEST_CPU_IS(amdfam15h, "amdfam15h")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_silvermont(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<6> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_silvermont(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 6
+
+// OGCG-LABEL: define{{.*}} void @test_silvermont(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 6
+TEST_CPU_IS(silvermont, "silvermont")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_knl(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<7> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_knl(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 7
+
+// OGCG-LABEL: define{{.*}} void @test_knl(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 7
+TEST_CPU_IS(knl, "knl")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_btver1(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<8> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_btver1(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 8
+
+// OGCG-LABEL: define{{.*}} void @test_btver1(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 8
+TEST_CPU_IS(btver1, "btver1")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_btver2(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<9> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_btver2(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 9
+
+// OGCG-LABEL: define{{.*}} void @test_btver2(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 9
+TEST_CPU_IS(btver2, "btver2")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amdfam17h(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<10> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_amdfam17h(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 10
+
+// OGCG-LABEL: define{{.*}} void @test_amdfam17h(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 10
+TEST_CPU_IS(amdfam17h, "amdfam17h")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_knm(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<11> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_knm(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 11
+
+// OGCG-LABEL: define{{.*}} void @test_knm(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 11
+TEST_CPU_IS(knm, "knm")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_goldmont(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<12> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_goldmont(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 12
+
+// OGCG-LABEL: define{{.*}} void @test_goldmont(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 12
+TEST_CPU_IS(goldmont, "goldmont")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_goldmont_plus(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<13> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_goldmont_plus(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 13
+
+// OGCG-LABEL: define{{.*}} void @test_goldmont_plus(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 13
+TEST_CPU_IS(goldmont_plus, "goldmont-plus")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_tremont(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<14> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_tremont(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 14
+
+// OGCG-LABEL: define{{.*}} void @test_tremont(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 14
+TEST_CPU_IS(tremont, "tremont")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amdfam19h(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<15> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_amdfam19h(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 15
+
+// OGCG-LABEL: define{{.*}} void @test_amdfam19h(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 15
+TEST_CPU_IS(amdfam19h, "amdfam19h")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_zhaoxin_fam7h(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<16> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_zhaoxin_fam7h(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 16
+
+// OGCG-LABEL: define{{.*}} void @test_zhaoxin_fam7h(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 16
+TEST_CPU_IS(zhaoxin_fam7h, "zhaoxin_fam7h")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_sierraforest(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<17> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_sierraforest(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 17
+
+// OGCG-LABEL: define{{.*}} void @test_sierraforest(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 17
+TEST_CPU_IS(sierraforest, "sierraforest")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_grandridge(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<18> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_grandridge(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 18
+
+// OGCG-LABEL: define{{.*}} void @test_grandridge(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 18
+TEST_CPU_IS(grandridge, "grandridge")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_clearwaterforest(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<19> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_clearwaterforest(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 19
+
+// OGCG-LABEL: define{{.*}} void @test_clearwaterforest(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 19
+TEST_CPU_IS(clearwaterforest, "clearwaterforest")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amdfam1ah(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<20> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_amdfam1ah(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 20
+
+// OGCG-LABEL: define{{.*}} void @test_amdfam1ah(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 20
+TEST_CPU_IS(amdfam1ah, "amdfam1ah")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_hygonfam18h(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<21> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_hygonfam18h(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 21
+
+// OGCG-LABEL: define{{.*}} void @test_hygonfam18h(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 21
+TEST_CPU_IS(hygonfam18h, "hygonfam18h")
+
+// Aliases
+// CIR-LABEL: cir.func no_inline dso_local @test_atom(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_atom(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 1
+
+// OGCG-LABEL: define{{.*}} void @test_atom(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 1
+TEST_CPU_IS(atom, "atom")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amdfam10(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<4> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_amdfam10(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 4
+
+// OGCG-LABEL: define{{.*}} void @test_amdfam10(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 4
+TEST_CPU_IS(amdfam10, "amdfam10")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amdfam15(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<5> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_amdfam15(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 5
+
+// OGCG-LABEL: define{{.*}} void @test_amdfam15(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 5
+TEST_CPU_IS(amdfam15, "amdfam15")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_slm(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<6> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_slm(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 6
+
+// OGCG-LABEL: define{{.*}} void @test_slm(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 6
+TEST_CPU_IS(slm, "slm")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amdfam1a(
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][1] {name = "__cpu_type"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<20> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_amdfam1a(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// LLVM: = icmp eq i32 [[LOAD]], 20
+
+// OGCG-LABEL: define{{.*}} void @test_amdfam1a(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 4)
+// OGCG: = icmp eq i32 [[LOAD]], 20
+TEST_CPU_IS(amdfam1a, "amdfam1a")
+
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-is-subtype.c b/clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-is-subtype.c
new file mode 100644
index 0000000000000..efff891331da1
--- /dev/null
+++ b/clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-is-subtype.c
@@ -0,0 +1,792 @@
+// RUN: %clang_cc1 -x c -ffreestanding -triple x86_64-unknown-linux -Wno-implicit-function-declaration -fclangir -emit-cir -o %t.cir %s
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+
+// RUN: %clang_cc1 -x c -ffreestanding -triple x86_64-unknown-linux -Wno-implicit-function-declaration -fclangir -emit-llvm -o %t.ll %s
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
+
+// RUN: %clang_cc1 -ffreestanding -triple=x86_64-pc-linux-gnu -emit-llvm -Wall -Werror %s -o - | FileCheck %s -check-prefix=OGCG
+
+// Test that __builtin_cpu_is emits the correct ABI value for every CPU
+// subtype, llvm/include/llvm/TargetParser/X86TargetParser.def.
+extern void a(const char *);
+
+// CIR: !rec_anon_struct = !cir.struct<{!u32i, !u32i, !u32i, !cir.array<!u32i x 1>}>
+// CIR: cir.global "private" external dso_local @__cpu_model : !rec_anon_struct
+// LLVM: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
+// OGCG: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
+
+#define TEST_CPU_IS(NAME, STR)                                                 \
+  void test_##NAME(void) {                                                     \
+    if (__builtin_cpu_is(STR))                                                 \
+      a(STR);                                                                  \
+  }
+
+// CIR-LABEL: cir.func no_inline dso_local @test_nehalem()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_nehalem(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 1
+
+// OGCG-LABEL: define{{.*}} void @test_nehalem(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 1
+TEST_CPU_IS(nehalem, "nehalem")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_westmere()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_westmere(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 2
+
+// OGCG-LABEL: define{{.*}} void @test_westmere(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 2
+TEST_CPU_IS(westmere, "westmere")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_sandybridge()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<3> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_sandybridge(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 3
+
+// OGCG-LABEL: define{{.*}} void @test_sandybridge(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 3
+TEST_CPU_IS(sandybridge, "sandybridge")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_barcelona()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<4> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_barcelona(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 4
+
+// OGCG-LABEL: define{{.*}} void @test_barcelona(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 4
+TEST_CPU_IS(barcelona, "barcelona")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_shanghai()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<5> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_shanghai(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 5
+
+// OGCG-LABEL: define{{.*}} void @test_shanghai(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 5
+TEST_CPU_IS(shanghai, "shanghai")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_istanbul()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<6> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_istanbul(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 6
+
+// OGCG-LABEL: define{{.*}} void @test_istanbul(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 6
+TEST_CPU_IS(istanbul, "istanbul")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_bdver1()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<7> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_bdver1(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 7
+
+// OGCG-LABEL: define{{.*}} void @test_bdver1(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 7
+TEST_CPU_IS(bdver1, "bdver1")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_bdver2()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<8> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_bdver2(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 8
+
+// OGCG-LABEL: define{{.*}} void @test_bdver2(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 8
+TEST_CPU_IS(bdver2, "bdver2")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_bdver3()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<9> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_bdver3(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 9
+
+// OGCG-LABEL: define{{.*}} void @test_bdver3(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 9
+TEST_CPU_IS(bdver3, "bdver3")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_bdver4()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<10> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_bdver4(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 10
+
+// OGCG-LABEL: define{{.*}} void @test_bdver4(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 10
+TEST_CPU_IS(bdver4, "bdver4")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_znver1()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<11> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_znver1(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 11
+
+// OGCG-LABEL: define{{.*}} void @test_znver1(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 11
+TEST_CPU_IS(znver1, "znver1")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_ivybridge()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<12> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_ivybridge(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 12
+
+// OGCG-LABEL: define{{.*}} void @test_ivybridge(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 12
+TEST_CPU_IS(ivybridge, "ivybridge")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_haswell()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<13> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_haswell(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 13
+
+// OGCG-LABEL: define{{.*}} void @test_haswell(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 13
+TEST_CPU_IS(haswell, "haswell")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_broadwell()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<14> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_broadwell(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 14
+
+// OGCG-LABEL: define{{.*}} void @test_broadwell(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 14
+TEST_CPU_IS(broadwell, "broadwell")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_skylake()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<15> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_skylake(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 15
+
+// OGCG-LABEL: define{{.*}} void @test_skylake(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 15
+TEST_CPU_IS(skylake, "skylake")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_skylake_avx512()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<16> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_skylake_avx512(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 16
+
+// OGCG-LABEL: define{{.*}} void @test_skylake_avx512(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 16
+TEST_CPU_IS(skylake_avx512, "skylake-avx512")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_cannonlake()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<17> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_cannonlake(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 17
+
+// OGCG-LABEL: define{{.*}} void @test_cannonlake(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 17
+TEST_CPU_IS(cannonlake, "cannonlake")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_icelake_client()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<18> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_icelake_client(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 18
+
+// OGCG-LABEL: define{{.*}} void @test_icelake_client(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 18
+TEST_CPU_IS(icelake_client, "icelake-client")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_icelake_server()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<19> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_icelake_server(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 19
+
+// OGCG-LABEL: define{{.*}} void @test_icelake_server(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 19
+TEST_CPU_IS(icelake_server, "icelake-server")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_znver2()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<20> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_znver2(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 20
+
+// OGCG-LABEL: define{{.*}} void @test_znver2(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 20
+TEST_CPU_IS(znver2, "znver2")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_cascadelake()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<21> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_cascadelake(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 21
+
+// OGCG-LABEL: define{{.*}} void @test_cascadelake(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 21
+TEST_CPU_IS(cascadelake, "cascadelake")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_tigerlake()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<22> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_tigerlake(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 22
+
+// OGCG-LABEL: define{{.*}} void @test_tigerlake(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 22
+TEST_CPU_IS(tigerlake, "tigerlake")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_cooperlake()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<23> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_cooperlake(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 23
+
+// OGCG-LABEL: define{{.*}} void @test_cooperlake(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 23
+TEST_CPU_IS(cooperlake, "cooperlake")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_sapphirerapids()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<24> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_sapphirerapids(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 24
+
+// OGCG-LABEL: define{{.*}} void @test_sapphirerapids(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 24
+TEST_CPU_IS(sapphirerapids, "sapphirerapids")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_alderlake()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<25> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_alderlake(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 25
+
+// OGCG-LABEL: define{{.*}} void @test_alderlake(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 25
+TEST_CPU_IS(alderlake, "alderlake")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_znver3()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<26> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_znver3(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 26
+
+// OGCG-LABEL: define{{.*}} void @test_znver3(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 26
+TEST_CPU_IS(znver3, "znver3")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_rocketlake()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<27> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_rocketlake(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 27
+
+// OGCG-LABEL: define{{.*}} void @test_rocketlake(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 27
+TEST_CPU_IS(rocketlake, "rocketlake")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_zhaoxin_fam7h_lujiazui()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<28> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_zhaoxin_fam7h_lujiazui(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 28
+
+// OGCG-LABEL: define{{.*}} void @test_zhaoxin_fam7h_lujiazui(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 28
+TEST_CPU_IS(zhaoxin_fam7h_lujiazui, "zhaoxin_fam7h_lujiazui")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_znver4()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<29> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_znver4(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 29
+
+// OGCG-LABEL: define{{.*}} void @test_znver4(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 29
+TEST_CPU_IS(znver4, "znver4")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_graniterapids()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<30> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_graniterapids(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 30
+
+// OGCG-LABEL: define{{.*}} void @test_graniterapids(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 30
+TEST_CPU_IS(graniterapids, "graniterapids")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_graniterapids_d()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<31> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_graniterapids_d(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 31
+
+// OGCG-LABEL: define{{.*}} void @test_graniterapids_d(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 31
+TEST_CPU_IS(graniterapids_d, "graniterapids-d")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_arrowlake()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<32> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_arrowlake(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 32
+
+// OGCG-LABEL: define{{.*}} void @test_arrowlake(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 32
+TEST_CPU_IS(arrowlake, "arrowlake")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_arrowlake_s()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<33> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_arrowlake_s(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 33
+
+// OGCG-LABEL: define{{.*}} void @test_arrowlake_s(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 33
+TEST_CPU_IS(arrowlake_s, "arrowlake-s")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_pantherlake()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<34> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_pantherlake(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 34
+
+// OGCG-LABEL: define{{.*}} void @test_pantherlake(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 34
+TEST_CPU_IS(pantherlake, "pantherlake")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_znver5()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<36> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_znver5(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 36
+
+// OGCG-LABEL: define{{.*}} void @test_znver5(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 36
+TEST_CPU_IS(znver5, "znver5")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_diamondrapids()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<38> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_diamondrapids(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 38
+
+// OGCG-LABEL: define{{.*}} void @test_diamondrapids(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 38
+TEST_CPU_IS(diamondrapids, "diamondrapids")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_novalake()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<39> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_novalake(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 39
+
+// OGCG-LABEL: define{{.*}} void @test_novalake(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 39
+TEST_CPU_IS(novalake, "novalake")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_znver6()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<40> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_znver6(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 40
+
+// OGCG-LABEL: define{{.*}} void @test_znver6(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 40
+TEST_CPU_IS(znver6, "znver6")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_c86_4g_m4()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<41> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_c86_4g_m4(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 41
+
+// OGCG-LABEL: define{{.*}} void @test_c86_4g_m4(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 41
+TEST_CPU_IS(c86_4g_m4, "c86-4g-m4")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_c86_4g_m6()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<42> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_c86_4g_m6(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 42
+
+// OGCG-LABEL: define{{.*}} void @test_c86_4g_m6(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 42
+TEST_CPU_IS(c86_4g_m6, "c86-4g-m6")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_c86_4g_m7()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<43> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_c86_4g_m7(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 43
+
+// OGCG-LABEL: define{{.*}} void @test_c86_4g_m7(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 43
+TEST_CPU_IS(c86_4g_m7, "c86-4g-m7")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_c86_4g_m8()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<44> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_c86_4g_m8(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 44
+
+// OGCG-LABEL: define{{.*}} void @test_c86_4g_m8(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 44
+TEST_CPU_IS(c86_4g_m8, "c86-4g-m8")
+
+// Aliases
+// CIR-LABEL: cir.func no_inline dso_local @test_emeraldrapids()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<24> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_emeraldrapids(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 24
+
+// OGCG-LABEL: define{{.*}} void @test_emeraldrapids(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 24
+TEST_CPU_IS(emeraldrapids, "emeraldrapids")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_raptorlake()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<25> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_raptorlake(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 25
+
+// OGCG-LABEL: define{{.*}} void @test_raptorlake(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 25
+TEST_CPU_IS(raptorlake, "raptorlake")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_meteorlake()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<25> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_meteorlake(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 25
+
+// OGCG-LABEL: define{{.*}} void @test_meteorlake(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 25
+TEST_CPU_IS(meteorlake, "meteorlake")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_gracemont()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<25> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_gracemont(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 25
+
+// OGCG-LABEL: define{{.*}} void @test_gracemont(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 25
+TEST_CPU_IS(gracemont, "gracemont")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_lunarlake()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<33> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_lunarlake(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 33
+
+// OGCG-LABEL: define{{.*}} void @test_lunarlake(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 33
+TEST_CPU_IS(lunarlake, "lunarlake")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_wildcatlake()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][2] {name = "__cpu_subtype"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<34> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_wildcatlake(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// LLVM: = icmp eq i32 [[LOAD]], 34
+
+// OGCG-LABEL: define{{.*}} void @test_wildcatlake(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 8)
+// OGCG: = icmp eq i32 [[LOAD]], 34
+TEST_CPU_IS(wildcatlake, "wildcatlake")
+
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-is-vendor.c b/clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-is-vendor.c
new file mode 100644
index 0000000000000..c2e27a4684a7d
--- /dev/null
+++ b/clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-is-vendor.c
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -x c -ffreestanding -triple x86_64-unknown-linux -Wno-implicit-function-declaration -fclangir -emit-cir -o %t.cir %s
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+
+// RUN: %clang_cc1 -x c -ffreestanding -triple x86_64-unknown-linux -Wno-implicit-function-declaration -fclangir -emit-llvm -o %t.ll %s
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
+
+// RUN: %clang_cc1 -ffreestanding -triple=x86_64-pc-linux-gnu -emit-llvm -Wall -Werror %s -o - | FileCheck %s -check-prefix=OGCG
+
+// Test that __builtin_cpu_is emits the correct ABI value and field offset for
+// every vendor (field offset 0) in llvm/include/llvm/TargetParser/
+// X86TargetParser.def.
+extern void a(const char *);
+
+// CIR: !rec_anon_struct = !cir.struct<{!u32i, !u32i, !u32i, !cir.array<!u32i x 1>}>
+// CIR: cir.global "private" external dso_local @__cpu_model : !rec_anon_struct
+// LLVM: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
+// OGCG: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
+
+#define TEST_CPU_IS(NAME, STR)                                                 \
+  void test_##NAME(void) {                                                     \
+    if (__builtin_cpu_is(STR))                                                 \
+      a(STR);                                                                  \
+  }
+// CIR-LABEL: cir.func no_inline dso_local @test_intel()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][0] {name = "__cpu_vendor"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_intel(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_model
+// LLVM: = icmp eq i32 [[LOAD]], 1
+
+// OGCG-LABEL: define{{.*}} void @test_intel(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_model
+// OGCG: = icmp eq i32 [[LOAD]], 1
+TEST_CPU_IS(intel, "intel")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amd()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][0] {name = "__cpu_vendor"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_amd(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_model
+// LLVM: = icmp eq i32 [[LOAD]], 2
+
+// OGCG-LABEL: define{{.*}} void @test_amd(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_model
+// OGCG: = icmp eq i32 [[LOAD]], 2
+TEST_CPU_IS(amd, "amd")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_other()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][0] {name = "__cpu_vendor"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALUE:%.]] = cir.load align(4) [[CPUTYPE]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<5> : !u32i
+// CIR-NEXT: {{.*}} = cir.cmp eq [[VALUE]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_other(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_model
+// LLVM: = icmp eq i32 [[LOAD]], 5
+
+// OGCG-LABEL: define{{.*}} void @test_other(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_model
+// OGCG: = icmp eq i32 [[LOAD]], 5
+TEST_CPU_IS(other, "other")
+
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-supports-all.c b/clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-supports-all.c
new file mode 100644
index 0000000000000..3d6017f97e325
--- /dev/null
+++ b/clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-supports-all.c
@@ -0,0 +1,2193 @@
+// RUN: %clang_cc1 -x c -ffreestanding -triple x86_64-unknown-linux -Wno-implicit-function-declaration -fclangir -emit-cir -o %t.cir %s
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+
+// RUN: %clang_cc1 -x c -ffreestanding -triple x86_64-unknown-linux -Wno-implicit-function-declaration -fclangir -emit-llvm -o %t.ll %s
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
+
+// RUN: %clang_cc1 -ffreestanding -triple=x86_64-pc-linux-gnu -emit-llvm -Wall -Werror %s -o - | FileCheck %s -check-prefix=OGCG
+
+// Test that __builtin_cpu_supports emits the correct field and bit for every
+// feature listed in llvm/include/llvm/TargetParser/X86TargetParser.def. 
+extern void a(const char *);
+
+// CIR: !rec_anon_struct = !cir.struct<{!u32i, !u32i, !u32i, !cir.array<!u32i x 1>}>
+// CIR: cir.global "private" external dso_local @__cpu_model : !rec_anon_struct
+// LLVM: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
+// OGCG: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
+
+#define TEST_CPU_SUPPORTS(NAME, STR)                                           \
+  void test_##NAME(void) {                                                     \
+    if (__builtin_cpu_supports(STR))                                           \
+      a(STR);                                                                  \
+  }
+
+// CIR-LABEL: cir.func no_inline dso_local @test_cmov()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<1> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_cmov(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 1
+
+// OGCG-LABEL: define{{.*}} void @test_cmov(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 1
+TEST_CPU_SUPPORTS(cmov, "cmov")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_mmx()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<2> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_mmx(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 2
+
+// OGCG-LABEL: define{{.*}} void @test_mmx(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 2
+TEST_CPU_SUPPORTS(mmx, "mmx")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_popcnt()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<4> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_popcnt(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 4
+
+// OGCG-LABEL: define{{.*}} void @test_popcnt(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 4
+TEST_CPU_SUPPORTS(popcnt, "popcnt")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_sse()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<8> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_sse(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 8
+
+// OGCG-LABEL: define{{.*}} void @test_sse(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 8
+TEST_CPU_SUPPORTS(sse, "sse")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_sse2()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<16> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_sse2(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 16
+
+// OGCG-LABEL: define{{.*}} void @test_sse2(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 16
+TEST_CPU_SUPPORTS(sse2, "sse2")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_sse3()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<32> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_sse3(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 32
+
+// OGCG-LABEL: define{{.*}} void @test_sse3(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 32
+TEST_CPU_SUPPORTS(sse3, "sse3")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_ssse3()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<64> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_ssse3(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 64
+
+// OGCG-LABEL: define{{.*}} void @test_ssse3(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 64
+TEST_CPU_SUPPORTS(ssse3, "ssse3")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_sse4_1()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<128> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_sse4_1(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 128
+
+// OGCG-LABEL: define{{.*}} void @test_sse4_1(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 128
+TEST_CPU_SUPPORTS(sse4_1, "sse4.1")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_sse4_2()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<256> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_sse4_2(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 256
+
+// OGCG-LABEL: define{{.*}} void @test_sse4_2(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 256
+TEST_CPU_SUPPORTS(sse4_2, "sse4.2")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<512> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_avx(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 512
+
+// OGCG-LABEL: define{{.*}} void @test_avx(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 512
+TEST_CPU_SUPPORTS(avx, "avx")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx2()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<1024> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_avx2(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 1024
+
+// OGCG-LABEL: define{{.*}} void @test_avx2(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 1024
+TEST_CPU_SUPPORTS(avx2, "avx2")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_sse4a()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<2048> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_sse4a(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 2048
+
+// OGCG-LABEL: define{{.*}} void @test_sse4a(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 2048
+TEST_CPU_SUPPORTS(sse4a, "sse4a")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_fma4()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<4096> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_fma4(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 4096
+
+// OGCG-LABEL: define{{.*}} void @test_fma4(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 4096
+TEST_CPU_SUPPORTS(fma4, "fma4")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_xop()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<8192> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_xop(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 8192
+
+// OGCG-LABEL: define{{.*}} void @test_xop(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 8192
+TEST_CPU_SUPPORTS(xop, "xop")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_fma()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<16384> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_fma(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 16384
+
+// OGCG-LABEL: define{{.*}} void @test_fma(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 16384
+TEST_CPU_SUPPORTS(fma, "fma")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx512f()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<32768> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_avx512f(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 32768
+
+// OGCG-LABEL: define{{.*}} void @test_avx512f(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 32768
+TEST_CPU_SUPPORTS(avx512f, "avx512f")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_bmi()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<65536> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_bmi(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 65536
+
+// OGCG-LABEL: define{{.*}} void @test_bmi(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 65536
+TEST_CPU_SUPPORTS(bmi, "bmi")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_bmi2()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<131072> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_bmi2(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 131072
+
+// OGCG-LABEL: define{{.*}} void @test_bmi2(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 131072
+TEST_CPU_SUPPORTS(bmi2, "bmi2")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_aes()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<262144> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_aes(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 262144
+
+// OGCG-LABEL: define{{.*}} void @test_aes(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 262144
+TEST_CPU_SUPPORTS(aes, "aes")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_pclmul()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<524288> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_pclmul(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 524288
+
+// OGCG-LABEL: define{{.*}} void @test_pclmul(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 524288
+TEST_CPU_SUPPORTS(pclmul, "pclmul")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx512vl()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<1048576> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_avx512vl(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 1048576
+
+// OGCG-LABEL: define{{.*}} void @test_avx512vl(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 1048576
+TEST_CPU_SUPPORTS(avx512vl, "avx512vl")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx512bw()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<2097152> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_avx512bw(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 2097152
+
+// OGCG-LABEL: define{{.*}} void @test_avx512bw(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 2097152
+TEST_CPU_SUPPORTS(avx512bw, "avx512bw")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx512dq()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<4194304> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_avx512dq(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 4194304
+
+// OGCG-LABEL: define{{.*}} void @test_avx512dq(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 4194304
+TEST_CPU_SUPPORTS(avx512dq, "avx512dq")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx512cd()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<8388608> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_avx512cd(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 8388608
+
+// OGCG-LABEL: define{{.*}} void @test_avx512cd(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 8388608
+TEST_CPU_SUPPORTS(avx512cd, "avx512cd")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx512vbmi()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<67108864> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_avx512vbmi(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 67108864
+
+// OGCG-LABEL: define{{.*}} void @test_avx512vbmi(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 67108864
+TEST_CPU_SUPPORTS(avx512vbmi, "avx512vbmi")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx512ifma()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<134217728> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_avx512ifma(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 134217728
+
+// OGCG-LABEL: define{{.*}} void @test_avx512ifma(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 134217728
+TEST_CPU_SUPPORTS(avx512ifma, "avx512ifma")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx512vpopcntdq()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<1073741824> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_avx512vpopcntdq(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], 1073741824
+
+// OGCG-LABEL: define{{.*}} void @test_avx512vpopcntdq(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], 1073741824
+TEST_CPU_SUPPORTS(avx512vpopcntdq, "avx512vpopcntdq")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx512vbmi2()
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[STRIDE:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[STRIDE]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<2147483648> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: {{.*}} = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+
+// LLVM-LABEL: define{{.*}} void @test_avx512vbmi2(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// LLVM: = and i32 [[LOAD]], -2147483648
+
+// OGCG-LABEL: define{{.*}} void @test_avx512vbmi2(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12)
+// OGCG: = and i32 [[LOAD]], -2147483648
+TEST_CPU_SUPPORTS(avx512vbmi2, "avx512vbmi2")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_gfni()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_gfni(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 1
+
+// OGCG-LABEL: define{{.*}} void @test_gfni(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 1
+TEST_CPU_SUPPORTS(gfni, "gfni")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_vpclmulqdq()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_vpclmulqdq(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 2
+
+// OGCG-LABEL: define{{.*}} void @test_vpclmulqdq(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 2
+TEST_CPU_SUPPORTS(vpclmulqdq, "vpclmulqdq")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx512vnni()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<4> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_avx512vnni(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 4
+
+// OGCG-LABEL: define{{.*}} void @test_avx512vnni(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 4
+TEST_CPU_SUPPORTS(avx512vnni, "avx512vnni")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx512bitalg()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<8> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_avx512bitalg(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 8
+
+// OGCG-LABEL: define{{.*}} void @test_avx512bitalg(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 8
+TEST_CPU_SUPPORTS(avx512bitalg, "avx512bitalg")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx512bf16()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<16> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_avx512bf16(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 16
+
+// OGCG-LABEL: define{{.*}} void @test_avx512bf16(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 16
+TEST_CPU_SUPPORTS(avx512bf16, "avx512bf16")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx512vp2intersect()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<32> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_avx512vp2intersect(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 32
+
+// OGCG-LABEL: define{{.*}} void @test_avx512vp2intersect(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 32
+TEST_CPU_SUPPORTS(avx512vp2intersect, "avx512vp2intersect")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_adx()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<256> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_adx(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 256
+
+// OGCG-LABEL: define{{.*}} void @test_adx(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 256
+TEST_CPU_SUPPORTS(adx, "adx")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_cldemote()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<1024> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_cldemote(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 1024
+
+// OGCG-LABEL: define{{.*}} void @test_cldemote(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 1024
+TEST_CPU_SUPPORTS(cldemote, "cldemote")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_clflushopt()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<2048> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_clflushopt(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 2048
+
+// OGCG-LABEL: define{{.*}} void @test_clflushopt(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 2048
+TEST_CPU_SUPPORTS(clflushopt, "clflushopt")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_clwb()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<4096> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_clwb(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 4096
+
+// OGCG-LABEL: define{{.*}} void @test_clwb(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 4096
+TEST_CPU_SUPPORTS(clwb, "clwb")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_clzero()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<8192> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_clzero(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 8192
+
+// OGCG-LABEL: define{{.*}} void @test_clzero(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 8192
+TEST_CPU_SUPPORTS(clzero, "clzero")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_cx16()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<16384> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_cx16(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 16384
+
+// OGCG-LABEL: define{{.*}} void @test_cx16(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 16384
+TEST_CPU_SUPPORTS(cx16, "cx16")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_enqcmd()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<65536> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_enqcmd(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 65536
+
+// OGCG-LABEL: define{{.*}} void @test_enqcmd(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 65536
+TEST_CPU_SUPPORTS(enqcmd, "enqcmd")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_f16c()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<131072> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_f16c(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 131072
+
+// OGCG-LABEL: define{{.*}} void @test_f16c(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 131072
+TEST_CPU_SUPPORTS(f16c, "f16c")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_fsgsbase()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<262144> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_fsgsbase(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 262144
+
+// OGCG-LABEL: define{{.*}} void @test_fsgsbase(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 262144
+TEST_CPU_SUPPORTS(fsgsbase, "fsgsbase")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_sahf()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<4194304> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_sahf(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 4194304
+
+// OGCG-LABEL: define{{.*}} void @test_sahf(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 4194304
+TEST_CPU_SUPPORTS(sahf, "sahf")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_64bit()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<8388608> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_64bit(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 8388608
+
+// OGCG-LABEL: define{{.*}} void @test_64bit(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 8388608
+TEST_CPU_SUPPORTS(64bit, "64bit")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_lwp()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<16777216> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_lwp(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 16777216
+
+// OGCG-LABEL: define{{.*}} void @test_lwp(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 16777216
+TEST_CPU_SUPPORTS(lwp, "lwp")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_lzcnt()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<33554432> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_lzcnt(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 33554432
+
+// OGCG-LABEL: define{{.*}} void @test_lzcnt(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 33554432
+TEST_CPU_SUPPORTS(lzcnt, "lzcnt")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_movbe()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<67108864> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_movbe(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 67108864
+
+// OGCG-LABEL: define{{.*}} void @test_movbe(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 67108864
+TEST_CPU_SUPPORTS(movbe, "movbe")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_movdir64b()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<134217728> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_movdir64b(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 134217728
+
+// OGCG-LABEL: define{{.*}} void @test_movdir64b(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 134217728
+TEST_CPU_SUPPORTS(movdir64b, "movdir64b")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_movdiri()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<268435456> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_movdiri(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 268435456
+
+// OGCG-LABEL: define{{.*}} void @test_movdiri(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 268435456
+TEST_CPU_SUPPORTS(movdiri, "movdiri")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_mwaitx()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<536870912> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_mwaitx(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], 536870912
+
+// OGCG-LABEL: define{{.*}} void @test_mwaitx(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], 536870912
+TEST_CPU_SUPPORTS(mwaitx, "mwaitx")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_pconfig()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<2147483648> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_pconfig(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// LLVM: = and i32 [[LOAD]], -2147483648
+
+// OGCG-LABEL: define{{.*}} void @test_pconfig(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
+// OGCG: = and i32 [[LOAD]], -2147483648
+TEST_CPU_SUPPORTS(pconfig, "pconfig")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_pku()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_pku(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 1
+
+// OGCG-LABEL: define{{.*}} void @test_pku(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 1
+TEST_CPU_SUPPORTS(pku, "pku")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_prfchw()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<4> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_prfchw(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 4
+
+// OGCG-LABEL: define{{.*}} void @test_prfchw(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 4
+TEST_CPU_SUPPORTS(prfchw, "prfchw")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_ptwrite()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<8> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_ptwrite(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 8
+
+// OGCG-LABEL: define{{.*}} void @test_ptwrite(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 8
+TEST_CPU_SUPPORTS(ptwrite, "ptwrite")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_rdpid()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<16> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_rdpid(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 16
+
+// OGCG-LABEL: define{{.*}} void @test_rdpid(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 16
+TEST_CPU_SUPPORTS(rdpid, "rdpid")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_rdrnd()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<32> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_rdrnd(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 32
+
+// OGCG-LABEL: define{{.*}} void @test_rdrnd(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 32
+TEST_CPU_SUPPORTS(rdrnd, "rdrnd")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_rdseed()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<64> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_rdseed(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 64
+
+// OGCG-LABEL: define{{.*}} void @test_rdseed(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 64
+TEST_CPU_SUPPORTS(rdseed, "rdseed")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_rtm()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<128> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_rtm(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 128
+
+// OGCG-LABEL: define{{.*}} void @test_rtm(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 128
+TEST_CPU_SUPPORTS(rtm, "rtm")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_serialize()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<256> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_serialize(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 256
+
+// OGCG-LABEL: define{{.*}} void @test_serialize(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 256
+TEST_CPU_SUPPORTS(serialize, "serialize")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_sgx()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<512> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_sgx(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 512
+
+// OGCG-LABEL: define{{.*}} void @test_sgx(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 512
+TEST_CPU_SUPPORTS(sgx, "sgx")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_sha()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<1024> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_sha(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 1024
+
+// OGCG-LABEL: define{{.*}} void @test_sha(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 1024
+TEST_CPU_SUPPORTS(sha, "sha")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_shstk()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<2048> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_shstk(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 2048
+
+// OGCG-LABEL: define{{.*}} void @test_shstk(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 2048
+TEST_CPU_SUPPORTS(shstk, "shstk")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_tbm()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<4096> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_tbm(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 4096
+
+// OGCG-LABEL: define{{.*}} void @test_tbm(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 4096
+TEST_CPU_SUPPORTS(tbm, "tbm")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_tsxldtrk()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<8192> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_tsxldtrk(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 8192
+
+// OGCG-LABEL: define{{.*}} void @test_tsxldtrk(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 8192
+TEST_CPU_SUPPORTS(tsxldtrk, "tsxldtrk")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_vaes()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<16384> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_vaes(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 16384
+
+// OGCG-LABEL: define{{.*}} void @test_vaes(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 16384
+TEST_CPU_SUPPORTS(vaes, "vaes")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_waitpkg()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<32768> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_waitpkg(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 32768
+
+// OGCG-LABEL: define{{.*}} void @test_waitpkg(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 32768
+TEST_CPU_SUPPORTS(waitpkg, "waitpkg")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_wbnoinvd()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<65536> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_wbnoinvd(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 65536
+
+// OGCG-LABEL: define{{.*}} void @test_wbnoinvd(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 65536
+TEST_CPU_SUPPORTS(wbnoinvd, "wbnoinvd")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_xsave()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<131072> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_xsave(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 131072
+
+// OGCG-LABEL: define{{.*}} void @test_xsave(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 131072
+TEST_CPU_SUPPORTS(xsave, "xsave")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_xsavec()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<262144> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_xsavec(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 262144
+
+// OGCG-LABEL: define{{.*}} void @test_xsavec(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 262144
+TEST_CPU_SUPPORTS(xsavec, "xsavec")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_xsaveopt()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<524288> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_xsaveopt(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 524288
+
+// OGCG-LABEL: define{{.*}} void @test_xsaveopt(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 524288
+TEST_CPU_SUPPORTS(xsaveopt, "xsaveopt")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_xsaves()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<1048576> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_xsaves(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 1048576
+
+// OGCG-LABEL: define{{.*}} void @test_xsaves(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 1048576
+TEST_CPU_SUPPORTS(xsaves, "xsaves")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amx_tile()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<2097152> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_amx_tile(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 2097152
+
+// OGCG-LABEL: define{{.*}} void @test_amx_tile(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 2097152
+TEST_CPU_SUPPORTS(amx_tile, "amx-tile")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amx_int8()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<4194304> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_amx_int8(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 4194304
+
+// OGCG-LABEL: define{{.*}} void @test_amx_int8(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 4194304
+TEST_CPU_SUPPORTS(amx_int8, "amx-int8")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amx_bf16()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<8388608> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_amx_bf16(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 8388608
+
+// OGCG-LABEL: define{{.*}} void @test_amx_bf16(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 8388608
+TEST_CPU_SUPPORTS(amx_bf16, "amx-bf16")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_uintr()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<16777216> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_uintr(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 16777216
+
+// OGCG-LABEL: define{{.*}} void @test_uintr(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 16777216
+TEST_CPU_SUPPORTS(uintr, "uintr")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_hreset()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<33554432> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_hreset(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 33554432
+
+// OGCG-LABEL: define{{.*}} void @test_hreset(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 33554432
+TEST_CPU_SUPPORTS(hreset, "hreset")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_kl()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<67108864> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_kl(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 67108864
+
+// OGCG-LABEL: define{{.*}} void @test_kl(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 67108864
+TEST_CPU_SUPPORTS(kl, "kl")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_widekl()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<268435456> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_widekl(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 268435456
+
+// OGCG-LABEL: define{{.*}} void @test_widekl(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 268435456
+TEST_CPU_SUPPORTS(widekl, "widekl")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avxvnni()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<536870912> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_avxvnni(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 536870912
+
+// OGCG-LABEL: define{{.*}} void @test_avxvnni(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 536870912
+TEST_CPU_SUPPORTS(avxvnni, "avxvnni")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx512fp16()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<1073741824> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_avx512fp16(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], 1073741824
+
+// OGCG-LABEL: define{{.*}} void @test_avx512fp16(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], 1073741824
+TEST_CPU_SUPPORTS(avx512fp16, "avx512fp16")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_x86_64()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<2147483648> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_x86_64(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// LLVM: = and i32 [[LOAD]], -2147483648
+
+// OGCG-LABEL: define{{.*}} void @test_x86_64(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4)
+// OGCG: = and i32 [[LOAD]], -2147483648
+TEST_CPU_SUPPORTS(x86_64, "x86-64")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_x86_64_v2()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_x86_64_v2(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 1
+
+// OGCG-LABEL: define{{.*}} void @test_x86_64_v2(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 1
+TEST_CPU_SUPPORTS(x86_64_v2, "x86-64-v2")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_x86_64_v3()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_x86_64_v3(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 2
+
+// OGCG-LABEL: define{{.*}} void @test_x86_64_v3(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 2
+TEST_CPU_SUPPORTS(x86_64_v3, "x86-64-v3")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_x86_64_v4()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<4> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_x86_64_v4(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 4
+
+// OGCG-LABEL: define{{.*}} void @test_x86_64_v4(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 4
+TEST_CPU_SUPPORTS(x86_64_v4, "x86-64-v4")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avxifma()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<8> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_avxifma(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 8
+
+// OGCG-LABEL: define{{.*}} void @test_avxifma(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 8
+TEST_CPU_SUPPORTS(avxifma, "avxifma")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avxvnniint8()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<16> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_avxvnniint8(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 16
+
+// OGCG-LABEL: define{{.*}} void @test_avxvnniint8(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 16
+TEST_CPU_SUPPORTS(avxvnniint8, "avxvnniint8")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avxneconvert()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<32> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_avxneconvert(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 32
+
+// OGCG-LABEL: define{{.*}} void @test_avxneconvert(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 32
+TEST_CPU_SUPPORTS(avxneconvert, "avxneconvert")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_cmpccxadd()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<64> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_cmpccxadd(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 64
+
+// OGCG-LABEL: define{{.*}} void @test_cmpccxadd(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 64
+TEST_CPU_SUPPORTS(cmpccxadd, "cmpccxadd")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amx_fp16()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<128> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_amx_fp16(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 128
+
+// OGCG-LABEL: define{{.*}} void @test_amx_fp16(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 128
+TEST_CPU_SUPPORTS(amx_fp16, "amx-fp16")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_prefetchi()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<256> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_prefetchi(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 256
+
+// OGCG-LABEL: define{{.*}} void @test_prefetchi(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 256
+TEST_CPU_SUPPORTS(prefetchi, "prefetchi")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_raoint()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<512> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_raoint(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 512
+
+// OGCG-LABEL: define{{.*}} void @test_raoint(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 512
+TEST_CPU_SUPPORTS(raoint, "raoint")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amx_complex()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<1024> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_amx_complex(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 1024
+
+// OGCG-LABEL: define{{.*}} void @test_amx_complex(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 1024
+TEST_CPU_SUPPORTS(amx_complex, "amx-complex")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avxvnniint16()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<2048> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_avxvnniint16(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 2048
+
+// OGCG-LABEL: define{{.*}} void @test_avxvnniint16(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 2048
+TEST_CPU_SUPPORTS(avxvnniint16, "avxvnniint16")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_sm3()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<4096> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_sm3(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 4096
+
+// OGCG-LABEL: define{{.*}} void @test_sm3(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 4096
+TEST_CPU_SUPPORTS(sm3, "sm3")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_sha512()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<8192> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_sha512(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 8192
+
+// OGCG-LABEL: define{{.*}} void @test_sha512(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 8192
+TEST_CPU_SUPPORTS(sha512, "sha512")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_sm4()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<16384> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_sm4(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 16384
+
+// OGCG-LABEL: define{{.*}} void @test_sm4(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 16384
+TEST_CPU_SUPPORTS(sm4, "sm4")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_apxf()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<32768> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_apxf(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 32768
+
+// OGCG-LABEL: define{{.*}} void @test_apxf(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 32768
+TEST_CPU_SUPPORTS(apxf, "apxf")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_usermsr()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<65536> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_usermsr(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 65536
+
+// OGCG-LABEL: define{{.*}} void @test_usermsr(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 65536
+TEST_CPU_SUPPORTS(usermsr, "usermsr")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx10_1()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<262144> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_avx10_1(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 262144
+
+// OGCG-LABEL: define{{.*}} void @test_avx10_1(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 262144
+TEST_CPU_SUPPORTS(avx10_1, "avx10.1")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx10_2()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<1048576> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_avx10_2(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 1048576
+
+// OGCG-LABEL: define{{.*}} void @test_avx10_2(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 1048576
+TEST_CPU_SUPPORTS(avx10_2, "avx10.2")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amx_avx512()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<2097152> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_amx_avx512(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 2097152
+
+// OGCG-LABEL: define{{.*}} void @test_amx_avx512(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 2097152
+TEST_CPU_SUPPORTS(amx_avx512, "amx-avx512")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amx_fp8()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<16777216> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_amx_fp8(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 16777216
+
+// OGCG-LABEL: define{{.*}} void @test_amx_fp8(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 16777216
+TEST_CPU_SUPPORTS(amx_fp8, "amx-fp8")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_movrs()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<33554432> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_movrs(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 33554432
+
+// OGCG-LABEL: define{{.*}} void @test_movrs(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 33554432
+TEST_CPU_SUPPORTS(movrs, "movrs")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_amx_movrs()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<67108864> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_amx_movrs(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 67108864
+
+// OGCG-LABEL: define{{.*}} void @test_amx_movrs(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 67108864
+TEST_CPU_SUPPORTS(amx_movrs, "amx-movrs")
+
+// CIR-LABEL: cir.func no_inline dso_local @test_avx512bmm()
+// CIR: [[TRUE:%.]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<134217728> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+
+// LLVM-LABEL: define{{.*}} void @test_avx512bmm(
+// LLVM: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// LLVM: = and i32 [[LOAD]], 134217728
+
+// OGCG-LABEL: define{{.*}} void @test_avx512bmm(
+// OGCG: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8)
+// OGCG: = and i32 [[LOAD]], 134217728
+TEST_CPU_SUPPORTS(avx512bmm, "avx512bmm")
+
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-supports.c b/clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-supports.c
new file mode 100644
index 0000000000000..1ca18ee7bf04f
--- /dev/null
+++ b/clang/test/CIR/CodeGenBuiltins/X86/builtin-cpu-supports.c
@@ -0,0 +1,222 @@
+// RUN: %clang_cc1 -x c -ffreestanding -triple x86_64-unknown-linux -Wno-implicit-function-declaration -fclangir -emit-llvm -o %t.ll %s
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
+//
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=OGCG
+
+// Test that we have the structure definition, the gep offsets, the name of the
+// global, the bit grab, and the icmp correct.
+extern void a(const char *);
+
+// CIR-LABEL: cir.func no_inline dso_local @main() -> !s32i
+// CIR: cir.call @__cpu_indicator_init()
+// CIR: [[TRUE:%.*]] = cir.const #true
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_model : !cir.ptr<!rec_anon_struct>
+// CIR-NEXT: [[CPUTYPE:%.]] = cir.get_member [[GLOBAL]][3] {name = "__cpu_feature"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!cir.array<!u32i x 1>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: {{.*}} = cir.ptr_stride [[CPUTYPE]], [[IDX]] : (!cir.ptr<!cir.array<!u32i x 1>>, !u32i) -> !cir.ptr<!cir.array<!u32i x 1>>
+// CIR: [[VALUE0:%.]] = cir.load align(4) {{.*}} : !cir.ptr<!u32i>, !u32i
+// CIR: [[MASK:%.]] = cir.const #cir.int<1> : !u32i
+// CIR: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE]] : !cir.bool
+// CIR: [[TRUE2:%.*]] = cir.const #true
+// CIR: [[GLOBAL2:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX2:%.]] = cir.const #cir.int<0> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL2]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX2]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE2]] : !cir.bool
+
+// LLVM-LABEL: define dso_local i32 @main(
+// LLVM-SAME: ) #[[ATTR0:[0-9]+]] {
+// LLVM-NEXT:    [[RETVAL:%.*]] = alloca i32, i64 1, align 4
+// LLVM-NEXT:    call void @__cpu_indicator_init()
+// LLVM:         [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12), align 4
+// LLVM-NEXT:    [[TMP1:%.*]] = and i32 [[TMP0]], 256
+// LLVM-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 256
+// LLVM-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], true
+// LLVM-NEXT:    br i1 [[TMP3]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// LLVM:    [[TMP4:%.*]] = load i32, ptr @__cpu_features2, align 4
+// LLVM-NEXT:    [[TMP5:%.*]] = and i32 [[TMP4]], 1
+// LLVM-NEXT:    [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 1
+// LLVM-NEXT:    [[TMP7:%.*]] = and i1 [[TMP6]], true
+// LLVM-NEXT:    br i1 [[TMP7]], label [[IF_THEN1:%.*]], label [[IF_END2:%.*]]
+// LLVM:    store i32 0, ptr [[RETVAL]], align 4
+
+// OGCG-LABEL: define dso_local i32 @main(
+// OGCG-SAME: ) #[[ATTR0:[0-9]+]] {
+// OGCG-NEXT:  entry:
+// OGCG-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
+// OGCG-NEXT:    store i32 0, ptr [[RETVAL]], align 4
+// OGCG-NEXT:    call void @__cpu_indicator_init()
+// OGCG-NEXT:    [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_model, i64 12), align 4
+// OGCG-NEXT:    [[TMP1:%.*]] = and i32 [[TMP0]], 256
+// OGCG-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 256
+// OGCG-NEXT:    [[TMP3:%.*]] = and i1 true, [[TMP2]]
+// OGCG-NEXT:    br i1 [[TMP3]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+// OGCG:       if.then:
+// OGCG-NEXT:    call void @a(ptr noundef @.str)
+// OGCG-NEXT:    br label [[IF_END]]
+// OGCG:       if.end:
+// OGCG-NEXT:    [[TMP4:%.*]] = load i32, ptr @__cpu_features2, align 4
+// OGCG-NEXT:    [[TMP5:%.*]] = and i32 [[TMP4]], 1
+// OGCG-NEXT:    [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 1
+// OGCG-NEXT:    [[TMP7:%.*]] = and i1 true, [[TMP6]]
+// OGCG-NEXT:    br i1 [[TMP7]], label [[IF_THEN1:%.*]], label [[IF_END2:%.*]]
+// OGCG:       if.then1:
+// OGCG-NEXT:    call void @a(ptr noundef @.str.1)
+// OGCG-NEXT:    br label [[IF_END2]]
+// OGCG:       if.end2:
+// OGCG-NEXT:    ret i32 0
+int main(void) {
+  __builtin_cpu_init();
+
+  if (__builtin_cpu_supports("sse4.2"))
+    a("sse4.2");
+
+
+  if (__builtin_cpu_supports("gfni"))
+    a("gfni");
+
+  return 0;
+}
+
+// CIR-LABEL: cir.func no_inline dso_local @baseline() -> !s32i
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<2147483648> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE2]] : !cir.bool
+
+// LLVM-LABEL: define dso_local i32 @baseline(
+// LLVM-SAME: ) #[[ATTR0]] {
+// LLVM-NEXT:    [[RETVAL:%.]] = alloca i32, i64 1, align 4
+// LLVM-NEXT:    [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4), align 4
+// LLVM-NEXT:    [[TMP1:%.*]] = and i32 [[TMP0]], -2147483648
+// LLVM-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -2147483648
+// LLVM-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], true
+// LLVM-NEXT:    [[CONV:%.*]] = zext i1 [[TMP3]] to i32
+// LLVM-NEXT:    store i32 [[CONV]], ptr [[RETVAL]], align 4
+// LLVM-NEXT:    [[RET:%.*]] = load i32, ptr [[RETVAL]], align 4
+// LLVM-NEXT:    ret i32 [[RET]]
+
+// OGCG-LABEL: define dso_local i32 @baseline(
+// OGCG-SAME: ) #[[ATTR0]] {
+// OGCG-NEXT:  entry:
+// OGCG-NEXT:    [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 4), align 4
+// OGCG-NEXT:    [[TMP1:%.*]] = and i32 [[TMP0]], -2147483648
+// OGCG-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -2147483648
+// OGCG-NEXT:    [[TMP3:%.*]] = and i1 true, [[TMP2]]
+// OGCG-NEXT:    [[CONV:%.*]] = zext i1 [[TMP3]] to i32
+// OGCG-NEXT:    ret i32 [[CONV]]
+int baseline() { return __builtin_cpu_supports("x86-64"); }
+
+// CIR-LABEL: cir.func no_inline dso_local @v2() -> !s32i
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<1> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE2]] : !cir.bool
+
+// LLVM-LABEL: define dso_local i32 @v2(
+// LLVM-SAME: ) #[[ATTR0]] {
+// LLVM-NEXT:    [[RETVAL:%.]] = alloca i32, i64 1, align 4
+// LLVM-NEXT:    [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8), align 4
+// LLVM-NEXT:    [[TMP1:%.*]] = and i32 [[TMP0]], 1
+// LLVM-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
+// LLVM-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], true
+// LLVM-NEXT:    [[CONV:%.*]] = zext i1 [[TMP3]] to i32
+// LLVM-NEXT:    store i32 [[CONV]], ptr [[RETVAL]], align 4
+// LLVM-NEXT:    [[RET:%.*]] = load i32, ptr [[RETVAL]], align 4
+// LLVM-NEXT:    ret i32 [[RET]]
+
+// OGCG-LABEL: define dso_local i32 @v2(
+// OGCG-SAME: ) #[[ATTR0]] {
+// OGCG-NEXT:  entry:
+// OGCG-NEXT:    [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8), align 4
+// OGCG-NEXT:    [[TMP1:%.*]] = and i32 [[TMP0]], 1
+// OGCG-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
+// OGCG-NEXT:    [[TMP3:%.*]] = and i1 true, [[TMP2]]
+// OGCG-NEXT:    [[CONV:%.*]] = zext i1 [[TMP3]] to i32
+// OGCG-NEXT:    ret i32 [[CONV]]
+int v2() { return __builtin_cpu_supports("x86-64-v2"); }
+
+// CIR-LABEL: cir.func no_inline dso_local @v3() -> !s32i
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE2]] : !cir.bool
+
+// LLVM-LABEL: define dso_local i32 @v3(
+// LLVM-SAME: ) #[[ATTR0]] {
+// LLVM-NEXT:    [[RETVAL:%.]] = alloca i32, i64 1, align 4
+// LLVM-NEXT:    [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8), align 4
+// LLVM-NEXT:    [[TMP1:%.*]] = and i32 [[TMP0]], 2
+// LLVM-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 2
+// LLVM-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], true
+// LLVM-NEXT:    [[CONV:%.*]] = zext i1 [[TMP3]] to i32
+// LLVM-NEXT:    store i32 [[CONV]], ptr [[RETVAL]], align 4
+// LLVM-NEXT:    [[RET:%.*]] = load i32, ptr [[RETVAL]], align 4
+// LLVM-NEXT:    ret i32 [[RET]]
+
+// OGCG-LABEL: define dso_local i32 @v3(
+// OGCG-SAME: ) #[[ATTR0]] {
+// OGCG-NEXT:  entry:
+// OGCG-NEXT:    [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8), align 4
+// OGCG-NEXT:    [[TMP1:%.*]] = and i32 [[TMP0]], 2
+// OGCG-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 2
+// OGCG-NEXT:    [[TMP3:%.*]] = and i1 true, [[TMP2]]
+// OGCG-NEXT:    [[CONV:%.*]] = zext i1 [[TMP3]] to i32
+// OGCG-NEXT:    ret i32 [[CONV]]
+int v3() { return __builtin_cpu_supports("x86-64-v3"); }
+
+// CIR-LABEL: cir.func no_inline dso_local @v4() -> !s32i
+// CIR: [[GLOBAL:%.]] = cir.get_global @__cpu_features2 : !cir.ptr<!cir.array<!u32i x 3>>
+// CIR-NEXT: [[IDX:%.]] = cir.const #cir.int<2> : !u32i
+// CIR-NEXT: [[ARRPTR:%.]] = cir.cast array_to_ptrdecay [[GLOBAL]] : !cir.ptr<!cir.array<!u32i x 3>> -> !cir.ptr<!u32i>
+// CIR-NEXT: [[VALPTR:%.]] = cir.ptr_stride [[ARRPTR]], [[IDX]] : (!cir.ptr<!u32i>, !u32i) -> !cir.ptr<!u32i> 
+// CIR-NEXT: [[VALUE0:%.]] = cir.load align(4) [[VALPTR]] : !cir.ptr<!u32i>, !u32i
+// CIR-NEXT: [[MASK:%.]] = cir.const #cir.int<4> : !u32i
+// CIR-NEXT: [[VALUE1:%.]] = cir.and [[VALUE0]], [[MASK]] : !u32i
+// CIR-NEXT: [[RES:%.]] = cir.cmp eq [[VALUE1]], [[MASK]] : !u32i
+// CIR-NEXT: cir.and [[RES]], [[TRUE2]] : !cir.bool
+
+// LLVM-LABEL: define dso_local i32 @v4(
+// LLVM-SAME: ) #[[ATTR0]] {
+// LLVM-NEXT:    [[RETVAL:%.]] = alloca i32, i64 1, align 4
+// LLVM-NEXT:    [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8), align 4
+// LLVM-NEXT:    [[TMP1:%.*]] = and i32 [[TMP0]], 4
+// LLVM-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 4
+// LLVM-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], true
+// LLVM-NEXT:    [[CONV:%.*]] = zext i1 [[TMP3]] to i32
+// LLVM-NEXT:    store i32 [[CONV]], ptr [[RETVAL]], align 4
+// LLVM-NEXT:    [[RET:%.*]] = load i32, ptr [[RETVAL]], align 4
+// LLVM-NEXT:    ret i32 [[RET]]
+
+// OGCG-LABEL: define dso_local i32 @v4(
+// OGCG-SAME: ) #[[ATTR0]] {
+// OGCG-NEXT:  entry:
+// OGCG-NEXT:    [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @__cpu_features2, i64 8), align 4
+// OGCG-NEXT:    [[TMP1:%.*]] = and i32 [[TMP0]], 4
+// OGCG-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 4
+// OGCG-NEXT:    [[TMP3:%.*]] = and i1 true, [[TMP2]]
+// OGCG-NEXT:    [[CONV:%.*]] = zext i1 [[TMP3]] to i32
+// OGCG-NEXT:    ret i32 [[CONV]]
+int v4() { return __builtin_cpu_supports("x86-64-v4"); }
+



More information about the cfe-commits mailing list