[clang] [CIR] Support fp strict for vector logical and, or ops (PR #221808)

Amr Hesham via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 8 10:54:16 PDT 2026


https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/221808

>From 9e5386f0f5729d4b503a888077804550f9fa77ed Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Mon, 7 Sep 2026 21:04:17 +0200
Subject: [PATCH 1/3] [CIR] Support fp strict for vector logical and, or ops

---
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp  | 16 ++--
 clang/test/CIR/CodeGen/vector-strict-fp.cpp | 92 +++++++++++++++++++--
 2 files changed, 92 insertions(+), 16 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index f7a39a9b4a8c9..fb833241c1f81 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1332,11 +1332,9 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
       mlir::Value rhs = Visit(e->getRHS());
 
       auto cmpOpKind = cir::CmpOpKind::ne;
-      mlir::Type resTy = cgf.convertType(e->getType());
-      lhs = cir::VecCmpOp::create(builder, loc, resTy, cmpOpKind, lhs, zeroVec);
-      rhs = cir::VecCmpOp::create(builder, loc, resTy, cmpOpKind, rhs, zeroVec);
-      mlir::Value vecOr = builder.createAnd(loc, lhs, rhs);
-      return builder.createIntCast(vecOr, resTy);
+      lhs = builder.createVecCompare(loc, cmpOpKind, lhs, zeroVec);
+      rhs = builder.createVecCompare(loc, cmpOpKind, rhs, zeroVec);
+      return builder.createAnd(loc, lhs, rhs);
     }
 
     assert(!cir::MissingFeatures::instrumentation());
@@ -1377,11 +1375,9 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
       mlir::Value rhs = Visit(e->getRHS());
 
       auto cmpOpKind = cir::CmpOpKind::ne;
-      mlir::Type resTy = cgf.convertType(e->getType());
-      lhs = cir::VecCmpOp::create(builder, loc, resTy, cmpOpKind, lhs, zeroVec);
-      rhs = cir::VecCmpOp::create(builder, loc, resTy, cmpOpKind, rhs, zeroVec);
-      mlir::Value vecOr = builder.createOr(loc, lhs, rhs);
-      return builder.createIntCast(vecOr, resTy);
+      lhs = builder.createVecCompare(loc, cmpOpKind, lhs, zeroVec);
+      rhs = builder.createVecCompare(loc, cmpOpKind, rhs, zeroVec);
+      return builder.createOr(loc, lhs, rhs);
     }
 
     assert(!cir::MissingFeatures::instrumentation());
diff --git a/clang/test/CIR/CodeGen/vector-strict-fp.cpp b/clang/test/CIR/CodeGen/vector-strict-fp.cpp
index 340834200d899..35f637f45530a 100644
--- a/clang/test/CIR/CodeGen/vector-strict-fp.cpp
+++ b/clang/test/CIR/CodeGen/vector-strict-fp.cpp
@@ -1,9 +1,9 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -ffp-contract=on -fexperimental-strict-floating-point -ffp-exception-behavior=strict -fclangir -emit-cir %s -o %t.cir
 // RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -ffp-contract=on -fexperimental-strict-floating-point -ffp-exception-behavior=strict -fclangir -emit-llvm %s -o %t-cir.ll
-// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefixes=LLVM,SHARED
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -ffp-contract=on -fexperimental-strict-floating-point -ffp-exception-behavior=strict -emit-llvm %s -o %t.ll
-// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+// RUN: FileCheck --input-file=%t.ll %s -check-prefixes=OGCG,SHARED
 
 typedef float v4f __attribute__((ext_vector_type(4)));
 typedef int v4i __attribute__((ext_vector_type(4)));
@@ -20,9 +20,89 @@ void vec_logical_not() {
 // CIR: %[[RESULT:.*]] = cir.vec.cmp(eq, %[[TMP_A]], %[[CONST_ZERO]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> {fenv = #cir.fenv<dynamic_rounding_mode = tonearest, except_mode = unknown, strict_except = true>}
 // CIR: cir.store {{.*}} %[[RESULT]], %[[B_ADDR]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
 
+// SHARED: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
+// SHARED: %[[B_ADDR:.*]] = alloca <4 x i32>, align 16
+// SHARED: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
+// SHARED: %[[RESULT:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"oeq", metadata !"fpexcept.strict")
+// SHARED: %[[RESULT_V4I:.*]] = sext <4 x i1> %[[RESULT]] to <4 x i32>
+// SHARED: store <4 x i32> %[[RESULT_V4I]], ptr %[[B_ADDR]], align 16
+
+void vec_logical_or() {
+  v4f a;
+  v4f b;
+  v4i r = a || b;
+}
+
+// CIR: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.vector<4 x !cir.float>>
+// CIR: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.vector<4 x !cir.float>>
+// CIR: %[[R_ADDR:.*]] = cir.alloca "r" {{.*}} init : !cir.ptr<!cir.vector<4 x !s32i>>
+// CIR: %[[CONST_ZERO:.*]] = cir.const #cir.zero : !cir.vector<4 x !cir.float>
+// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float>
+// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float>
+// CIR: %[[A_NE_ZERO:.*]] = cir.vec.cmp(ne, %[[TMP_A]], %[[CONST_ZERO]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> {fenv = #cir.fenv<dynamic_rounding_mode = tonearest, except_mode = unknown, strict_except = true>}
+// CIR: %[[B_NE_ZERO:.*]] = cir.vec.cmp(ne, %[[TMP_B]], %[[CONST_ZERO]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> {fenv = #cir.fenv<dynamic_rounding_mode = tonearest, except_mode = unknown, strict_except = true>}
+// CIR: %[[RESULT:.*]] = cir.or %[[A_NE_ZERO]], %[[B_NE_ZERO]] : !cir.vector<4 x !s32i>
+// CIR: cir.store {{.*}} %[[RESULT]], %[[R_ADDR]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
+
+// LLVM: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
+// LLVM: %[[B_ADDR:.*]] = alloca <4 x float>, align 16
+// LLVM: %[[R_ADDR:.*]] = alloca <4 x i32>, align 16
+// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
+// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16
+// LLVM: %[[A_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict")
+// LLVM: %[[A_NE_ZERO_VEC:.*]] = sext <4 x i1> %[[A_NE_ZERO]] to <4 x i32>
+// LLVM: %[[B_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_B]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict")
+// LLVM: %[[B_NE_ZERO_VEC:.*]] = sext <4 x i1> %[[B_NE_ZERO]] to <4 x i32>
+// LLVM: %[[RESULT:.*]] = or <4 x i32> %[[A_NE_ZERO_VEC]], %[[B_NE_ZERO_VEC]]
+// LLVM: store <4 x i32> %[[RESULT]], ptr %[[R_ADDR]], align 16
+
+// OGCG: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
+// OGCG: %[[B_ADDR:.*]] = alloca <4 x float>, align 16
+// OGCG: %[[R_ADDR:.*]] = alloca <4 x i32>, align 16
+// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
+// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16
+// OGCG: %[[A_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict")
+// OGCG: %[[B_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_B]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict")
+// OGCG: %[[RESULT:.*]] = or <4 x i1> %[[A_NE_ZERO]], %[[B_NE_ZERO]]
+// OGCG: %[[RESULT_VEC:.*]] = sext <4 x i1> %2 to <4 x i32>
+// OGCG: store <4 x i32> %[[RESULT_VEC]], ptr %[[R_ADDR]], align 16
+
+void vec_logical_and() {
+  v4f a;
+  v4f b;
+  v4i r = a && b;
+}
+
+// CIR: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.vector<4 x !cir.float>>
+// CIR: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.vector<4 x !cir.float>>
+// CIR: %[[R_ADDR:.*]] = cir.alloca "r" {{.*}} init : !cir.ptr<!cir.vector<4 x !s32i>>
+// CIR: %[[CONST_ZERO:.*]] = cir.const #cir.zero : !cir.vector<4 x !cir.float>
+// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float>
+// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float>
+// CIR: %[[A_NE_ZERO:.*]] = cir.vec.cmp(ne, %[[TMP_A]], %[[CONST_ZERO]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> {fenv = #cir.fenv<dynamic_rounding_mode = tonearest, except_mode = unknown, strict_except = true>}
+// CIR: %[[B_NE_ZERO:.*]] = cir.vec.cmp(ne, %[[TMP_B]], %[[CONST_ZERO]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> {fenv = #cir.fenv<dynamic_rounding_mode = tonearest, except_mode = unknown, strict_except = true>}
+// CIR: %[[RESULT:.*]] = cir.and %[[A_NE_ZERO]], %[[B_NE_ZERO]] : !cir.vector<4 x !s32i>
+// CIR: cir.store {{.*}} %[[RESULT]], %[[R_ADDR]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
+
 // LLVM: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
-// LLVM: %[[B_ADDR:.*]] = alloca <4 x i32>, align 16
+// LLVM: %[[B_ADDR:.*]] = alloca <4 x float>, align 16
+// LLVM: %[[R_ADDR:.*]] = alloca <4 x i32>, align 16
 // LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
-// LLVM: %[[RESULT:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"oeq", metadata !"fpexcept.strict")
-// LLVM: %[[RESULT_V4I:.*]] = sext <4 x i1> %[[RESULT]] to <4 x i32>
-// LLVM: store <4 x i32> %[[RESULT_V4I]], ptr %[[B_ADDR]], align 16
+// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16
+// LLVM: %[[A_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict")
+// LLVM: %[[A_NE_ZERO_VEC:.*]] = sext <4 x i1> %[[A_NE_ZERO]] to <4 x i32>
+// LLVM: %[[B_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_B]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict")
+// LLVM: %[[B_NE_ZERO_VEC:.*]] = sext <4 x i1> %[[B_NE_ZERO]] to <4 x i32>
+// LLVM: %[[RESULT:.*]] = and <4 x i32> %[[A_NE_ZERO_VEC]], %[[B_NE_ZERO_VEC]]
+// LLVM: store <4 x i32> %[[RESULT]], ptr %[[R_ADDR]], align 16
+
+// OGCG: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
+// OGCG: %[[B_ADDR:.*]] = alloca <4 x float>, align 16
+// OGCG: %[[R_ADDR:.*]] = alloca <4 x i32>, align 16
+// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
+// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16
+// OGCG: %[[A_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict") #2
+// OGCG: %[[B_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_B]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict") #2
+// OGCG: %[[RESULT:.*]] = and <4 x i1> %[[A_NE_ZERO]], %[[B_NE_ZERO]]
+// OGCG: %[[RESULT_VEC:.*]] = sext <4 x i1> %2 to <4 x i32>
+// OGCG: store <4 x i32> %[[RESULT_VEC]], ptr %[[R_ADDR]], align 16

>From 8dacaeb8bdb8194a094d5631e0b996631cfdc194 Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Tue, 8 Sep 2026 19:31:04 +0200
Subject: [PATCH 2/3] Remove merge prefixes

---
 clang/test/CIR/CodeGen/vector-strict-fp.cpp | 23 ++++++++++++++-------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/clang/test/CIR/CodeGen/vector-strict-fp.cpp b/clang/test/CIR/CodeGen/vector-strict-fp.cpp
index 35f637f45530a..65dfbb1190455 100644
--- a/clang/test/CIR/CodeGen/vector-strict-fp.cpp
+++ b/clang/test/CIR/CodeGen/vector-strict-fp.cpp
@@ -1,9 +1,9 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -ffp-contract=on -fexperimental-strict-floating-point -ffp-exception-behavior=strict -fclangir -emit-cir %s -o %t.cir
 // RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -ffp-contract=on -fexperimental-strict-floating-point -ffp-exception-behavior=strict -fclangir -emit-llvm %s -o %t-cir.ll
-// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefixes=LLVM,SHARED
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -ffp-contract=on -fexperimental-strict-floating-point -ffp-exception-behavior=strict -emit-llvm %s -o %t.ll
-// RUN: FileCheck --input-file=%t.ll %s -check-prefixes=OGCG,SHARED
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
 
 typedef float v4f __attribute__((ext_vector_type(4)));
 typedef int v4i __attribute__((ext_vector_type(4)));
@@ -20,12 +20,19 @@ void vec_logical_not() {
 // CIR: %[[RESULT:.*]] = cir.vec.cmp(eq, %[[TMP_A]], %[[CONST_ZERO]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> {fenv = #cir.fenv<dynamic_rounding_mode = tonearest, except_mode = unknown, strict_except = true>}
 // CIR: cir.store {{.*}} %[[RESULT]], %[[B_ADDR]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
 
-// SHARED: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
-// SHARED: %[[B_ADDR:.*]] = alloca <4 x i32>, align 16
-// SHARED: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
-// SHARED: %[[RESULT:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"oeq", metadata !"fpexcept.strict")
-// SHARED: %[[RESULT_V4I:.*]] = sext <4 x i1> %[[RESULT]] to <4 x i32>
-// SHARED: store <4 x i32> %[[RESULT_V4I]], ptr %[[B_ADDR]], align 16
+// LLVM: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
+// LLVM: %[[B_ADDR:.*]] = alloca <4 x i32>, align 16
+// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
+// LLVM: %[[RESULT:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"oeq", metadata !"fpexcept.strict")
+// LLVM: %[[RESULT_V4I:.*]] = sext <4 x i1> %[[RESULT]] to <4 x i32>
+// LLVM: store <4 x i32> %[[RESULT_V4I]], ptr %[[B_ADDR]], align 16
+
+// OGCG: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
+// OGCG: %[[B_ADDR:.*]] = alloca <4 x i32>, align 16
+// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
+// OGCG: %[[RESULT:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"oeq", metadata !"fpexcept.strict")
+// OGCG: %[[RESULT_V4I:.*]] = sext <4 x i1> %[[RESULT]] to <4 x i32>
+// OGCG: store <4 x i32> %[[RESULT_V4I]], ptr %[[B_ADDR]], align 16
 
 void vec_logical_or() {
   v4f a;

>From 7d6a782180f56a4808dd859c9384a789f4da7bc8 Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Tue, 8 Sep 2026 19:53:57 +0200
Subject: [PATCH 3/3] Merge shared part in the test

---
 clang/test/CIR/CodeGen/vector-strict-fp.cpp | 79 ++++++++++-----------
 1 file changed, 36 insertions(+), 43 deletions(-)

diff --git a/clang/test/CIR/CodeGen/vector-strict-fp.cpp b/clang/test/CIR/CodeGen/vector-strict-fp.cpp
index 65dfbb1190455..3034949bc5adf 100644
--- a/clang/test/CIR/CodeGen/vector-strict-fp.cpp
+++ b/clang/test/CIR/CodeGen/vector-strict-fp.cpp
@@ -1,9 +1,9 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -ffp-contract=on -fexperimental-strict-floating-point -ffp-exception-behavior=strict -fclangir -emit-cir %s -o %t.cir
 // RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -ffp-contract=on -fexperimental-strict-floating-point -ffp-exception-behavior=strict -fclangir -emit-llvm %s -o %t-cir.ll
-// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefixes=LLVM,SHARED
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -ffp-contract=on -fexperimental-strict-floating-point -ffp-exception-behavior=strict -emit-llvm %s -o %t.ll
-// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+// RUN: FileCheck --input-file=%t.ll %s -check-prefixes=OGCG,SHARED
 
 typedef float v4f __attribute__((ext_vector_type(4)));
 typedef int v4i __attribute__((ext_vector_type(4)));
@@ -20,19 +20,12 @@ void vec_logical_not() {
 // CIR: %[[RESULT:.*]] = cir.vec.cmp(eq, %[[TMP_A]], %[[CONST_ZERO]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> {fenv = #cir.fenv<dynamic_rounding_mode = tonearest, except_mode = unknown, strict_except = true>}
 // CIR: cir.store {{.*}} %[[RESULT]], %[[B_ADDR]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
 
-// LLVM: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
-// LLVM: %[[B_ADDR:.*]] = alloca <4 x i32>, align 16
-// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
-// LLVM: %[[RESULT:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"oeq", metadata !"fpexcept.strict")
-// LLVM: %[[RESULT_V4I:.*]] = sext <4 x i1> %[[RESULT]] to <4 x i32>
-// LLVM: store <4 x i32> %[[RESULT_V4I]], ptr %[[B_ADDR]], align 16
-
-// OGCG: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
-// OGCG: %[[B_ADDR:.*]] = alloca <4 x i32>, align 16
-// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
-// OGCG: %[[RESULT:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"oeq", metadata !"fpexcept.strict")
-// OGCG: %[[RESULT_V4I:.*]] = sext <4 x i1> %[[RESULT]] to <4 x i32>
-// OGCG: store <4 x i32> %[[RESULT_V4I]], ptr %[[B_ADDR]], align 16
+// SHARED: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
+// SHARED: %[[B_ADDR:.*]] = alloca <4 x i32>, align 16
+// SHARED: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
+// SHARED: %[[RESULT:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"oeq", metadata !"fpexcept.strict")
+// SHARED: %[[RESULT_V4I:.*]] = sext <4 x i1> %[[RESULT]] to <4 x i32>
+// SHARED: store <4 x i32> %[[RESULT_V4I]], ptr %[[B_ADDR]], align 16
 
 void vec_logical_or() {
   v4f a;
@@ -51,28 +44,28 @@ void vec_logical_or() {
 // CIR: %[[RESULT:.*]] = cir.or %[[A_NE_ZERO]], %[[B_NE_ZERO]] : !cir.vector<4 x !s32i>
 // CIR: cir.store {{.*}} %[[RESULT]], %[[R_ADDR]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
 
-// LLVM: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
-// LLVM: %[[B_ADDR:.*]] = alloca <4 x float>, align 16
-// LLVM: %[[R_ADDR:.*]] = alloca <4 x i32>, align 16
-// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
-// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16
+// SHARED: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
+// SHARED: %[[B_ADDR:.*]] = alloca <4 x float>, align 16
+// SHARED: %[[R_ADDR:.*]] = alloca <4 x i32>, align 16
+// SHARED: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
+// SHARED: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16
+
+// In CIR IR vec compare will perform sext cast -> logical or
+
 // LLVM: %[[A_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict")
 // LLVM: %[[A_NE_ZERO_VEC:.*]] = sext <4 x i1> %[[A_NE_ZERO]] to <4 x i32>
 // LLVM: %[[B_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_B]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict")
 // LLVM: %[[B_NE_ZERO_VEC:.*]] = sext <4 x i1> %[[B_NE_ZERO]] to <4 x i32>
-// LLVM: %[[RESULT:.*]] = or <4 x i32> %[[A_NE_ZERO_VEC]], %[[B_NE_ZERO_VEC]]
-// LLVM: store <4 x i32> %[[RESULT]], ptr %[[R_ADDR]], align 16
-
-// OGCG: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
-// OGCG: %[[B_ADDR:.*]] = alloca <4 x float>, align 16
-// OGCG: %[[R_ADDR:.*]] = alloca <4 x i32>, align 16
-// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
-// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16
+// LLVM: %[[RESULT_VEC:.*]] = or <4 x i32> %[[A_NE_ZERO_VEC]], %[[B_NE_ZERO_VEC]]
+
+// In OG it's perform compare -> logical or -> sext
+
 // OGCG: %[[A_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict")
 // OGCG: %[[B_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_B]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict")
 // OGCG: %[[RESULT:.*]] = or <4 x i1> %[[A_NE_ZERO]], %[[B_NE_ZERO]]
 // OGCG: %[[RESULT_VEC:.*]] = sext <4 x i1> %2 to <4 x i32>
-// OGCG: store <4 x i32> %[[RESULT_VEC]], ptr %[[R_ADDR]], align 16
+
+// SHARED: store <4 x i32> %[[RESULT_VEC]], ptr %[[R_ADDR]], align 16
 
 void vec_logical_and() {
   v4f a;
@@ -91,25 +84,25 @@ void vec_logical_and() {
 // CIR: %[[RESULT:.*]] = cir.and %[[A_NE_ZERO]], %[[B_NE_ZERO]] : !cir.vector<4 x !s32i>
 // CIR: cir.store {{.*}} %[[RESULT]], %[[R_ADDR]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
 
-// LLVM: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
-// LLVM: %[[B_ADDR:.*]] = alloca <4 x float>, align 16
-// LLVM: %[[R_ADDR:.*]] = alloca <4 x i32>, align 16
-// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
-// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16
+// SHARED: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
+// SHARED: %[[B_ADDR:.*]] = alloca <4 x float>, align 16
+// SHARED: %[[R_ADDR:.*]] = alloca <4 x i32>, align 16
+// SHARED: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
+// SHARED: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16
+
+// In CIR IR vec compare will perform sext cast -> logical and
+
 // LLVM: %[[A_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict")
 // LLVM: %[[A_NE_ZERO_VEC:.*]] = sext <4 x i1> %[[A_NE_ZERO]] to <4 x i32>
 // LLVM: %[[B_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_B]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict")
 // LLVM: %[[B_NE_ZERO_VEC:.*]] = sext <4 x i1> %[[B_NE_ZERO]] to <4 x i32>
-// LLVM: %[[RESULT:.*]] = and <4 x i32> %[[A_NE_ZERO_VEC]], %[[B_NE_ZERO_VEC]]
-// LLVM: store <4 x i32> %[[RESULT]], ptr %[[R_ADDR]], align 16
-
-// OGCG: %[[A_ADDR:.*]] = alloca <4 x float>, align 16
-// OGCG: %[[B_ADDR:.*]] = alloca <4 x float>, align 16
-// OGCG: %[[R_ADDR:.*]] = alloca <4 x i32>, align 16
-// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16
-// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16
+// LLVM: %[[RESULT_VEC:.*]] = and <4 x i32> %[[A_NE_ZERO_VEC]], %[[B_NE_ZERO_VEC]]
+
+// In OG it's perform compare -> logical and -> sext
+
 // OGCG: %[[A_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_A]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict") #2
 // OGCG: %[[B_NE_ZERO:.*]] = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float> %[[TMP_B]], <4 x float> zeroinitializer, metadata !"une", metadata !"fpexcept.strict") #2
 // OGCG: %[[RESULT:.*]] = and <4 x i1> %[[A_NE_ZERO]], %[[B_NE_ZERO]]
 // OGCG: %[[RESULT_VEC:.*]] = sext <4 x i1> %2 to <4 x i32>
-// OGCG: store <4 x i32> %[[RESULT_VEC]], ptr %[[R_ADDR]], align 16
+
+// SHARED: store <4 x i32> %[[RESULT_VEC]], ptr %[[R_ADDR]], align 16



More information about the cfe-commits mailing list