aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp29
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenTypes.cpp7
-rw-r--r--clang/lib/CIR/Dialect/IR/CIRAttrs.cpp20
-rw-r--r--clang/lib/CIR/Dialect/IR/CIRDialect.cpp9
-rw-r--r--clang/lib/CIR/Dialect/IR/CIRTypes.cpp24
-rw-r--r--clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp65
6 files changed, 134 insertions, 20 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 9085ee2..c41ab54 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -577,12 +577,33 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value,
case APValue::Union:
cgm.errorNYI("ConstExprEmitter::tryEmitPrivate struct or union");
return {};
- case APValue::FixedPoint:
case APValue::ComplexInt:
- case APValue::ComplexFloat:
+ case APValue::ComplexFloat: {
+ mlir::Type desiredType = cgm.convertType(destType);
+ cir::ComplexType complexType =
+ mlir::dyn_cast<cir::ComplexType>(desiredType);
+
+ mlir::Type complexElemTy = complexType.getElementType();
+ if (isa<cir::IntType>(complexElemTy)) {
+ 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));
+ }
+
+ assert(isa<cir::CIRFPTypeInterface>(complexElemTy) &&
+ "expected floating-point type");
+ llvm::APFloat real = value.getComplexFloatReal();
+ llvm::APFloat imag = value.getComplexFloatImag();
+ return builder.getAttr<cir::ConstComplexAttr>(
+ complexType, builder.getAttr<cir::FPAttr>(complexElemTy, real),
+ builder.getAttr<cir::FPAttr>(complexElemTy, imag));
+ }
+ case APValue::FixedPoint:
case APValue::AddrLabelDiff:
- cgm.errorNYI("ConstExprEmitter::tryEmitPrivate fixed point, complex int, "
- "complex float, addr label diff");
+ cgm.errorNYI(
+ "ConstExprEmitter::tryEmitPrivate fixed point, addr label diff");
return {};
}
llvm_unreachable("Unknown APValue kind");
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index f748649..5f51d34 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -388,6 +388,13 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
break;
}
+ case Type::Complex: {
+ const auto *ct = cast<clang::ComplexType>(ty);
+ mlir::Type elementTy = convertType(ct->getElementType());
+ resultType = cir::ComplexType::get(elementTy);
+ break;
+ }
+
case Type::LValueReference:
case Type::RValueReference: {
const ReferenceType *refTy = cast<ReferenceType>(ty);
diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
index 52f0b33..b52e9c3 100644
--- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
@@ -184,6 +184,26 @@ LogicalResult FPAttr::verify(function_ref<InFlightDiagnostic()> emitError,
}
//===----------------------------------------------------------------------===//
+// ConstComplexAttr definitions
+//===----------------------------------------------------------------------===//
+
+LogicalResult
+ConstComplexAttr::verify(function_ref<InFlightDiagnostic()> emitError,
+ cir::ComplexType type, mlir::TypedAttr real,
+ mlir::TypedAttr imag) {
+ mlir::Type elemType = type.getElementType();
+ if (real.getType() != elemType)
+ return emitError()
+ << "type of the real part does not match the complex type";
+
+ if (imag.getType() != elemType)
+ return emitError()
+ << "type of the imaginary part does not match the complex type";
+
+ return success();
+}
+
+//===----------------------------------------------------------------------===//
// CIR ConstArrayAttr
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index fa7fb59..5f2efa3 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -231,9 +231,11 @@ static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType,
}
if (isa<cir::ZeroAttr>(attrType)) {
- if (isa<cir::RecordType, cir::ArrayType, cir::VectorType>(opType))
+ if (isa<cir::RecordType, cir::ArrayType, cir::VectorType, cir::ComplexType>(
+ opType))
return success();
- return op->emitOpError("zero expects struct or array type");
+ return op->emitOpError(
+ "zero expects struct, array, vector, or complex type");
}
if (mlir::isa<cir::BoolAttr>(attrType)) {
@@ -253,7 +255,8 @@ static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType,
return success();
}
- if (mlir::isa<cir::ConstArrayAttr, cir::ConstVectorAttr>(attrType))
+ if (mlir::isa<cir::ConstArrayAttr, cir::ConstVectorAttr,
+ cir::ConstComplexAttr>(attrType))
return success();
assert(isa<TypedAttr>(attrType) && "What else could we be looking at here?");
diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
index 3543c13..09926a9 100644
--- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
@@ -558,9 +558,31 @@ LongDoubleType::getABIAlignment(const mlir::DataLayout &dataLayout,
}
//===----------------------------------------------------------------------===//
-// FuncType Definitions
+// ComplexType Definitions
//===----------------------------------------------------------------------===//
+llvm::TypeSize
+cir::ComplexType::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
+ mlir::DataLayoutEntryListRef params) const {
+ // C17 6.2.5p13:
+ // Each complex type has the same representation and alignment requirements
+ // as an array type containing exactly two elements of the corresponding
+ // real type.
+
+ return dataLayout.getTypeSizeInBits(getElementType()) * 2;
+}
+
+uint64_t
+cir::ComplexType::getABIAlignment(const mlir::DataLayout &dataLayout,
+ mlir::DataLayoutEntryListRef params) const {
+ // C17 6.2.5p13:
+ // Each complex type has the same representation and alignment requirements
+ // as an array type containing exactly two elements of the corresponding
+ // real type.
+
+ return dataLayout.getTypeABIAlignment(getElementType());
+}
+
FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
assert(results.size() == 1 && "expected exactly one result type");
return get(llvm::to_vector(inputs), results[0], isVarArg());
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index bbfd5df..8059836 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -188,14 +188,15 @@ public:
mlir::Value visit(mlir::Attribute attr) {
return llvm::TypeSwitch<mlir::Attribute, mlir::Value>(attr)
- .Case<cir::IntAttr, cir::FPAttr, cir::ConstArrayAttr,
- cir::ConstVectorAttr, cir::ConstPtrAttr, cir::ZeroAttr>(
- [&](auto attrT) { return visitCirAttr(attrT); })
+ .Case<cir::IntAttr, cir::FPAttr, cir::ConstComplexAttr,
+ cir::ConstArrayAttr, cir::ConstVectorAttr, cir::ConstPtrAttr,
+ cir::ZeroAttr>([&](auto attrT) { return visitCirAttr(attrT); })
.Default([&](auto attrT) { return mlir::Value(); });
}
mlir::Value visitCirAttr(cir::IntAttr intAttr);
mlir::Value visitCirAttr(cir::FPAttr fltAttr);
+ mlir::Value visitCirAttr(cir::ConstComplexAttr complexAttr);
mlir::Value visitCirAttr(cir::ConstPtrAttr ptrAttr);
mlir::Value visitCirAttr(cir::ConstArrayAttr attr);
mlir::Value visitCirAttr(cir::ConstVectorAttr attr);
@@ -226,6 +227,42 @@ mlir::Value CIRAttrToValue::visitCirAttr(cir::IntAttr intAttr) {
loc, converter->convertType(intAttr.getType()), intAttr.getValue());
}
+/// FPAttr visitor.
+mlir::Value CIRAttrToValue::visitCirAttr(cir::FPAttr fltAttr) {
+ mlir::Location loc = parentOp->getLoc();
+ return rewriter.create<mlir::LLVM::ConstantOp>(
+ loc, converter->convertType(fltAttr.getType()), fltAttr.getValue());
+}
+
+/// ConstComplexAttr visitor.
+mlir::Value CIRAttrToValue::visitCirAttr(cir::ConstComplexAttr complexAttr) {
+ auto complexType = mlir::cast<cir::ComplexType>(complexAttr.getType());
+ mlir::Type complexElemTy = complexType.getElementType();
+ mlir::Type complexElemLLVMTy = converter->convertType(complexElemTy);
+
+ mlir::Attribute components[2];
+ if (const auto intType = mlir::dyn_cast<cir::IntType>(complexElemTy)) {
+ components[0] = rewriter.getIntegerAttr(
+ complexElemLLVMTy,
+ mlir::cast<cir::IntAttr>(complexAttr.getReal()).getValue());
+ components[1] = rewriter.getIntegerAttr(
+ complexElemLLVMTy,
+ mlir::cast<cir::IntAttr>(complexAttr.getImag()).getValue());
+ } else {
+ components[0] = rewriter.getFloatAttr(
+ complexElemLLVMTy,
+ mlir::cast<cir::FPAttr>(complexAttr.getReal()).getValue());
+ components[1] = rewriter.getFloatAttr(
+ complexElemLLVMTy,
+ mlir::cast<cir::FPAttr>(complexAttr.getImag()).getValue());
+ }
+
+ mlir::Location loc = parentOp->getLoc();
+ return rewriter.create<mlir::LLVM::ConstantOp>(
+ loc, converter->convertType(complexAttr.getType()),
+ rewriter.getArrayAttr(components));
+}
+
/// ConstPtrAttr visitor.
mlir::Value CIRAttrToValue::visitCirAttr(cir::ConstPtrAttr ptrAttr) {
mlir::Location loc = parentOp->getLoc();
@@ -241,13 +278,6 @@ mlir::Value CIRAttrToValue::visitCirAttr(cir::ConstPtrAttr ptrAttr) {
loc, converter->convertType(ptrAttr.getType()), ptrVal);
}
-/// FPAttr visitor.
-mlir::Value CIRAttrToValue::visitCirAttr(cir::FPAttr fltAttr) {
- mlir::Location loc = parentOp->getLoc();
- return rewriter.create<mlir::LLVM::ConstantOp>(
- loc, converter->convertType(fltAttr.getType()), fltAttr.getValue());
-}
-
// ConstArrayAttr visitor
mlir::Value CIRAttrToValue::visitCirAttr(cir::ConstArrayAttr attr) {
mlir::Type llvmTy = converter->convertType(attr.getType());
@@ -341,9 +371,11 @@ public:
mlir::Attribute visitCirAttr(cir::IntAttr attr) {
return rewriter.getIntegerAttr(llvmType, attr.getValue());
}
+
mlir::Attribute visitCirAttr(cir::FPAttr attr) {
return rewriter.getFloatAttr(llvmType, attr.getValue());
}
+
mlir::Attribute visitCirAttr(cir::BoolAttr attr) {
return rewriter.getBoolAttr(attr.getValue());
}
@@ -986,7 +1018,7 @@ CIRToLLVMGlobalOpLowering::matchAndRewriteRegionInitializedGlobal(
mlir::ConversionPatternRewriter &rewriter) const {
// TODO: Generalize this handling when more types are needed here.
assert((isa<cir::ConstArrayAttr, cir::ConstVectorAttr, cir::ConstPtrAttr,
- cir::ZeroAttr>(init)));
+ cir::ConstComplexAttr, cir::ZeroAttr>(init)));
// TODO(cir): once LLVM's dialect has proper equivalent attributes this
// should be updated. For now, we use a custom op to initialize globals
@@ -1039,7 +1071,8 @@ mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite(
return mlir::failure();
}
} else if (mlir::isa<cir::ConstArrayAttr, cir::ConstVectorAttr,
- cir::ConstPtrAttr, cir::ZeroAttr>(init.value())) {
+ cir::ConstPtrAttr, cir::ConstComplexAttr,
+ cir::ZeroAttr>(init.value())) {
// TODO(cir): once LLVM's dialect has proper equivalent attributes this
// should be updated. For now, we use a custom op to initialize globals
// to the appropriate value.
@@ -1571,6 +1604,14 @@ static void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
converter.addConversion([&](cir::BF16Type type) -> mlir::Type {
return mlir::BFloat16Type::get(type.getContext());
});
+ converter.addConversion([&](cir::ComplexType type) -> mlir::Type {
+ // A complex type is lowered to an LLVM struct that contains the real and
+ // imaginary part as data fields.
+ mlir::Type elementTy = converter.convertType(type.getElementType());
+ mlir::Type structFields[2] = {elementTy, elementTy};
+ return mlir::LLVM::LLVMStructType::getLiteral(type.getContext(),
+ structFields);
+ });
converter.addConversion([&](cir::FuncType type) -> std::optional<mlir::Type> {
auto result = converter.convertType(type.getReturnType());
llvm::SmallVector<mlir::Type> arguments;