Skip to content

Commit 5e72941

Browse files
orbirixlauko
authored andcommitted
[CIR] Extend support for floating point attributes (llvm#572)
This commit extends the support for floating point attributes parsing by using the new `AsmParser::parseFloat(fltSemnatics, APFloat&)` interface. As a drive-by, this commit also harmonizes the cir.fp print/parse namespace usage, and adds the constraint of supporting only "CIRFPType"s for cir.fp in tablegen instead of verifying it manually in the parsing logic. --- This commit is based on top of a to-be-upstreamed commit which extends the upstream MLIR float type parsing. Upstream parsing of float type has full capability only through parsing the Builtin Dialect's `FloatAttr`. Thos commit exposes the same capabilities to downstream users. --- This PR should resolve (at least) `GCC-C-execute-ieee-fp-cmp-2` and `GCC-C-execute-ieee-fp-cmp-4`, paving the way to other `GCC-C-execute-ieee-*` tests passing from the SingleSource suite. It resolves llvm#559 .
1 parent 04e3256 commit 5e72941

File tree

4 files changed

+35
-46
lines changed

4 files changed

+35
-46
lines changed

clang/include/clang/CIR/Dialect/IR/CIRAttrs.td

+16-9
Original file line numberDiff line numberDiff line change
@@ -285,13 +285,20 @@ def FPAttr : CIR_Attr<"FP", "fp", [TypedAttrInterface]> {
285285
let summary = "An attribute containing a floating-point value";
286286
let description = [{
287287
An fp attribute is a literal attribute that represents a floating-point
288-
value of the specified floating-point type.
288+
value of the specified floating-point type. Supporting only CIR FP types.
289289
}];
290-
let parameters = (ins AttributeSelfTypeParameter<"">:$type, "APFloat":$value);
290+
let parameters = (ins
291+
AttributeSelfTypeParameter<"", "::mlir::cir::CIRFPTypeInterface">:$type,
292+
APFloatParameter<"">:$value
293+
);
291294
let builders = [
292295
AttrBuilderWithInferredContext<(ins "Type":$type,
293296
"const APFloat &":$value), [{
294-
return $_get(type.getContext(), type, value);
297+
return $_get(type.getContext(), mlir::cast<CIRFPTypeInterface>(type), value);
298+
}]>,
299+
AttrBuilder<(ins "Type":$type,
300+
"const APFloat &":$value), [{
301+
return $_get($_ctxt, mlir::cast<CIRFPTypeInterface>(type), value);
295302
}]>,
296303
];
297304
let extraClassDeclaration = [{
@@ -319,7 +326,7 @@ def ComplexAttr : CIR_Attr<"Complex", "complex", [TypedAttrInterface]> {
319326
contains values of the same CIR type.
320327
}];
321328

322-
let parameters = (ins
329+
let parameters = (ins
323330
AttributeSelfTypeParameter<"", "mlir::cir::ComplexType">:$type,
324331
"mlir::TypedAttr":$real, "mlir::TypedAttr":$imag);
325332

@@ -820,7 +827,7 @@ def AddressSpaceAttr : CIR_Attr<"AddressSpace", "addrspace"> {
820827
let extraClassDeclaration = [{
821828
static constexpr char kTargetKeyword[] = "}]#targetASCase.symbol#[{";
822829
static constexpr int32_t kFirstTargetASValue = }]#targetASCase.value#[{;
823-
830+
824831
bool isLang() const;
825832
bool isTarget() const;
826833
unsigned getTargetValue() const;
@@ -980,7 +987,7 @@ def ASTCallExprAttr : AST<"CallExpr", "call.expr",
980987
// VisibilityAttr
981988
//===----------------------------------------------------------------------===//
982989

983-
def VK_Default : I32EnumAttrCase<"Default", 1, "default">;
990+
def VK_Default : I32EnumAttrCase<"Default", 1, "default">;
984991
def VK_Hidden : I32EnumAttrCase<"Hidden", 2, "hidden">;
985992
def VK_Protected : I32EnumAttrCase<"Protected", 3, "protected">;
986993

@@ -1013,7 +1020,7 @@ def VisibilityAttr : CIR_Attr<"Visibility", "visibility"> {
10131020
bool isDefault() const { return getValue() == VisibilityKind::Default; };
10141021
bool isHidden() const { return getValue() == VisibilityKind::Hidden; };
10151022
bool isProtected() const { return getValue() == VisibilityKind::Protected; };
1016-
}];
1023+
}];
10171024
}
10181025

10191026

@@ -1160,7 +1167,7 @@ def AnnotationAttr : CIR_Attr<"Annotation", "annotation"> {
11601167
let parameters = (ins "StringAttr":$name,
11611168
"ArrayAttr":$args);
11621169

1163-
let assemblyFormat = "`<` struct($name, $args) `>`";
1170+
let assemblyFormat = "`<` struct($name, $args) `>`";
11641171

11651172
let extraClassDeclaration = [{
11661173
bool isNoArgs() const { return getArgs().empty(); };
@@ -1187,7 +1194,7 @@ def GlobalAnnotationValuesAttr : CIR_Attr<"GlobalAnnotationValues",
11871194
void *c __attribute__((annotate("noargvar")));
11881195
void foo(int i) __attribute__((annotate("noargfunc"))) {}
11891196
```
1190-
After CIR lowering prepare pass, compiler generates a
1197+
After CIR lowering prepare pass, compiler generates a
11911198
`GlobalAnnotationValuesAttr` like the following:
11921199
```
11931200
#cir<global_annotations [

clang/lib/CIR/Dialect/IR/CIRAttrs.cpp

+17-35
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ static void printFloatLiteral(mlir::AsmPrinter &p, llvm::APFloat value,
4242
mlir::Type ty);
4343
static mlir::ParseResult
4444
parseFloatLiteral(mlir::AsmParser &parser,
45-
mlir::FailureOr<llvm::APFloat> &value, mlir::Type ty);
45+
mlir::FailureOr<llvm::APFloat> &value,
46+
mlir::cir::CIRFPTypeInterface fpType);
4647

4748
static mlir::ParseResult parseConstPtr(mlir::AsmParser &parser,
4849
mlir::IntegerAttr &value);
@@ -313,50 +314,31 @@ LogicalResult IntAttr::verify(function_ref<InFlightDiagnostic()> emitError,
313314
// FPAttr definitions
314315
//===----------------------------------------------------------------------===//
315316

316-
static void printFloatLiteral(mlir::AsmPrinter &p, llvm::APFloat value,
317-
mlir::Type ty) {
317+
static void printFloatLiteral(AsmPrinter &p, APFloat value, Type ty) {
318318
p << value;
319319
}
320320

321-
static mlir::ParseResult
322-
parseFloatLiteral(mlir::AsmParser &parser,
323-
mlir::FailureOr<llvm::APFloat> &value, mlir::Type ty) {
324-
double rawValue;
325-
if (parser.parseFloat(rawValue)) {
326-
return parser.emitError(parser.getCurrentLocation(),
327-
"expected floating-point value");
328-
}
329-
330-
auto losesInfo = false;
331-
value.emplace(rawValue);
321+
static ParseResult parseFloatLiteral(AsmParser &parser,
322+
FailureOr<APFloat> &value,
323+
CIRFPTypeInterface fpType) {
332324

333-
auto tyFpInterface = dyn_cast<cir::CIRFPTypeInterface>(ty);
334-
if (!tyFpInterface) {
335-
// Parsing of the current floating-point literal has succeeded, but the
336-
// given attribute type is invalid. This error will be reported later when
337-
// the attribute is being verified.
338-
return success();
339-
}
325+
APFloat parsedValue(0.0);
326+
if (parser.parseFloat(fpType.getFloatSemantics(), parsedValue))
327+
return failure();
340328

341-
value->convert(tyFpInterface.getFloatSemantics(),
342-
llvm::RoundingMode::TowardZero, &losesInfo);
329+
value.emplace(parsedValue);
343330
return success();
344331
}
345332

346-
cir::FPAttr cir::FPAttr::getZero(mlir::Type type) {
347-
return get(
348-
type, APFloat::getZero(
349-
mlir::cast<cir::CIRFPTypeInterface>(type).getFloatSemantics()));
333+
FPAttr FPAttr::getZero(Type type) {
334+
return get(type,
335+
APFloat::getZero(
336+
mlir::cast<CIRFPTypeInterface>(type).getFloatSemantics()));
350337
}
351338

352-
LogicalResult cir::FPAttr::verify(function_ref<InFlightDiagnostic()> emitError,
353-
Type type, APFloat value) {
354-
auto fltTypeInterface = mlir::dyn_cast<cir::CIRFPTypeInterface>(type);
355-
if (!fltTypeInterface) {
356-
emitError() << "expected floating-point type";
357-
return failure();
358-
}
359-
if (APFloat::SemanticsToEnum(fltTypeInterface.getFloatSemantics()) !=
339+
LogicalResult FPAttr::verify(function_ref<InFlightDiagnostic()> emitError,
340+
CIRFPTypeInterface fpType, APFloat value) {
341+
if (APFloat::SemanticsToEnum(fpType.getFloatSemantics()) !=
360342
APFloat::SemanticsToEnum(value.getSemantics())) {
361343
emitError() << "floating-point semantics mismatch";
362344
return failure();

clang/test/CIR/Lowering/class.cir

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ module {
4444
// CHECK: %0 = llvm.mlir.undef : !llvm.struct<"class.S1", (i32, f32, ptr)>
4545
// CHECK: %1 = llvm.mlir.constant(1 : i32) : i32
4646
// CHECK: %2 = llvm.insertvalue %1, %0[0] : !llvm.struct<"class.S1", (i32, f32, ptr)>
47-
// CHECK: %3 = llvm.mlir.constant(0.099999994 : f32) : f32
47+
// CHECK: %3 = llvm.mlir.constant(1.000000e-01 : f32) : f32
4848
// CHECK: %4 = llvm.insertvalue %3, %2[1] : !llvm.struct<"class.S1", (i32, f32, ptr)>
4949
// CHECK: %5 = llvm.mlir.zero : !llvm.ptr
5050
// CHECK: %6 = llvm.insertvalue %5, %4[2] : !llvm.struct<"class.S1", (i32, f32, ptr)>

clang/test/CIR/Lowering/struct.cir

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ module {
150150
// CHECK: %0 = llvm.mlir.undef : !llvm.struct<"struct.S1", (i32, f32, ptr)>
151151
// CHECK: %1 = llvm.mlir.constant(1 : i32) : i32
152152
// CHECK: %2 = llvm.insertvalue %1, %0[0] : !llvm.struct<"struct.S1", (i32, f32, ptr)>
153-
// CHECK: %3 = llvm.mlir.constant(0.099999994 : f32) : f32
153+
// CHECK: %3 = llvm.mlir.constant(1.000000e-01 : f32) : f32
154154
// CHECK: %4 = llvm.insertvalue %3, %2[1] : !llvm.struct<"struct.S1", (i32, f32, ptr)>
155155
// CHECK: %5 = llvm.mlir.zero : !llvm.ptr
156156
// CHECK: %6 = llvm.insertvalue %5, %4[2] : !llvm.struct<"struct.S1", (i32, f32, ptr)>

0 commit comments

Comments
 (0)