Author: Amr Hesham
Date: 2026-08-21T07:58:38+02:00
New Revision: 3a2130742511b3d1a1460e454cd01285fbb09841

URL: 
https://github.com/llvm/llvm-project/commit/3a2130742511b3d1a1460e454cd01285fbb09841
DIFF: 
https://github.com/llvm/llvm-project/commit/3a2130742511b3d1a1460e454cd01285fbb09841.diff

LOG: [CIR] Support Vector of bool ty in VecCmpOp (#216400)

Support the Vector of bool in VecCmpOp

Added: 
    

Modified: 
    clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
    clang/test/CIR/CodeGen/vector-bool.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 578b328b622ee..20db99f11fbef 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -4874,13 +4874,18 @@ mlir::LogicalResult 
CIRToLLVMVecInsertOpLowering::matchAndRewrite(
 mlir::LogicalResult CIRToLLVMVecCmpOpLowering::matchAndRewrite(
     cir::VecCmpOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
-  mlir::Type elementType = elementTypeIfVector(op.getLhs().getType());
+  mlir::Type elementType = op.getLhs().getType().getElementType();
   mlir::Value bitResult;
   if (auto intType = mlir::dyn_cast<cir::IntType>(elementType)) {
     bitResult = mlir::LLVM::ICmpOp::create(
         rewriter, op.getLoc(),
         convertCmpKindToICmpPredicate(op.getKind(), intType.isSigned()),
         adaptor.getLhs(), adaptor.getRhs());
+  } else if (auto boolType = mlir::dyn_cast<cir::BoolType>(elementType)) {
+    bitResult = mlir::LLVM::ICmpOp::create(
+        rewriter, op.getLoc(),
+        convertCmpKindToICmpPredicate(op.getKind(), /*isSigned=*/false),
+        adaptor.getLhs(), adaptor.getRhs());
   } else if (mlir::isa<cir::FPTypeInterface>(elementType)) {
     if (cir::FenvAttr fenv = op.getFenvAttr()) {
       auto i1VecTy = mlir::VectorType::get(op.getLhs().getType().getSize(),
@@ -4901,7 +4906,9 @@ mlir::LogicalResult 
CIRToLLVMVecCmpOpLowering::matchAndRewrite(
   // LLVM IR vector comparison returns a vector of i1. This one-bit vector
   // must be sign-extended to the correct result type, unless a vector of i1 is
   // the type we need.
-  if (cast<cir::IntType>(op.getType().getElementType()).getWidth() > 1)
+  mlir::Type vecElemTy = op.getType().getElementType();
+  if (isa<cir::IntType>(vecElemTy) &&
+      cast<cir::IntType>(vecElemTy).getWidth() > 1)
     rewriter.replaceOpWithNewOp<mlir::LLVM::SExtOp>(
         op, typeConverter->convertType(op.getType()), bitResult);
   else

diff  --git a/clang/test/CIR/CodeGen/vector-bool.cpp 
b/clang/test/CIR/CodeGen/vector-bool.cpp
index d2294e6dc383e..cae3ecdf49dac 100644
--- a/clang/test/CIR/CodeGen/vector-bool.cpp
+++ b/clang/test/CIR/CodeGen/vector-bool.cpp
@@ -252,3 +252,84 @@ void vec_bool_not_op() {
 // SHARED: %[[RESULT:.*]] = xor <8 x i1> %[[TMP_A_VEC]], splat (i1 true)
 // SHARED: %[[RESULT_I8:.*]] = bitcast <8 x i1> %[[RESULT]] to i8
 // SHARED: store i8 %[[RESULT_I8]], ptr %[[B_ADDR]], align 1
+
+void vec_bool_compare() {
+  v8b a;
+  v8b b;
+  v8b eq = a == b;
+  v8b gt = a > b;
+  v8b ge = a >= b;
+  v8b lt = a < b;
+  v8b le = a <= b;
+}
+
+// CIR: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.vector<8 x 
!cir.bool>>
+// CIR: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.vector<8 x 
!cir.bool>>
+// CIR: %[[EQ_ADDR:.*]] = cir.alloca "eq" {{.*}} init : !cir.ptr<!cir.vector<8 
x !cir.bool>>
+// CIR: %[[GT_ADDR:.*]] = cir.alloca "gt" {{.*}} init : !cir.ptr<!cir.vector<8 
x !cir.bool>>
+// CIR: %[[GE_ADDR:.*]] = cir.alloca "ge" {{.*}} init : !cir.ptr<!cir.vector<8 
x !cir.bool>>
+// CIR: %[[LT_ADDR:.*]] = cir.alloca "lt" {{.*}} init : !cir.ptr<!cir.vector<8 
x !cir.bool>>
+// CIR: %[[LE_ADDR:.*]] = cir.alloca "le" {{.*}} init : !cir.ptr<!cir.vector<8 
x !cir.bool>>
+// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.vector<8 x 
!cir.bool>>, !cir.vector<8 x !cir.bool>
+// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.vector<8 x 
!cir.bool>>, !cir.vector<8 x !cir.bool>
+// CIR: %[[EQ:.*]] = cir.vec.cmp(eq, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<8 x 
!cir.bool>, !cir.vector<8 x !cir.bool>
+// CIR: cir.store {{.*}} %[[EQ]], %[[EQ_ADDR]] : !cir.vector<8 x !cir.bool>, 
!cir.ptr<!cir.vector<8 x !cir.bool>>
+// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.vector<8 x 
!cir.bool>>, !cir.vector<8 x !cir.bool>
+// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.vector<8 x 
!cir.bool>>, !cir.vector<8 x !cir.bool>
+// CIR: %[[GT:.*]] = cir.vec.cmp(gt, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<8 x 
!cir.bool>, !cir.vector<8 x !cir.bool>
+// CIR: cir.store {{.*}} %[[GT]], %[[GT_ADDR]] : !cir.vector<8 x !cir.bool>, 
!cir.ptr<!cir.vector<8 x !cir.bool>>
+// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.vector<8 x 
!cir.bool>>, !cir.vector<8 x !cir.bool>
+// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.vector<8 x 
!cir.bool>>, !cir.vector<8 x !cir.bool>
+// CIR: %[[GE:.*]] = cir.vec.cmp(ge, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<8 x 
!cir.bool>, !cir.vector<8 x !cir.bool>
+// CIR: cir.store {{.*}} %[[GE]], %[[GE_ADDR]] : !cir.vector<8 x !cir.bool>, 
!cir.ptr<!cir.vector<8 x !cir.bool>>
+// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.vector<8 x 
!cir.bool>>, !cir.vector<8 x !cir.bool>
+// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.vector<8 x 
!cir.bool>>, !cir.vector<8 x !cir.bool>
+// CIR: %[[LT:.*]] = cir.vec.cmp(lt, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<8 x 
!cir.bool>, !cir.vector<8 x !cir.bool>
+// CIR: cir.store {{.*}} %[[LT]], %[[LT_ADDR]] : !cir.vector<8 x !cir.bool>, 
!cir.ptr<!cir.vector<8 x !cir.bool>>
+// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.vector<8 x 
!cir.bool>>, !cir.vector<8 x !cir.bool>
+// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.vector<8 x 
!cir.bool>>, !cir.vector<8 x !cir.bool>
+// CIR: %[[LE:.*]] = cir.vec.cmp(le, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<8 x 
!cir.bool>, !cir.vector<8 x !cir.bool>
+// CIR: cir.store {{.*}} %[[LE]], %[[LE_ADDR]] : !cir.vector<8 x !cir.bool>, 
!cir.ptr<!cir.vector<8 x !cir.bool>>
+
+// SHARED: %[[A_ADDR:.*]] = alloca i8, align 1
+// SHARED: %[[B_ADDR:.*]] = alloca i8, align 1
+// SHARED: %[[EQ_ADDR:.*]] = alloca i8, align 1
+// SHARED: %[[GT_ADDR:.*]] = alloca i8, align 1
+// SHARED: %[[GE_ADDR:.*]] = alloca i8, align 1
+// SHARED: %[[LT_ADDR:.*]] = alloca i8, align 1
+// SHARED: %[[LE_ADDR:.*]] = alloca i8, align 1
+// SHARED: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1
+// SHARED: %[[TMP_A_VEC:.*]] = bitcast i8 %[[TMP_A]] to <8 x i1>
+// SHARED: %[[TMP_B:.*]] = load i8, ptr %[[B_ADDR]], align 1
+// SHARED: %[[TMP_B_VEC:.*]] = bitcast i8 %[[TMP_B]] to <8 x i1>
+// SHARED: %[[EQ:.*]] = icmp eq <8 x i1> %[[TMP_A_VEC]], %[[TMP_B_VEC]]
+// SHARED: %[[EQ_I8:.*]] = bitcast <8 x i1> %[[EQ]] to i8
+// SHARED: store i8 %[[EQ_I8]], ptr %[[EQ_ADDR]], align 1
+// SHARED: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1
+// SHARED: %[[TMP_A_VEC:.*]] = bitcast i8 %[[TMP_A]] to <8 x i1>
+// SHARED: %[[TMP_B:.*]] = load i8, ptr %[[B_ADDR]], align 1
+// SHARED: %[[TMP_B_VEC:.*]] = bitcast i8 %[[TMP_B]] to <8 x i1>
+// SHARED: %[[GT:.*]] = icmp ugt <8 x i1> %[[TMP_A_VEC]], %[[TMP_B_VEC]]
+// SHARED: %[[GT_I8:.*]] = bitcast <8 x i1> %[[GT]] to i8
+// SHARED: store i8 %[[GT_I8]], ptr %[[GT_ADDR]], align 1
+// SHARED: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1
+// SHARED: %[[TMP_A_VEC:.*]] = bitcast i8 %[[TMP_A]] to <8 x i1>
+// SHARED: %[[TMP_B:.*]] = load i8, ptr %[[B_ADDR]], align 1
+// SHARED: %[[TMP_B_VEC:.*]] = bitcast i8 %[[TMP_B]] to <8 x i1>
+// SHARED: %[[GE:.*]] = icmp uge <8 x i1> %[[TMP_A_VEC]], %[[TMP_B_VEC]]
+// SHARED: %[[GE_I8:.*]] = bitcast <8 x i1> %[[GE]] to i8
+// SHARED: store i8 %[[GE_I8]], ptr %[[GE_ADDR]], align 1
+// SHARED: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1
+// SHARED: %[[TMP_A_VEC:.*]] = bitcast i8 %[[TMP_A]] to <8 x i1>
+// SHARED: %[[TMP_B:.*]] = load i8, ptr %[[B_ADDR]], align 1
+// SHARED: %[[TMP_B_VEC:.*]] = bitcast i8 %[[TMP_B]] to <8 x i1>
+// SHARED: %[[LT:.*]] = icmp ult <8 x i1> %[[TMP_A_VEC]], %[[TMP_B_VEC]]
+// SHARED: %[[LT_I8:.*]] = bitcast <8 x i1> %[[LT]] to i8
+// SHARED: store i8 %[[LT_I8]], ptr %[[LT_ADDR]], align 1
+// SHARED: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1
+// SHARED: %[[TMP_A_VEC:.*]] = bitcast i8 %[[TMP_A]] to <8 x i1>
+// SHARED: %[[TMP_B:.*]] = load i8, ptr %[[B_ADDR]], align 1
+// SHARED: %[[TMP_B_VEC:.*]] = bitcast i8 %[[TMP_B]] to <8 x i1>
+// SHARED: %[[LE:.*]] = icmp ule <8 x i1> %[[TMP_A_VEC]], %[[TMP_B_VEC]]
+// SHARED: %[[LE_I8:.*]] = bitcast <8 x i1> %[[LE]] to i8
+// SHARED: store i8 %[[LE_I8]], ptr %[[LE_ADDR]], align 1


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to