llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Morris Hafner (mmha)

<details>
<summary>Changes</summary>

This patch adds support for comparison operators with ClangIR, both integral 
and floating point.

---

Patch is 22.42 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/133159.diff


7 Files Affected:

- (modified) clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h (+5) 
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+44) 
- (modified) clang/include/clang/CIR/MissingFeatures.h (-1) 
- (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+83) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+92-2) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h (+14) 
- (added) clang/test/CIR/CodeGen/cmp.cpp (+233) 


``````````diff
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index ac7658276ec37..b94e9f8490be5 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -265,6 +265,11 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
     return createAdd(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
   }
 
+  cir::CmpOp createCompare(mlir::Location loc, cir::CmpOpKind kind,
+                           mlir::Value lhs, mlir::Value rhs) {
+    return create<cir::CmpOp>(loc, getBoolTy(), kind, lhs, rhs);
+  }
+
   //
   // Block handling helpers
   // ----------------------
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 455cc2b8b0277..3fba7566e9f1b 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -826,6 +826,50 @@ def ForOp : CIR_Op<"for", [LoopOpInterface, 
NoRegionArguments]> {
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// CmpOp
+//===----------------------------------------------------------------------===//
+
+def CmpOpKind_LT : I32EnumAttrCase<"lt", 1>;
+def CmpOpKind_LE : I32EnumAttrCase<"le", 2>;
+def CmpOpKind_GT : I32EnumAttrCase<"gt", 3>;
+def CmpOpKind_GE : I32EnumAttrCase<"ge", 4>;
+def CmpOpKind_EQ : I32EnumAttrCase<"eq", 5>;
+def CmpOpKind_NE : I32EnumAttrCase<"ne", 6>;
+
+def CmpOpKind : I32EnumAttr<
+    "CmpOpKind",
+    "compare operation kind",
+    [CmpOpKind_LT, CmpOpKind_LE, CmpOpKind_GT,
+     CmpOpKind_GE, CmpOpKind_EQ, CmpOpKind_NE]> {
+  let cppNamespace = "::cir";
+}
+
+def CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> {
+
+  let summary = "Compare values two values and produce a boolean result";
+  let description = [{
+    `cir.cmp` compares two input operands of the same type and produces a
+    `cir.bool` result. The kinds of comparison available are:
+    [lt,gt,ge,eq,ne]
+
+    ```mlir
+    %7 = cir.cmp(gt, %1, %2) : i32, !cir.bool
+    ```
+  }];
+
+  let results = (outs CIR_BoolType:$result);
+  let arguments = (ins Arg<CmpOpKind, "cmp kind">:$kind,
+                       CIR_AnyType:$lhs, CIR_AnyType:$rhs);
+
+  let assemblyFormat = [{
+    `(` $kind `,` $lhs `,` $rhs  `)` `:` type($lhs) `,` type($result) attr-dict
+  }];
+
+  // Already covered by the traits
+  let hasVerifier = 0;
+}
+
 
//===----------------------------------------------------------------------===//
 // BinOp
 
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index 3a102d90aba8f..6e93f50ac83e6 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -89,7 +89,6 @@ struct MissingFeatures {
   static bool opGlobalViewAttr() { return false; }
   static bool lowerModeOptLevel() { return false; }
   static bool opTBAA() { return false; }
-  static bool opCmp() { return false; }
   static bool objCLifetime() { return false; }
   static bool emitNullabilityCheck() { return false; }
   static bool astVarDeclInterface() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 52bd3b2933744..992c92635369d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -710,6 +710,89 @@ class ScalarExprEmitter : public 
StmtVisitor<ScalarExprEmitter, mlir::Value> {
   HANDLEBINOP(Xor)
   HANDLEBINOP(Or)
 #undef HANDLEBINOP
+
+  mlir::Value emitCmp(const BinaryOperator *e) {
+    mlir::Value result;
+    QualType lhsTy = e->getLHS()->getType();
+    QualType rhsTy = e->getRHS()->getType();
+
+    auto clangCmpToCIRCmp =
+        [](clang::BinaryOperatorKind clangCmp) -> cir::CmpOpKind {
+      switch (clangCmp) {
+      case BO_LT:
+        return cir::CmpOpKind::lt;
+      case BO_GT:
+        return cir::CmpOpKind::gt;
+      case BO_LE:
+        return cir::CmpOpKind::le;
+      case BO_GE:
+        return cir::CmpOpKind::ge;
+      case BO_EQ:
+        return cir::CmpOpKind::eq;
+      case BO_NE:
+        return cir::CmpOpKind::ne;
+      default:
+        llvm_unreachable("unsupported comparison kind");
+      }
+    };
+
+    if (lhsTy->getAs<MemberPointerType>()) {
+      assert(e->getOpcode() == BO_EQ || e->getOpcode() == BO_NE);
+      mlir::Value lhs = cgf.emitScalarExpr(e->getLHS());
+      mlir::Value rhs = cgf.emitScalarExpr(e->getRHS());
+      cir::CmpOpKind kind = clangCmpToCIRCmp(e->getOpcode());
+      result =
+          builder.createCompare(cgf.getLoc(e->getExprLoc()), kind, lhs, rhs);
+    } else if (!lhsTy->isAnyComplexType() && !rhsTy->isAnyComplexType()) {
+      BinOpInfo boInfo = emitBinOps(e);
+      mlir::Value lhs = boInfo.lhs;
+      mlir::Value rhs = boInfo.rhs;
+
+      if (lhsTy->isVectorType()) {
+        assert(!cir::MissingFeatures::vectorType());
+        cgf.cgm.errorNYI(boInfo.loc, "vector comparisons");
+        result = builder.getBool(false, cgf.getLoc(boInfo.loc));
+      } else if (boInfo.isFixedPointOp()) {
+        assert(!cir::MissingFeatures::fixedPointType());
+        cgf.cgm.errorNYI(boInfo.loc, "fixed point comparisons");
+        result = builder.getBool(false, cgf.getLoc(boInfo.loc));
+      } else if (lhsTy->hasSignedIntegerRepresentation()) {
+        cir::CmpOpKind kind = clangCmpToCIRCmp(e->getOpcode());
+        result = builder.createCompare(cgf.getLoc(boInfo.loc), kind, lhs, rhs);
+      } else {
+        // Unsigned integers and pointers.
+        if (cgf.cgm.getCodeGenOpts().StrictVTablePointers &&
+            mlir::isa<cir::PointerType>(lhs.getType()) &&
+            mlir::isa<cir::PointerType>(rhs.getType())) {
+          cgf.cgm.errorNYI(boInfo.loc, "strict vtable pointer comparisons");
+          result = builder.getBool(false, cgf.getLoc(boInfo.loc));
+        }
+
+        cir::CmpOpKind kind = clangCmpToCIRCmp(e->getOpcode());
+        result = builder.createCompare(cgf.getLoc(boInfo.loc), kind, lhs, rhs);
+      }
+    } else {
+      // Complex Comparison: can only be an equality comparison.
+      assert(!cir::MissingFeatures::complexType());
+      const mlir::Location loc = cgf.getLoc(e->getSourceRange());
+      cgf.cgm.errorNYI(loc, "complex comparison");
+      result = builder.getBool(false, loc);
+    }
+
+    return emitScalarConversion(result, cgf.getContext().BoolTy, e->getType(),
+                                e->getExprLoc());
+  }
+
+// Comparisons.
+#define VISITCOMP(CODE)                                                        
\
+  mlir::Value VisitBin##CODE(const BinaryOperator *E) { return emitCmp(E); }
+  VISITCOMP(LT)
+  VISITCOMP(GT)
+  VISITCOMP(LE)
+  VISITCOMP(GE)
+  VISITCOMP(EQ)
+  VISITCOMP(NE)
+#undef VISITCOMP
 };
 
 LValue ScalarExprEmitter::emitCompoundAssignLValue(
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 1c2b9ad05a132..f58e1cb21bb49 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -20,6 +20,7 @@
 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
 #include "mlir/IR/BuiltinDialect.h"
 #include "mlir/IR/BuiltinOps.h"
+#include "mlir/IR/Types.h"
 #include "mlir/Pass/Pass.h"
 #include "mlir/Pass/PassManager.h"
 #include "mlir/Target/LLVMIR/Dialect/Builtin/BuiltinToLLVMIRTranslation.h"
@@ -514,9 +515,17 @@ mlir::LogicalResult 
CIRToLLVMCastOpLowering::matchAndRewrite(
     assert(!MissingFeatures::cxxABI());
     assert(!MissingFeatures::dataMemberType());
     break;
-  case cir::CastKind::ptr_to_bool:
-    assert(!cir::MissingFeatures::opCmp());
+  case cir::CastKind::ptr_to_bool: {
+    auto zero =
+        mlir::IntegerAttr::get(mlir::IntegerType::get(getContext(), 64), 0);
+    auto null = rewriter.create<cir::ConstantOp>(
+        castOp.getLoc(), castOp.getSrc().getType(),
+        cir::ConstPtrAttr::get(getContext(), castOp.getSrc().getType(), zero));
+    rewriter.replaceOpWithNewOp<cir::CmpOp>(
+        castOp, cir::BoolType::get(getContext()), cir::CmpOpKind::ne,
+        castOp.getSrc(), null);
     break;
+  }
   case cir::CastKind::address_space: {
     mlir::Type dstTy = castOp.getType();
     mlir::Value llvmSrcVal = adaptor.getOperands().front();
@@ -1117,6 +1126,86 @@ mlir::LogicalResult 
CIRToLLVMBinOpLowering::matchAndRewrite(
   return mlir::LogicalResult::success();
 }
 
+/// Convert from a CIR comparison kind to an LLVM IR integral comparison kind.
+static mlir::LLVM::ICmpPredicate
+convertCmpKindToICmpPredicate(cir::CmpOpKind kind, bool isSigned) {
+  using CIR = cir::CmpOpKind;
+  using LLVMICmp = mlir::LLVM::ICmpPredicate;
+  switch (kind) {
+  case CIR::eq:
+    return LLVMICmp::eq;
+  case CIR::ne:
+    return LLVMICmp::ne;
+  case CIR::lt:
+    return (isSigned ? LLVMICmp::slt : LLVMICmp::ult);
+  case CIR::le:
+    return (isSigned ? LLVMICmp::sle : LLVMICmp::ule);
+  case CIR::gt:
+    return (isSigned ? LLVMICmp::sgt : LLVMICmp::ugt);
+  case CIR::ge:
+    return (isSigned ? LLVMICmp::sge : LLVMICmp::uge);
+  }
+  llvm_unreachable("Unknown CmpOpKind");
+}
+
+/// Convert from a CIR comparison kind to an LLVM IR floating-point comparison
+/// kind.
+static mlir::LLVM::FCmpPredicate
+convertCmpKindToFCmpPredicate(cir::CmpOpKind kind) {
+  using CIR = cir::CmpOpKind;
+  using LLVMFCmp = mlir::LLVM::FCmpPredicate;
+  switch (kind) {
+  case CIR::eq:
+    return LLVMFCmp::oeq;
+  case CIR::ne:
+    return LLVMFCmp::une;
+  case CIR::lt:
+    return LLVMFCmp::olt;
+  case CIR::le:
+    return LLVMFCmp::ole;
+  case CIR::gt:
+    return LLVMFCmp::ogt;
+  case CIR::ge:
+    return LLVMFCmp::oge;
+  }
+  llvm_unreachable("Unknown CmpOpKind");
+}
+
+mlir::LogicalResult CIRToLLVMCmpOpLowering::matchAndRewrite(
+    cir::CmpOp cmpOp, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  mlir::Type type = cmpOp.getLhs().getType();
+
+  assert(!cir::MissingFeatures::dataMemberType());
+  assert(!cir::MissingFeatures::methodType());
+
+  // Lower to LLVM comparison op.
+  if (mlir::isa<cir::IntType, mlir::IntegerType>(type)) {
+    bool isSigned = mlir::isa<cir::IntType>(type)
+                        ? mlir::cast<cir::IntType>(type).isSigned()
+                        : mlir::cast<mlir::IntegerType>(type).isSigned();
+    mlir::LLVM::ICmpPredicate kind =
+        convertCmpKindToICmpPredicate(cmpOp.getKind(), isSigned);
+    rewriter.replaceOpWithNewOp<mlir::LLVM::ICmpOp>(
+        cmpOp, kind, adaptor.getLhs(), adaptor.getRhs());
+  } else if (auto ptrTy = mlir::dyn_cast<cir::PointerType>(type)) {
+    mlir::LLVM::ICmpPredicate kind =
+        convertCmpKindToICmpPredicate(cmpOp.getKind(),
+                                      /* isSigned=*/false);
+    rewriter.replaceOpWithNewOp<mlir::LLVM::ICmpOp>(
+        cmpOp, kind, adaptor.getLhs(), adaptor.getRhs());
+  } else if (mlir::isa<cir::CIRFPTypeInterface>(type)) {
+    mlir::LLVM::FCmpPredicate kind =
+        convertCmpKindToFCmpPredicate(cmpOp.getKind());
+    rewriter.replaceOpWithNewOp<mlir::LLVM::FCmpOp>(
+        cmpOp, kind, adaptor.getLhs(), adaptor.getRhs());
+  } else {
+    return cmpOp.emitError() << "unsupported type for CmpOp: " << type;
+  }
+
+  return mlir::success();
+}
+
 static void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
                                  mlir::DataLayout &dataLayout) {
   converter.addConversion([&](cir::PointerType type) -> mlir::Type {
@@ -1258,6 +1347,7 @@ void ConvertCIRToLLVMPass::runOnOperation() {
                CIRToLLVMBinOpLowering,
                CIRToLLVMBrCondOpLowering,
                CIRToLLVMBrOpLowering,
+               CIRToLLVMCmpOpLowering,
                CIRToLLVMFuncOpLowering,
                CIRToLLVMTrapOpLowering,
                CIRToLLVMUnaryOpLowering
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
index ef0bb2deaccdf..c57f86f57ecde 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
@@ -189,6 +189,20 @@ class CIRToLLVMBinOpLowering : public 
mlir::OpConversionPattern<cir::BinOp> {
                   mlir::ConversionPatternRewriter &) const override;
 };
 
+class CIRToLLVMCmpOpLowering : public mlir::OpConversionPattern<cir::CmpOp> {
+public:
+  CIRToLLVMCmpOpLowering(const mlir::TypeConverter &typeConverter,
+                         mlir::MLIRContext *context)
+      : OpConversionPattern(typeConverter, context) {
+    setHasBoundedRewriteRecursion();
+  }
+
+  mlir::LogicalResult
+  matchAndRewrite(cir::CmpOp op, OpAdaptor,
+                  mlir::ConversionPatternRewriter &) const override;
+};
+
+
 class CIRToLLVMBrOpLowering : public mlir::OpConversionPattern<cir::BrOp> {
 public:
   using mlir::OpConversionPattern<cir::BrOp>::OpConversionPattern;
diff --git a/clang/test/CIR/CodeGen/cmp.cpp b/clang/test/CIR/CodeGen/cmp.cpp
new file mode 100644
index 0000000000000..57d6b5b411f98
--- /dev/null
+++ b/clang/test/CIR/CodeGen/cmp.cpp
@@ -0,0 +1,233 @@
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir 
-emit-cir -DCIR_ONLY %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 
-fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+
+void c0(int a, int b) {
+  bool x = a > b;
+  x = a < b;
+  x = a <= b;
+  x = a >= b;
+  x = a != b;
+  x = a == b;
+}
+
+// CIR: cir.func @c0(
+
+// CIR: %[[A_PTR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
+// CIR: %[[B_PTR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]
+// CIR: %[[X_PTR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["x", init]
+
+// CIR: %[[A1:.*]] = cir.load %[[A_PTR]]
+// CIR: %[[B1:.*]] = cir.load %[[B_PTR]]
+// CIR: %{{.*}} = cir.cmp(gt, %[[A1]], %[[B1]]) : !s32i, !cir.bool
+// CIR: cir.store {{.*}}, %[[X_PTR]]
+
+// CIR: %[[A2:.*]] = cir.load %[[A_PTR]]
+// CIR: %[[B2:.*]] = cir.load %[[B_PTR]]
+// CIR: %{{.*}} = cir.cmp(lt, %[[A2]], %[[B2]]) : !s32i, !cir.bool
+
+// CIR: %[[A3:.*]] = cir.load %[[A_PTR]]
+// CIR: %[[B3:.*]] = cir.load %[[B_PTR]]
+// CIR: %{{.*}} = cir.cmp(le, %[[A3]], %[[B3]]) : !s32i, !cir.bool
+
+// CIR: %[[A4:.*]] = cir.load %[[A_PTR]]
+// CIR: %[[B4:.*]] = cir.load %[[B_PTR]]
+// CIR: %{{.*}} = cir.cmp(ge, %[[A4]], %[[B4]]) : !s32i, !cir.bool
+
+// CIR: %[[A5:.*]] = cir.load %[[A_PTR]]
+// CIR: %[[B5:.*]] = cir.load %[[B_PTR]]
+// CIR: %{{.*}} = cir.cmp(ne, %[[A5]], %[[B5]]) : !s32i, !cir.bool
+
+// CIR: %[[A6:.*]] = cir.load %[[A_PTR]]
+// CIR: %[[B6:.*]] = cir.load %[[B_PTR]]
+// CIR: %{{.*}} = cir.cmp(eq, %[[A6]], %[[B6]]) : !s32i, !cir.bool
+
+// LLVM: define void @c0(i32 %0, i32 %1) {
+// LLVM: %[[PTR1:.*]] = alloca i32, i64 1
+// LLVM: %[[PTR2:.*]] = alloca i32, i64 1
+// LLVM: %[[BOOL_PTR:.*]] = alloca i8, i64 1
+// LLVM: store i32 %0, ptr %[[PTR1]]
+// LLVM: store i32 %1, ptr %[[PTR2]]
+
+// LLVM: %[[A1:.*]] = load i32, ptr %[[PTR1]]
+// LLVM: %[[B1:.*]] = load i32, ptr %[[PTR2]]
+// LLVM: %[[CMP1:.*]] = icmp sgt i32 %[[A1]], %[[B1]]
+// LLVM: %[[ZEXT1:.*]] = zext i1 %[[CMP1]] to i8
+// LLVM: store i8 %[[ZEXT1]], ptr %[[BOOL_PTR]]
+
+// LLVM: %[[A2:.*]] = load i32, ptr %[[PTR1]]
+// LLVM: %[[B2:.*]] = load i32, ptr %[[PTR2]]
+// LLVM: %[[CMP2:.*]] = icmp slt i32 %[[A2]], %[[B2]]
+// LLVM: %[[ZEXT2:.*]] = zext i1 %[[CMP2]] to i8
+// LLVM: store i8 %[[ZEXT2]], ptr %[[BOOL_PTR]]
+
+// LLVM: %[[A3:.*]] = load i32, ptr %[[PTR1]]
+// LLVM: %[[B3:.*]] = load i32, ptr %[[PTR2]]
+// LLVM: %[[CMP3:.*]] = icmp sle i32 %[[A3]], %[[B3]]
+// LLVM: %[[ZEXT3:.*]] = zext i1 %[[CMP3]] to i8
+// LLVM: store i8 %[[ZEXT3]], ptr %[[BOOL_PTR]]
+
+// LLVM: %[[A4:.*]] = load i32, ptr %[[PTR1]]
+// LLVM: %[[B4:.*]] = load i32, ptr %[[PTR2]]
+// LLVM: %[[CMP4:.*]] = icmp sge i32 %[[A4]], %[[B4]]
+// LLVM: %[[ZEXT4:.*]] = zext i1 %[[CMP4]] to i8
+// LLVM: store i8 %[[ZEXT4]], ptr %[[BOOL_PTR]]
+
+// LLVM: %[[A5:.*]] = load i32, ptr %[[PTR1]]
+// LLVM: %[[B5:.*]] = load i32, ptr %[[PTR2]]
+// LLVM: %[[CMP5:.*]] = icmp ne i32 %[[A5]], %[[B5]]
+// LLVM: %[[ZEXT5:.*]] = zext i1 %[[CMP5]] to i8
+// LLVM: store i8 %[[ZEXT5]], ptr %[[BOOL_PTR]]
+
+// LLVM: %[[A6:.*]] = load i32, ptr %[[PTR1]]
+// LLVM: %[[B6:.*]] = load i32, ptr %[[PTR2]]
+// LLVM: %[[CMP6:.*]] = icmp eq i32 %[[A6]], %[[B6]]
+// LLVM: %[[ZEXT6:.*]] = zext i1 %[[CMP6]] to i8
+// LLVM: store i8 %[[ZEXT6]], ptr %[[BOOL_PTR]]
+
+void c0_unsigned(unsigned int a, unsigned int b) {
+  bool x = a > b;
+  x = a < b;
+  x = a <= b;
+  x = a >= b;
+  x = a != b;
+  x = a == b;
+}
+
+// CIR: cir.func @c0_unsigned(
+
+// CIR: %[[U_A_PTR:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["a", init]
+// CIR: %[[U_B_PTR:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["b", init]
+// CIR: %[[U_X_PTR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["x", 
init]
+
+// CIR: %[[UA1:.*]] = cir.load %[[U_A_PTR]]
+// CIR: %[[UB1:.*]] = cir.load %[[U_B_PTR]]
+// CIR: %{{.*}} = cir.cmp(gt, %[[UA1]], %[[UB1]]) : !u32i, !cir.bool
+
+// CIR: %[[UA2:.*]] = cir.load %[[U_A_PTR]]
+// CIR: %[[UB2:.*]] = cir.load %[[U_B_PTR]]
+// CIR: %{{.*}} = cir.cmp(lt, %[[UA2]], %[[UB2]]) : !u32i, !cir.bool
+
+// CIR: %[[UA3:.*]] = cir.load %[[U_A_PTR]]
+// CIR: %[[UB3:.*]] = cir.load %[[U_B_PTR]]
+// CIR: %{{.*}} = cir.cmp(le, %[[UA3]], %[[UB3]]) : !u32i, !cir.bool
+
+// CIR: %[[UA4:.*]] = cir.load %[[U_A_PTR]]
+// CIR: %[[UB4:.*]] = cir.load %[[U_B_PTR]]
+// CIR: %{{.*}} = cir.cmp(ge, %[[UA4]], %[[UB4]]) : !u32i, !cir.bool
+
+// CIR: %[[UA5:.*]] = cir.load %[[U_A_PTR]]
+// CIR: %[[UB5:.*]] = cir.load %[[U_B_PTR]]
+// CIR: %{{.*}} = cir.cmp(ne, %[[UA5]], %[[UB5]]) : !u32i, !cir.bool
+
+// CIR: %[[UA6:.*]] = cir.load %[[U_A_PTR]]
+// CIR: %[[UB6:.*]] = cir.load %[[U_B_PTR]]
+// CIR: %{{.*}} = cir.cmp(eq, %[[UA6]], %[[UB6]]) : !u32i, !cir.bool
+
+// LLVM: define void @c0_unsigned(i32 %0, i32 %1) {
+// LLVM: %[[U_PTR1:.*]] = alloca i32, i64 1
+// LLVM: %[[U_PTR2:.*]] = alloca i32, i64 1
+// LLVM: %[[U_BOOL_PTR:.*]] = alloca i8, i64 1
+// LLVM: store i32 %0, ptr %[[U_PTR1]]
+// LLVM: store i32 %1, ptr %[[U_PTR2]]
+
+// LLVM: %[[UA1:.*]] = load i32, ptr %[[U_PTR1]]
+// LLVM: %[[UB1:.*]] = load i32, ptr %[[U_PTR2]]
+// LLVM: %[[UCMP1:.*]] = icmp ugt i32 %[[UA1]], %[[UB1]]
+// LLVM: %[[UZEXT1:.*]] = zext i1 %[[UCMP1]] to i8
+// LLVM: store i8 %[[UZEXT1]], ptr %[[U_BOOL_PTR]]
+
+// LLVM: %[[UA2:.*]] = load i32, ptr %[[U_PTR1]]
+// LLVM: %[[UB2:.*]] = load i32, ptr %[[U_PTR2]]
+// LLVM: %[[UCMP2:.*]] = icmp ult i32 %[[UA2]], %[[UB2]]
+// LLVM: %[[UZEXT2:.*]] = zext i1 %[[UCMP2]] to i8
+// LLVM: store i8 %[[UZEXT2]], ptr %[[U_BOOL_PTR]]
+
+// LLVM: %[[UA3:.*]] = load i32, ptr %[[U_PTR1]]
+// LLVM: %[[UB3:.*]] = load i32, ptr %[[U_PTR2]]
+// LLVM: %[[UCMP3:.*]] = icmp ule i32 %[[UA3]], %[[UB3]]
+// LLVM: %[[UZEXT3:.*]] = zext i1 %[[UCMP3]] to i8
+// LLVM: store i8 %[[UZEXT3]], ptr %[[U_BOOL_PTR]]
+
+// LLVM: %[[UA4:.*]] = load i32, ptr %[[U_PTR1]]
+// LLVM: %[[UB4:.*]] = load i32, ptr %[[U_PTR2]]
+// LLVM: %[[UCMP4:.*]] = icmp uge i32 %[[UA4]], %[[UB4]]
+// LLVM: %[[UZEXT4:.*]] = zext i1 %[[UCMP4]] to i8
+// LLVM: store i8 %[[UZEXT4]], ptr %[[U_BOOL_PTR]]
+
+// LLVM: %[[UA5:.*]] = load i32, ptr %[[U_PTR1]]
+// LLVM: %[[UB5:.*]] = load i32, ptr %[[U_PTR2]]
+// LLVM: %[[UCMP5:.*]] = icmp ne i32 %[[UA5]], %[[UB5]]
+// LLVM: %[[UZEXT5:.*]] = zext i1 %[[UCMP5]] to i8
+// LLVM: store i8 %[[UZEXT5]], ptr %[[U_BOOL_PTR]]
+
+// LLVM: %[[UA6:.*]] = load i32, ptr %[[U_PTR1]]
+// LLVM: %[[UB6:.*]] = load i32, ptr %[[U_PTR2]]
+// LLVM: %[[UCMP6:.*]] = icmp eq i32 %[[UA6]], %[[UB6]]
+// LLVM: %[[UZEXT6:.*]] = zext i1 %[[UCMP6]] to i8
+// LLVM: store i8 %[[UZEXT6]], ptr %[[U_BOOL_PTR]]
+
+void c0_float(float a, float b) {
+  bool x = a > b;
+  x = a < b;
+  x = a <= b;
+  x = a >= b;
+  x = a != b;
+  x = a == b;
+}
+
+// CIR: cir.func @c0_float(%arg0: !cir.float{{.*}}, %arg1: !cir.float{{.*}}) {
+// CIR: %[[A_PTR:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["a", 
init]
+// CIR: %[[B_PTR:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["b", 
init]
+// CIR: %[[X_PTR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["x", init]
+
+// CIR: cir.store %arg0, %[[A_PTR]] : !cir.float, !cir.ptr<!cir.float>
+// CIR: cir.store ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/133159
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to