https://github.com/xlauko created https://github.com/llvm/llvm-project/pull/146661
- Add common CIR_ prefix - Simplify printing/parsing - Make it use IntTypeInterface This mirrors incubator changes from https://github.com/llvm/clangir/pull/1725 >From 7e092b87f30c9081551158186c0afae3b337b66f Mon Sep 17 00:00:00 2001 From: xlauko <xla...@mail.muni.cz> Date: Wed, 2 Jul 2025 09:50:24 +0200 Subject: [PATCH] [CIR] Clean up IntAttr - Add common CIR_ prefix - Simplify printing/parsing - Make it use IntTypeInterface This mirrors incubator changes from https://github.com/llvm/clangir/pull/1725 --- .../CIR/Dialect/Builder/CIRBaseBuilder.h | 2 +- .../include/clang/CIR/Dialect/IR/CIRAttrs.td | 53 ++++++++-- clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp | 6 +- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 15 ++- clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 100 +++++++++--------- 5 files changed, 101 insertions(+), 75 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 3e052c564112e..41ac8c1c875df 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -63,7 +63,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ, const llvm::APInt &val) { - return create<cir::ConstantOp>(loc, getAttr<cir::IntAttr>(typ, val)); + return create<cir::ConstantOp>(loc, cir::IntAttr::get(typ, val)); } cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr) { diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 9a6560519eec4..a042f5cd0c19e 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -117,36 +117,67 @@ def UndefAttr : CIR_TypedAttr<"Undef", "undef"> { // IntegerAttr //===----------------------------------------------------------------------===// -def IntAttr : CIR_Attr<"Int", "int", [TypedAttrInterface]> { +def CIR_IntAttr : CIR_Attr<"Int", "int", [TypedAttrInterface]> { let summary = "An attribute containing an integer value"; let description = [{ An integer attribute is a literal attribute that represents an integral value of the specified integer type. }]; - let parameters = (ins AttributeSelfTypeParameter<"">:$type, - APIntParameter<"">:$value); + + let parameters = (ins + AttributeSelfTypeParameter<"", "cir::IntTypeInterface">:$type, + APIntParameter<"">:$value + ); + let builders = [ AttrBuilderWithInferredContext<(ins "mlir::Type":$type, "const llvm::APInt &":$value), [{ - return $_get(type.getContext(), type, value); + auto intType = mlir::cast<cir::IntTypeInterface>(type); + return $_get(type.getContext(), intType, value); }]>, AttrBuilderWithInferredContext<(ins "mlir::Type":$type, "int64_t":$value), [{ - IntType intType = mlir::cast<IntType>(type); + auto intType = mlir::cast<cir::IntTypeInterface>(type); mlir::APInt apValue(intType.getWidth(), value, intType.isSigned()); return $_get(intType.getContext(), intType, apValue); }]>, ]; + let extraClassDeclaration = [{ - int64_t getSInt() const { return getValue().getSExtValue(); } - uint64_t getUInt() const { return getValue().getZExtValue(); } - bool isNullValue() const { return getValue() == 0; } - uint64_t getBitWidth() const { - return mlir::cast<IntType>(getType()).getWidth(); + int64_t getSInt() const; + uint64_t getUInt() const; + bool isNullValue() const; + bool isSigned() const; + bool isUnsigned() const; + uint64_t getBitWidth() const; + }]; + + let extraClassDefinition = [{ + int64_t $cppClass::getSInt() const { + return getValue().getSExtValue(); + } + uint64_t $cppClass::getUInt() const { + return getValue().getZExtValue(); + } + bool $cppClass::isNullValue() const { + return getValue() == 0; + } + bool $cppClass::isSigned() const { + return mlir::cast<IntTypeInterface>(getType()).isSigned(); + } + bool $cppClass::isUnsigned() const { + return mlir::cast<IntTypeInterface>(getType()).isUnsigned(); + } + uint64_t $cppClass::getBitWidth() const { + return mlir::cast<IntTypeInterface>(getType()).getWidth(); } }]; + + let assemblyFormat = [{ + `<` custom<IntLiteral>($value, ref($type)) `>` + }]; + let genVerifyDecl = 1; - let hasCustomAssemblyFormat = 1; } //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp index e25819cdb11bf..5fc7a92cd00f9 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp @@ -684,7 +684,7 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value, if (mlir::isa<cir::BoolType>(ty)) return builder.getCIRBoolAttr(value.getInt().getZExtValue()); assert(mlir::isa<cir::IntType>(ty) && "expected integral type"); - return cgm.getBuilder().getAttr<cir::IntAttr>(ty, value.getInt()); + return cir::IntAttr::get(ty, value.getInt()); } case APValue::Float: { const llvm::APFloat &init = value.getFloat(); @@ -789,8 +789,8 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value, llvm::APSInt real = value.getComplexIntReal(); llvm::APSInt imag = value.getComplexIntImag(); return builder.getAttr<cir::ConstComplexAttr>( - complexType, builder.getAttr<cir::IntAttr>(complexElemTy, real), - builder.getAttr<cir::IntAttr>(complexElemTy, imag)); + complexType, cir::IntAttr::get(complexElemTy, real), + cir::IntAttr::get(complexElemTy, imag)); } assert(isa<cir::FPTypeInterface>(complexElemTy) && diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 2535a67995138..06827f84f34d4 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -157,8 +157,7 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { mlir::Value VisitIntegerLiteral(const IntegerLiteral *e) { mlir::Type type = cgf.convertType(e->getType()); return builder.create<cir::ConstantOp>( - cgf.getLoc(e->getExprLoc()), - builder.getAttr<cir::IntAttr>(type, e->getValue())); + cgf.getLoc(e->getExprLoc()), cir::IntAttr::get(type, e->getValue())); } mlir::Value VisitFloatingLiteral(const FloatingLiteral *e) { @@ -1970,21 +1969,21 @@ mlir::Value ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr( "sizeof operator for VariableArrayType", e->getStmtClassName()); return builder.getConstant( - loc, builder.getAttr<cir::IntAttr>( - cgf.cgm.UInt64Ty, llvm::APSInt(llvm::APInt(64, 1), true))); + loc, cir::IntAttr::get(cgf.cgm.UInt64Ty, + llvm::APSInt(llvm::APInt(64, 1), true))); } } else if (e->getKind() == UETT_OpenMPRequiredSimdAlign) { cgf.getCIRGenModule().errorNYI( e->getSourceRange(), "sizeof operator for OpenMpRequiredSimdAlign", e->getStmtClassName()); return builder.getConstant( - loc, builder.getAttr<cir::IntAttr>( - cgf.cgm.UInt64Ty, llvm::APSInt(llvm::APInt(64, 1), true))); + loc, cir::IntAttr::get(cgf.cgm.UInt64Ty, + llvm::APSInt(llvm::APInt(64, 1), true))); } return builder.getConstant( - loc, builder.getAttr<cir::IntAttr>( - cgf.cgm.UInt64Ty, e->EvaluateKnownConstInt(cgf.getContext()))); + loc, cir::IntAttr::get(cgf.cgm.UInt64Ty, + e->EvaluateKnownConstInt(cgf.getContext()))); } /// Return true if the specified expression is cheap enough and side-effect-free diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp index 29a9a815c31a1..075ea3ef70842 100644 --- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp @@ -15,6 +15,19 @@ #include "mlir/IR/DialectImplementation.h" #include "llvm/ADT/TypeSwitch.h" +//===-----------------------------------------------------------------===// +// IntLiteral +//===-----------------------------------------------------------------===// + +static void printIntLiteral(mlir::AsmPrinter &p, llvm::APInt value, + cir::IntTypeInterface ty); +static mlir::ParseResult parseIntLiteral(mlir::AsmParser &parser, + llvm::APInt &value, + cir::IntTypeInterface ty); +//===-----------------------------------------------------------------===// +// FloatLiteral +//===-----------------------------------------------------------------===// + static void printFloatLiteral(mlir::AsmPrinter &p, llvm::APFloat value, mlir::Type ty); static mlir::ParseResult @@ -82,69 +95,52 @@ static void printConstPtr(AsmPrinter &p, mlir::IntegerAttr value) { // IntAttr definitions //===----------------------------------------------------------------------===// -Attribute IntAttr::parse(AsmParser &parser, Type odsType) { - mlir::APInt apValue; - - if (!mlir::isa<IntType>(odsType)) - return {}; - auto type = mlir::cast<IntType>(odsType); - - // Consume the '<' symbol. - if (parser.parseLess()) - return {}; - - // Fetch arbitrary precision integer value. - if (type.isSigned()) { - int64_t value = 0; - if (parser.parseInteger(value)) { - parser.emitError(parser.getCurrentLocation(), "expected integer value"); - } else { - apValue = mlir::APInt(type.getWidth(), value, type.isSigned(), - /*implicitTrunc=*/true); - if (apValue.getSExtValue() != value) - parser.emitError(parser.getCurrentLocation(), - "integer value too large for the given type"); - } +template <typename IntT> +static bool isTooLargeForType(const mlir::APInt &value, IntT expectedValue) { + if constexpr (std::is_signed_v<IntT>) { + return value.getSExtValue() != expectedValue; } else { - uint64_t value = 0; - if (parser.parseInteger(value)) { - parser.emitError(parser.getCurrentLocation(), "expected integer value"); - } else { - apValue = mlir::APInt(type.getWidth(), value, type.isSigned(), - /*implicitTrunc=*/true); - if (apValue.getZExtValue() != value) - parser.emitError(parser.getCurrentLocation(), - "integer value too large for the given type"); - } + return value.getZExtValue() != expectedValue; } +} - // Consume the '>' symbol. - if (parser.parseGreater()) - return {}; +template <typename IntT> +static mlir::ParseResult parseIntLiteralImpl(mlir::AsmParser &p, + llvm::APInt &value, + cir::IntTypeInterface ty) { + IntT ivalue; + const bool isSigned = ty.isSigned(); + if (p.parseInteger(ivalue)) + return p.emitError(p.getCurrentLocation(), "expected integer value"); + + value = mlir::APInt(ty.getWidth(), ivalue, isSigned, /*implicitTrunc=*/true); + if (isTooLargeForType(value, ivalue)) + return p.emitError(p.getCurrentLocation(), + "integer value too large for the given type"); - return IntAttr::get(type, apValue); + return success(); +} + +mlir::ParseResult parseIntLiteral(mlir::AsmParser &parser, llvm::APInt &value, + cir::IntTypeInterface ty) { + if (ty.isSigned()) + return parseIntLiteralImpl<int64_t>(parser, value, ty); + return parseIntLiteralImpl<uint64_t>(parser, value, ty); } -void IntAttr::print(AsmPrinter &printer) const { - auto type = mlir::cast<IntType>(getType()); - printer << '<'; - if (type.isSigned()) - printer << getSInt(); +void printIntLiteral(mlir::AsmPrinter &p, llvm::APInt value, + cir::IntTypeInterface ty) { + if (ty.isSigned()) + p << value.getSExtValue(); else - printer << getUInt(); - printer << '>'; + p << value.getZExtValue(); } LogicalResult IntAttr::verify(function_ref<InFlightDiagnostic()> emitError, - Type type, APInt value) { - if (!mlir::isa<IntType>(type)) - return emitError() << "expected 'simple.int' type"; - - auto intType = mlir::cast<IntType>(type); - if (value.getBitWidth() != intType.getWidth()) + cir::IntTypeInterface type, llvm::APInt value) { + if (value.getBitWidth() != type.getWidth()) return emitError() << "type and value bitwidth mismatch: " - << intType.getWidth() << " != " << value.getBitWidth(); - + << type.getWidth() << " != " << value.getBitWidth(); return success(); } _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits