[clang] [CIR] Upstream type `bool` (PR #128601)

David Olsen via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 24 15:57:56 PST 2025


https://github.com/dkolsen-pgi created https://github.com/llvm/llvm-project/pull/128601

Support the type `bool` and the literals `true` and `false`. Add the type `cir::BoolType` and the attribute `cir::BoolAttr` to ClangIR.  Add code in all the necessary places in ClangIR CodeGen to handle and to recognize the type and the attribute.

Add test cases to existing tests func-simple.cpp and global-var-simple.cpp.

>From bbadebdf7444ed453721f064e4e30ac2917c5fe9 Mon Sep 17 00:00:00 2001
From: David Olsen <dolsen at nvidia.com>
Date: Mon, 24 Feb 2025 15:50:19 -0800
Subject: [PATCH] [CIR] Upstream type `bool`

Support the type `bool` and the literals `true` and `false`.
Add the type `cir::BoolType` and the attribute `cir::BoolAttr` to
ClangIR.  Add code in all the necessary places in ClangIR CodeGen
to handle and to recognize the type and the attribute.

Add test cases to existing tests func-simple.cpp and
global-var-simple.cpp.
---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h      | 14 ++++++++++
 .../include/clang/CIR/Dialect/IR/CIRAttrs.td  | 19 +++++++++++++
 .../include/clang/CIR/Dialect/IR/CIRTypes.td  | 19 ++++++++++++-
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp    |  7 +++++
 clang/lib/CIR/CodeGen/CIRGenModule.cpp        |  6 +++-
 clang/lib/CIR/CodeGen/CIRGenTypes.cpp         |  5 ++++
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp       | 25 +++++++++++++++++
 clang/lib/CIR/Dialect/IR/CIRTypes.cpp         | 28 +++++++++++++++++++
 clang/test/CIR/func-simple.cpp                |  6 ++++
 clang/test/CIR/global-var-simple.cpp          |  3 ++
 10 files changed, 130 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index b4a961de224aa..f03241a875845 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -10,6 +10,8 @@
 #define LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H
 
 #include "clang/CIR/Dialect/IR/CIRAttrs.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
+#include "clang/CIR/Dialect/IR/CIRTypes.h"
 
 #include "mlir/IR/Builders.h"
 #include "mlir/IR/BuiltinTypes.h"
@@ -23,6 +25,14 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
   CIRBaseBuilderTy(mlir::MLIRContext &mlirContext)
       : mlir::OpBuilder(&mlirContext) {}
 
+  cir::ConstantOp getBool(bool state, mlir::Location loc) {
+    return create<cir::ConstantOp>(loc, getBoolTy(), getCIRBoolAttr(state));
+  }
+  cir::ConstantOp getFalse(mlir::Location loc) { return getBool(false, loc); }
+  cir::ConstantOp getTrue(mlir::Location loc) { return getBool(true, loc); }
+
+  cir::BoolType getBoolTy() { return cir::BoolType::get(getContext()); }
+
   cir::PointerType getPointerTo(mlir::Type ty) {
     return cir::PointerType::get(getContext(), ty);
   }
@@ -31,6 +41,10 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
     return getPointerTo(cir::VoidType::get(getContext()));
   }
 
+  cir::BoolAttr getCIRBoolAttr(bool state) {
+    return cir::BoolAttr::get(getContext(), getBoolTy(), state);
+  }
+
   mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value) {
     auto valueAttr = mlir::IntegerAttr::get(
         mlir::IntegerType::get(type.getContext(), 64), value);
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index bd1665e1ac1a0..097616ba06749 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -35,6 +35,25 @@ class CIRUnitAttr<string name, string attrMnemonic, list<Trait> traits = []>
   let isOptional = 1;
 }
 
+//===----------------------------------------------------------------------===//
+// BoolAttr
+//===----------------------------------------------------------------------===//
+
+def CIR_BoolAttr : CIR_Attr<"Bool", "bool", [TypedAttrInterface]> {
+  let summary = "Represent true/false for !cir.bool types";
+  let description = [{
+    The BoolAttr represents a 'true' or 'false' value.
+  }];
+
+  let parameters = (ins AttributeSelfTypeParameter<
+                        "", "cir::BoolType">:$type,
+                    "bool":$value);
+
+  let assemblyFormat = [{
+    `<` $value `>`
+  }];
+}
+
 //===----------------------------------------------------------------------===//
 // IntegerAttr
 //===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
index a32fb3c801114..63403bc9f5b41 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
@@ -266,6 +266,22 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr",
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// BoolType
+//===----------------------------------------------------------------------===//
+
+def CIR_BoolType :
+    CIR_Type<"Bool", "bool",
+             [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
+
+  let summary = "CIR bool type";
+  let description = [{
+    `cir.bool` represents C++ bool type.
+  }];
+
+  let hasCustomAssemblyFormat = 1;
+}
+
 //===----------------------------------------------------------------------===//
 // FuncType
 //===----------------------------------------------------------------------===//
@@ -355,7 +371,8 @@ def VoidPtr : Type<
 //===----------------------------------------------------------------------===//
 
 def CIR_AnyType : AnyTypeOf<[
-  CIR_VoidType, CIR_IntType, CIR_AnyFloat, CIR_PointerType, CIR_FuncType
+  CIR_VoidType, CIR_BoolType, CIR_IntType, CIR_AnyFloat, CIR_PointerType,
+  CIR_FuncType
 ]>;
 
 #endif // MLIR_CIR_DIALECT_CIR_TYPES
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index b802705ca8fdc..24a959108f73b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -58,6 +58,13 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
         cgf.getLoc(e->getExprLoc()), type,
         builder.getAttr<cir::IntAttr>(type, e->getValue()));
   }
+
+  mlir::Value VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *e) {
+    mlir::Type type = cgf.convertType(e->getType());
+    return builder.create<cir::ConstantOp>(
+        cgf.getLoc(e->getExprLoc()), type,
+        builder.getCIRBoolAttr(e->getValue()));
+  }
 };
 } // namespace
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index c1d3265200e3b..d8acc99e550ad 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -141,7 +141,11 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
       if (APValue *value = initDecl->evaluateValue()) {
         switch (value->getKind()) {
         case APValue::Int: {
-          initializer = builder.getAttr<cir::IntAttr>(type, value->getInt());
+          if (mlir::isa<cir::BoolType>(type))
+            initializer =
+                builder.getCIRBoolAttr(value->getInt().getZExtValue());
+          else
+            initializer = builder.getAttr<cir::IntAttr>(type, value->getInt());
           break;
         }
         case APValue::Float: {
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 551b43ef121b3..16aec10fda81e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -108,6 +108,11 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
       resultType = cgm.VoidTy;
       break;
 
+    // bool
+    case BuiltinType::Bool:
+      resultType = cir::BoolType::get(&getMLIRContext());
+      break;
+
     // Signed integral types.
     case BuiltinType::Char_S:
     case BuiltinType::Int:
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 10ad7fb4e6542..bfc74d4373f34 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -25,6 +25,23 @@ using namespace cir;
 //===----------------------------------------------------------------------===//
 // CIR Dialect
 //===----------------------------------------------------------------------===//
+namespace {
+struct CIROpAsmDialectInterface : public OpAsmDialectInterface {
+  using OpAsmDialectInterface::OpAsmDialectInterface;
+
+  AliasResult getAlias(Type type, raw_ostream &os) const final {
+    return AliasResult::NoAlias;
+  }
+
+  AliasResult getAlias(Attribute attr, raw_ostream &os) const final {
+    if (auto boolAttr = mlir::dyn_cast<cir::BoolAttr>(attr)) {
+      os << (boolAttr.getValue() ? "true" : "false");
+      return AliasResult::FinalAlias;
+    }
+    return AliasResult::NoAlias;
+  }
+};
+} // namespace
 
 void cir::CIRDialect::initialize() {
   registerTypes();
@@ -33,6 +50,7 @@ void cir::CIRDialect::initialize() {
 #define GET_OP_LIST
 #include "clang/CIR/Dialect/IR/CIROps.cpp.inc"
       >();
+  addInterfaces<CIROpAsmDialectInterface>();
 }
 
 //===----------------------------------------------------------------------===//
@@ -112,6 +130,13 @@ static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType,
     return success();
   }
 
+  if (mlir::isa<cir::BoolAttr>(attrType)) {
+    if (!mlir::isa<cir::BoolType>(opType))
+      return op->emitOpError("result type (")
+             << opType << ") must be '!cir.bool' for '" << attrType << "'";
+    return success();
+  }
+
   if (mlir::isa<cir::IntAttr, cir::FPAttr>(attrType)) {
     auto at = cast<TypedAttr>(attrType);
     if (at.getType() != opType) {
diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
index 48be11ba4e243..3f04bcb9ba195 100644
--- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
@@ -381,6 +381,34 @@ llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes() const {
 
 bool FuncType::isVoid() const { return mlir::isa<VoidType>(getReturnType()); }
 
+//===----------------------------------------------------------------------===//
+// BoolType
+//===----------------------------------------------------------------------===//
+
+Type BoolType::parse(mlir::AsmParser &parser) {
+  return get(parser.getContext());
+}
+
+void BoolType::print(mlir::AsmPrinter &printer) const {}
+
+llvm::TypeSize
+BoolType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
+                            ::mlir::DataLayoutEntryListRef params) const {
+  return llvm::TypeSize::getFixed(8);
+}
+
+uint64_t
+BoolType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
+                          ::mlir::DataLayoutEntryListRef params) const {
+  return 1;
+}
+
+uint64_t
+BoolType::getPreferredAlignment(const ::mlir::DataLayout &dataLayout,
+                                ::mlir::DataLayoutEntryListRef params) const {
+  return 1;
+}
+
 //===----------------------------------------------------------------------===//
 // PointerType Definitions
 //===----------------------------------------------------------------------===//
diff --git a/clang/test/CIR/func-simple.cpp b/clang/test/CIR/func-simple.cpp
index 10c49bc506c87..22c120d3404d3 100644
--- a/clang/test/CIR/func-simple.cpp
+++ b/clang/test/CIR/func-simple.cpp
@@ -51,3 +51,9 @@ unsigned long long ullfunc() { return 42ull; }
 // CHECK:   %0 = cir.const #cir.int<42> : !cir.int<u, 64>
 // CHECK:   cir.return %0 : !cir.int<u, 64>
 // CHECK: }
+
+bool boolfunc() { return true; }
+// CHECK: cir.func @boolfunc() -> !cir.bool {
+// CHECK:   %0 = cir.const #true
+// CHECK:   cir.return %0 : !cir.bool
+// CHECK: }
diff --git a/clang/test/CIR/global-var-simple.cpp b/clang/test/CIR/global-var-simple.cpp
index 237070a5b7564..dfe8371668e2c 100644
--- a/clang/test/CIR/global-var-simple.cpp
+++ b/clang/test/CIR/global-var-simple.cpp
@@ -58,6 +58,9 @@ _BitInt(20) sb20;
 unsigned _BitInt(48) ub48;
 // CHECK: cir.global @ub48 : !cir.int<u, 48>
 
+bool boolfalse = false;
+// CHECK: cir.global @boolfalse = #false
+
 _Float16 f16;
 // CHECK: cir.global @f16 : !cir.f16
 



More information about the cfe-commits mailing list