[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