Skip to content

Commit 36dd199

Browse files
authored
[CIR] Upstream global initialization for ComplexType (#141369)
This change adds support for zero and global init for ComplexType #141365
1 parent 0a85b31 commit 36dd199

File tree

13 files changed

+341
-20
lines changed

13 files changed

+341
-20
lines changed

clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
9090
return cir::IntAttr::get(ty, 0);
9191
if (cir::isAnyFloatingPointType(ty))
9292
return cir::FPAttr::getZero(ty);
93+
if (auto complexType = mlir::dyn_cast<cir::ComplexType>(ty))
94+
return cir::ZeroAttr::get(complexType);
9395
if (auto arrTy = mlir::dyn_cast<cir::ArrayType>(ty))
9496
return cir::ZeroAttr::get(arrTy);
9597
if (auto vecTy = mlir::dyn_cast<cir::VectorType>(ty))
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This file defines the CIR dialect attributes constraints.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef CLANG_CIR_DIALECT_IR_CIRATTRCONSTRAINTS_TD
15+
#define CLANG_CIR_DIALECT_IR_CIRATTRCONSTRAINTS_TD
16+
17+
include "mlir/IR/CommonAttrConstraints.td"
18+
19+
class CIR_IsAttrPred<code attr> : CPred<"::mlir::isa<" # attr # ">($_self)">;
20+
21+
class CIR_AttrConstraint<code attr, string summary = "">
22+
: Attr<CIR_IsAttrPred<attr>, summary>;
23+
24+
//===----------------------------------------------------------------------===//
25+
// IntAttr constraints
26+
//===----------------------------------------------------------------------===//
27+
28+
def CIR_AnyIntAttr : CIR_AttrConstraint<"::cir::IntAttr", "integer attribute">;
29+
30+
//===----------------------------------------------------------------------===//
31+
// FPAttr constraints
32+
//===----------------------------------------------------------------------===//
33+
34+
def CIR_AnyFPAttr : CIR_AttrConstraint<"::cir::FPAttr",
35+
"floating-point attribute">;
36+
37+
def CIR_AnyIntOrFloatAttr : AnyAttrOf<[CIR_AnyIntAttr, CIR_AnyFPAttr],
38+
"integer or floating point type"> {
39+
string cppType = "::mlir::TypedAttr";
40+
}
41+
42+
#endif // CLANG_CIR_DIALECT_IR_CIRATTRCONSTRAINTS_TD

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ include "mlir/IR/BuiltinAttributeInterfaces.td"
1717
include "mlir/IR/EnumAttr.td"
1818

1919
include "clang/CIR/Dialect/IR/CIRDialect.td"
20+
include "clang/CIR/Dialect/IR/CIRAttrConstraints.td"
2021

2122
//===----------------------------------------------------------------------===//
2223
// CIR Attrs
@@ -276,6 +277,50 @@ def ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> {
276277
}];
277278
}
278279

280+
//===----------------------------------------------------------------------===//
281+
// ConstComplexAttr
282+
//===----------------------------------------------------------------------===//
283+
284+
def ConstComplexAttr : CIR_Attr<"ConstComplex", "const_complex",
285+
[TypedAttrInterface]> {
286+
let summary = "An attribute that contains a constant complex value";
287+
let description = [{
288+
The `#cir.const_complex` attribute contains a constant value of complex
289+
number type. The `real` parameter gives the real part of the complex number
290+
and the `imag` parameter gives the imaginary part of the complex number.
291+
292+
The `real` and `imag` parameters must both reference the same type and must
293+
be either IntAttr or FPAttr.
294+
295+
```mlir
296+
%ci = #cir.const_complex<#cir.int<1> : !s32i, #cir.int<2> : !s32i>
297+
: !cir.complex<!s32i>
298+
%cf = #cir.const_complex<#cir.fp<1.000000e+00> : !cir.float,
299+
#cir.fp<2.000000e+00> : !cir.float> : !cir.complex<!cir.float>
300+
```
301+
}];
302+
303+
let parameters = (ins
304+
AttributeSelfTypeParameter<"", "cir::ComplexType">:$type,
305+
CIR_AnyIntOrFloatAttr:$real,
306+
CIR_AnyIntOrFloatAttr:$imag
307+
);
308+
309+
let builders = [
310+
AttrBuilderWithInferredContext<(ins "cir::ComplexType":$type,
311+
"mlir::TypedAttr":$real,
312+
"mlir::TypedAttr":$imag), [{
313+
return $_get(type.getContext(), type, real, imag);
314+
}]>,
315+
];
316+
317+
let genVerifyDecl = 1;
318+
319+
let assemblyFormat = [{
320+
`<` qualified($real) `,` qualified($imag) `>`
321+
}];
322+
}
323+
279324
//===----------------------------------------------------------------------===//
280325
// VisibilityAttr
281326
//===----------------------------------------------------------------------===//

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,56 @@ def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> {
161161
}];
162162
}
163163

164+
//===----------------------------------------------------------------------===//
165+
// ComplexType
166+
//===----------------------------------------------------------------------===//
167+
168+
def CIR_ComplexType : CIR_Type<"Complex", "complex",
169+
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
170+
171+
let summary = "CIR complex type";
172+
let description = [{
173+
CIR type that represents a C complex number. `cir.complex` models the C type
174+
`T _Complex`.
175+
176+
`cir.complex` type is not directly mapped to `std::complex`.
177+
178+
The type models complex values, per C99 6.2.5p11. It supports the C99
179+
complex float types as well as the GCC integer complex extensions.
180+
181+
The parameter `elementType` gives the type of the real and imaginary part of
182+
the complex number. `elementType` must be either a CIR integer type or a CIR
183+
floating-point type.
184+
185+
```mlir
186+
!cir.complex<!s32i>
187+
!cir.complex<!cir.float>
188+
```
189+
}];
190+
191+
let parameters = (ins CIR_AnyIntOrFloatType:$elementType);
192+
193+
let builders = [
194+
TypeBuilderWithInferredContext<(ins "mlir::Type":$elementType), [{
195+
return $_get(elementType.getContext(), elementType);
196+
}]>,
197+
];
198+
199+
let assemblyFormat = [{
200+
`<` $elementType `>`
201+
}];
202+
203+
let extraClassDeclaration = [{
204+
bool isFloatingPointComplex() const {
205+
return isAnyFloatingPointType(getElementType());
206+
}
207+
208+
bool isIntegerComplex() const {
209+
return mlir::isa<cir::IntType>(getElementType());
210+
}
211+
}];
212+
}
213+
164214
//===----------------------------------------------------------------------===//
165215
// PointerType
166216
//===----------------------------------------------------------------------===//

clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -577,12 +577,33 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value,
577577
case APValue::Union:
578578
cgm.errorNYI("ConstExprEmitter::tryEmitPrivate struct or union");
579579
return {};
580-
case APValue::FixedPoint:
581580
case APValue::ComplexInt:
582-
case APValue::ComplexFloat:
581+
case APValue::ComplexFloat: {
582+
mlir::Type desiredType = cgm.convertType(destType);
583+
cir::ComplexType complexType =
584+
mlir::dyn_cast<cir::ComplexType>(desiredType);
585+
586+
mlir::Type complexElemTy = complexType.getElementType();
587+
if (isa<cir::IntType>(complexElemTy)) {
588+
llvm::APSInt real = value.getComplexIntReal();
589+
llvm::APSInt imag = value.getComplexIntImag();
590+
return builder.getAttr<cir::ConstComplexAttr>(
591+
complexType, builder.getAttr<cir::IntAttr>(complexElemTy, real),
592+
builder.getAttr<cir::IntAttr>(complexElemTy, imag));
593+
}
594+
595+
assert(isa<cir::CIRFPTypeInterface>(complexElemTy) &&
596+
"expected floating-point type");
597+
llvm::APFloat real = value.getComplexFloatReal();
598+
llvm::APFloat imag = value.getComplexFloatImag();
599+
return builder.getAttr<cir::ConstComplexAttr>(
600+
complexType, builder.getAttr<cir::FPAttr>(complexElemTy, real),
601+
builder.getAttr<cir::FPAttr>(complexElemTy, imag));
602+
}
603+
case APValue::FixedPoint:
583604
case APValue::AddrLabelDiff:
584-
cgm.errorNYI("ConstExprEmitter::tryEmitPrivate fixed point, complex int, "
585-
"complex float, addr label diff");
605+
cgm.errorNYI(
606+
"ConstExprEmitter::tryEmitPrivate fixed point, addr label diff");
586607
return {};
587608
}
588609
llvm_unreachable("Unknown APValue kind");

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,13 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
388388
break;
389389
}
390390

391+
case Type::Complex: {
392+
const auto *ct = cast<clang::ComplexType>(ty);
393+
mlir::Type elementTy = convertType(ct->getElementType());
394+
resultType = cir::ComplexType::get(elementTy);
395+
break;
396+
}
397+
391398
case Type::LValueReference:
392399
case Type::RValueReference: {
393400
const ReferenceType *refTy = cast<ReferenceType>(ty);

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,26 @@ LogicalResult FPAttr::verify(function_ref<InFlightDiagnostic()> emitError,
183183
return success();
184184
}
185185

186+
//===----------------------------------------------------------------------===//
187+
// ConstComplexAttr definitions
188+
//===----------------------------------------------------------------------===//
189+
190+
LogicalResult
191+
ConstComplexAttr::verify(function_ref<InFlightDiagnostic()> emitError,
192+
cir::ComplexType type, mlir::TypedAttr real,
193+
mlir::TypedAttr imag) {
194+
mlir::Type elemType = type.getElementType();
195+
if (real.getType() != elemType)
196+
return emitError()
197+
<< "type of the real part does not match the complex type";
198+
199+
if (imag.getType() != elemType)
200+
return emitError()
201+
<< "type of the imaginary part does not match the complex type";
202+
203+
return success();
204+
}
205+
186206
//===----------------------------------------------------------------------===//
187207
// CIR ConstArrayAttr
188208
//===----------------------------------------------------------------------===//

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,11 @@ static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType,
231231
}
232232

233233
if (isa<cir::ZeroAttr>(attrType)) {
234-
if (isa<cir::RecordType, cir::ArrayType, cir::VectorType>(opType))
234+
if (isa<cir::RecordType, cir::ArrayType, cir::VectorType, cir::ComplexType>(
235+
opType))
235236
return success();
236-
return op->emitOpError("zero expects struct or array type");
237+
return op->emitOpError(
238+
"zero expects struct, array, vector, or complex type");
237239
}
238240

239241
if (mlir::isa<cir::BoolAttr>(attrType)) {
@@ -253,7 +255,8 @@ static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType,
253255
return success();
254256
}
255257

256-
if (mlir::isa<cir::ConstArrayAttr, cir::ConstVectorAttr>(attrType))
258+
if (mlir::isa<cir::ConstArrayAttr, cir::ConstVectorAttr,
259+
cir::ConstComplexAttr>(attrType))
257260
return success();
258261

259262
assert(isa<TypedAttr>(attrType) && "What else could we be looking at here?");

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,9 +558,31 @@ LongDoubleType::getABIAlignment(const mlir::DataLayout &dataLayout,
558558
}
559559

560560
//===----------------------------------------------------------------------===//
561-
// FuncType Definitions
561+
// ComplexType Definitions
562562
//===----------------------------------------------------------------------===//
563563

564+
llvm::TypeSize
565+
cir::ComplexType::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
566+
mlir::DataLayoutEntryListRef params) const {
567+
// C17 6.2.5p13:
568+
// Each complex type has the same representation and alignment requirements
569+
// as an array type containing exactly two elements of the corresponding
570+
// real type.
571+
572+
return dataLayout.getTypeSizeInBits(getElementType()) * 2;
573+
}
574+
575+
uint64_t
576+
cir::ComplexType::getABIAlignment(const mlir::DataLayout &dataLayout,
577+
mlir::DataLayoutEntryListRef params) const {
578+
// C17 6.2.5p13:
579+
// Each complex type has the same representation and alignment requirements
580+
// as an array type containing exactly two elements of the corresponding
581+
// real type.
582+
583+
return dataLayout.getTypeABIAlignment(getElementType());
584+
}
585+
564586
FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
565587
assert(results.size() == 1 && "expected exactly one result type");
566588
return get(llvm::to_vector(inputs), results[0], isVarArg());

0 commit comments

Comments
 (0)