[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