[clang] [CIR] Implement SSE packed float comparison builtins (PR #194724)

via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 28 13:59:51 PDT 2026


https://github.com/adams381 created https://github.com/llvm/llvm-project/pull/194724

`emitVectorFCmp` already handles `cmpnltps/pd` and `cmpnleps/pd`, but the non-negated and other comparison variants were NYI.  Adds cases for `cmpeqps/pd` (`oeq`), `cmpltps/pd` (`olt`), `cmpleps/pd` (`ole`), `cmpunordps/pd` (`uno`), `cmpneqps/pd` (`une`), and `cmpordps/pd` (`ord` via inverted `uno`).

Found while building the Eigen test suite with CIR — 6 of 135 test files hit these NYI builtins through `xmmintrin.h` / `emmintrin.h`.


>From 8a2c3689a3c45e62212f5c0d1ad1233309e512ec Mon Sep 17 00:00:00 2001
From: Adam Smith <adams at nvidia.com>
Date: Tue, 28 Apr 2026 13:56:20 -0700
Subject: [PATCH] [CIR] Implement SSE packed float comparison builtins

Add emitVectorFCmp cases for cmpeqps/pd, cmpltps/pd, cmpleps/pd,
cmpunordps/pd, cmpneqps/pd, and cmpordps/pd.  These were
previously NYI and hit an errorNYI diagnostic when Eigen's SSE
code paths were compiled.

The implementation reuses the existing emitVectorFCmp helper
that already handles cmpnltps/pd and cmpnleps/pd.

Made-with: Cursor
---
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 16 +++--
 clang/test/CIR/CodeGen/builtins-x86.c      | 79 ++++++++++++++++++++++
 2 files changed, 91 insertions(+), 4 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 0ec01c335d777..6ca8a0e7a460f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -2301,18 +2301,24 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) {
   case X86::BI__builtin_ia32_vpshufbitqmb512_mask:
   case X86::BI__builtin_ia32_cmpeqps:
   case X86::BI__builtin_ia32_cmpeqpd:
+    return emitVectorFCmp(*this, *expr, ops, cir::CmpOpKind::eq,
+                          /*shouldInvert=*/false);
   case X86::BI__builtin_ia32_cmpltps:
   case X86::BI__builtin_ia32_cmpltpd:
+    return emitVectorFCmp(*this, *expr, ops, cir::CmpOpKind::lt,
+                          /*shouldInvert=*/false);
   case X86::BI__builtin_ia32_cmpleps:
   case X86::BI__builtin_ia32_cmplepd:
+    return emitVectorFCmp(*this, *expr, ops, cir::CmpOpKind::le,
+                          /*shouldInvert=*/false);
   case X86::BI__builtin_ia32_cmpunordps:
   case X86::BI__builtin_ia32_cmpunordpd:
+    return emitVectorFCmp(*this, *expr, ops, cir::CmpOpKind::uno,
+                          /*shouldInvert=*/false);
   case X86::BI__builtin_ia32_cmpneqps:
   case X86::BI__builtin_ia32_cmpneqpd:
-    cgm.errorNYI(expr->getSourceRange(),
-                 std::string("unimplemented X86 builtin call: ") +
-                     getContext().BuiltinInfo.getName(builtinID));
-    return mlir::Value{};
+    return emitVectorFCmp(*this, *expr, ops, cir::CmpOpKind::ne,
+                          /*shouldInvert=*/false);
   case X86::BI__builtin_ia32_cmpnltps:
   case X86::BI__builtin_ia32_cmpnltpd:
     return emitVectorFCmp(*this, *expr, ops, cir::CmpOpKind::lt,
@@ -2323,6 +2329,8 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) {
                           /*shouldInvert=*/true);
   case X86::BI__builtin_ia32_cmpordps:
   case X86::BI__builtin_ia32_cmpordpd:
+    return emitVectorFCmp(*this, *expr, ops, cir::CmpOpKind::uno,
+                          /*shouldInvert=*/true);
   case X86::BI__builtin_ia32_cmpph128_mask:
   case X86::BI__builtin_ia32_cmpph256_mask:
   case X86::BI__builtin_ia32_cmpph512_mask:
diff --git a/clang/test/CIR/CodeGen/builtins-x86.c b/clang/test/CIR/CodeGen/builtins-x86.c
index 8511286a79723..34fe989c5a8a1 100644
--- a/clang/test/CIR/CodeGen/builtins-x86.c
+++ b/clang/test/CIR/CodeGen/builtins-x86.c
@@ -56,6 +56,85 @@ void test_clflush(void* a){
 typedef float v4f __attribute__((vector_size(16)));
 typedef int   v4i __attribute__((vector_size(16)));
 
+v4f test_cmpeqps(v4f a, v4f b) {
+  // CIR-LABEL: @test_cmpeqps
+  // CIR: cir.vec.cmp(eq, %{{.*}}, %{{.*}}) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<4 x !s32i> -> !cir.vector<4 x !cir.float>
+
+  // LLVM-LABEL: @test_cmpeqps
+  // LLVM: fcmp oeq <4 x float>
+
+  // OGCG-LABEL: @test_cmpeqps
+  // OGCG: fcmp oeq <4 x float>
+  return __builtin_ia32_cmpeqps(a, b);
+}
+
+v4f test_cmpltps(v4f a, v4f b) {
+  // CIR-LABEL: @test_cmpltps
+  // CIR: cir.vec.cmp(lt, %{{.*}}, %{{.*}}) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<4 x !s32i> -> !cir.vector<4 x !cir.float>
+
+  // LLVM-LABEL: @test_cmpltps
+  // LLVM: fcmp olt <4 x float>
+
+  // OGCG-LABEL: @test_cmpltps
+  // OGCG: fcmp olt <4 x float>
+  return __builtin_ia32_cmpltps(a, b);
+}
+
+v4f test_cmpleps(v4f a, v4f b) {
+  // CIR-LABEL: @test_cmpleps
+  // CIR: cir.vec.cmp(le, %{{.*}}, %{{.*}}) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<4 x !s32i> -> !cir.vector<4 x !cir.float>
+
+  // LLVM-LABEL: @test_cmpleps
+  // LLVM: fcmp ole <4 x float>
+
+  // OGCG-LABEL: @test_cmpleps
+  // OGCG: fcmp ole <4 x float>
+  return __builtin_ia32_cmpleps(a, b);
+}
+
+v4f test_cmpunordps(v4f a, v4f b) {
+  // CIR-LABEL: @test_cmpunordps
+  // CIR: cir.vec.cmp(uno, %{{.*}}, %{{.*}}) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<4 x !s32i> -> !cir.vector<4 x !cir.float>
+
+  // LLVM-LABEL: @test_cmpunordps
+  // LLVM: fcmp uno <4 x float>
+
+  // OGCG-LABEL: @test_cmpunordps
+  // OGCG: fcmp uno <4 x float>
+  return __builtin_ia32_cmpunordps(a, b);
+}
+
+v4f test_cmpordps(v4f a, v4f b) {
+  // CIR-LABEL: @test_cmpordps
+  // CIR: cir.vec.cmp(uno, %{{.*}}, %{{.*}}) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i>
+  // CIR: cir.not %{{.*}} : !cir.vector<4 x !s32i>
+
+  // LLVM-LABEL: @test_cmpordps
+  // LLVM: fcmp uno <4 x float>
+  // LLVM: xor <4 x i32> %{{.*}}, splat (i32 -1)
+
+  // OGCG-LABEL: @test_cmpordps
+  // OGCG: fcmp ord <4 x float>
+  return __builtin_ia32_cmpordps(a, b);
+}
+
+v4f test_cmpneqps(v4f a, v4f b) {
+  // CIR-LABEL: @test_cmpneqps
+  // CIR: cir.vec.cmp(ne, %{{.*}}, %{{.*}}) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<4 x !s32i> -> !cir.vector<4 x !cir.float>
+
+  // LLVM-LABEL: @test_cmpneqps
+  // LLVM: fcmp une <4 x float>
+
+  // OGCG-LABEL: @test_cmpneqps
+  // OGCG: fcmp une <4 x float>
+  return __builtin_ia32_cmpneqps(a, b);
+}
+
 v4i test_convertvector(v4f a) {
   // CIR-LABEL: test_convertvector
   // CIR: cir.cast float_to_int %{{.*}} : !cir.vector<4 x !cir.float> -> !cir.vector<4 x !s32i>



More information about the cfe-commits mailing list