Skip to content

Commit bddd7a6

Browse files
committed
[flang] REAL(KIND=3) and COMPLEX(KIND=3) descriptors
Update descriptor generation to correctly set the `type` field for REAL(3) and COMPLEX(3) objects.
1 parent dcf296b commit bddd7a6

File tree

7 files changed

+229
-139
lines changed

7 files changed

+229
-139
lines changed

flang/include/flang/ISO_Fortran_binding.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ typedef unsigned char CFI_attribute_t;
4343
typedef signed char CFI_type_t;
4444
/* These codes are required to be macros (i.e., #ifdef will work).
4545
* They are not required to be distinct, but neither are they required
46-
* to have had their synonyms combined. Codes marked as extensions may be
47-
* place holders for as yet unimplemented types.
46+
* to have had their synonyms combined.
4847
*/
4948
#define CFI_type_signed_char 1
5049
#define CFI_type_short 2
@@ -56,7 +55,7 @@ typedef signed char CFI_type_t;
5655
#define CFI_type_int16_t 8
5756
#define CFI_type_int32_t 9
5857
#define CFI_type_int64_t 10
59-
#define CFI_type_int128_t 11 /* extension */
58+
#define CFI_type_int128_t 11 /* extension kind=16 */
6059
#define CFI_type_int_least8_t 12
6160
#define CFI_type_int_least16_t 13
6261
#define CFI_type_int_least32_t 14
@@ -88,8 +87,8 @@ typedef signed char CFI_type_t;
8887
#define CFI_type_char 40
8988
#define CFI_type_cptr 41
9089
#define CFI_type_struct 42
91-
#define CFI_type_char16_t 43 /* extension */
92-
#define CFI_type_char32_t 44 /* extension */
90+
#define CFI_type_char16_t 43 /* extension kind=2 */
91+
#define CFI_type_char32_t 44 /* extension kind=4 */
9392
#define CFI_TYPE_LAST CFI_type_char32_t
9493
#define CFI_type_other (-1) // must be negative
9594

flang/include/flang/Optimizer/Dialect/FIRType.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,8 @@ bool hasAbstractResult(mlir::FunctionType ty);
359359
mlir::Type fromRealTypeID(mlir::MLIRContext *context, llvm::Type::TypeID typeID,
360360
fir::KindTy kind);
361361

362+
int getTypeCode(mlir::Type ty, KindMapping &kindMap);
363+
362364
inline bool BaseBoxType::classof(mlir::Type type) {
363365
return type.isa<fir::BoxType, fir::ClassType>();
364366
}

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 27 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,119 +1272,42 @@ struct EmboxCommonConversion : public FIROpConversion<OP> {
12721272
mlir::Location loc, mlir::ConversionPatternRewriter &rewriter,
12731273
mlir::Type boxEleTy, mlir::ValueRange lenParams = {}) const {
12741274
auto i64Ty = mlir::IntegerType::get(rewriter.getContext(), 64);
1275-
auto getKindMap = [&]() -> fir::KindMapping & {
1276-
return this->lowerTy().getKindMap();
1277-
};
1278-
auto doInteger =
1279-
[&](mlir::Type type,
1280-
unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
1281-
int typeCode = fir::integerBitsToTypeCode(width);
1282-
return {
1283-
genTypeStrideInBytes(loc, i64Ty, rewriter, this->convertType(type)),
1284-
this->genConstantOffset(loc, rewriter, typeCode)};
1285-
};
1286-
auto doLogical =
1287-
[&](mlir::Type type,
1288-
unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
1289-
int typeCode = fir::logicalBitsToTypeCode(width);
1290-
return {
1291-
genTypeStrideInBytes(loc, i64Ty, rewriter, this->convertType(type)),
1292-
this->genConstantOffset(loc, rewriter, typeCode)};
1293-
};
1294-
auto doFloat = [&](mlir::Type type,
1295-
unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
1296-
int typeCode = fir::realBitsToTypeCode(width);
1297-
return {
1298-
genTypeStrideInBytes(loc, i64Ty, rewriter, this->convertType(type)),
1299-
this->genConstantOffset(loc, rewriter, typeCode)};
1300-
};
1301-
auto doComplex =
1302-
[&](mlir::Type type,
1303-
unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
1304-
auto typeCode = fir::complexBitsToTypeCode(width);
1305-
return {
1306-
genTypeStrideInBytes(loc, i64Ty, rewriter, this->convertType(type)),
1307-
this->genConstantOffset(loc, rewriter, typeCode)};
1308-
};
1309-
auto doCharacter = [&](fir::CharacterType type, mlir::ValueRange lenParams)
1310-
-> std::tuple<mlir::Value, mlir::Value> {
1311-
unsigned bitWidth = getKindMap().getCharacterBitsize(type.getFKind());
1312-
auto typeCode = fir::characterBitsToTypeCode(bitWidth);
1313-
auto typeCodeVal = this->genConstantOffset(loc, rewriter, typeCode);
1314-
1315-
bool lengthIsConst = (type.getLen() != fir::CharacterType::unknownLen());
1316-
mlir::Value eleSize =
1317-
genTypeStrideInBytes(loc, i64Ty, rewriter, this->convertType(type));
1318-
1319-
if (!lengthIsConst) {
1320-
// If length is constant, then the fir::CharacterType will be
1321-
// represented as an array of known size of elements having
1322-
// the corresponding LLVM type. In this case eleSize already
1323-
// holds correct memory size. If length is not constant, then
1324-
// the fir::CharacterType will decay to a scalar type,
1325-
// so we have to multiply it by the non-constant length
1326-
// to get its size in memory.
1275+
if (auto eleTy = fir::dyn_cast_ptrEleTy(boxEleTy))
1276+
boxEleTy = eleTy;
1277+
if (auto seqTy = boxEleTy.dyn_cast<fir::SequenceType>())
1278+
return getSizeAndTypeCode(loc, rewriter, seqTy.getEleTy(), lenParams);
1279+
if (boxEleTy.isa<mlir::NoneType>()) // unlimited polymorphic or assumed type
1280+
return {rewriter.create<mlir::LLVM::ConstantOp>(loc, i64Ty, 0),
1281+
this->genConstantOffset(loc, rewriter, CFI_type_other)};
1282+
mlir::Value typeCodeVal = this->genConstantOffset(
1283+
loc, rewriter,
1284+
fir::getTypeCode(boxEleTy, this->lowerTy().getKindMap()));
1285+
if (fir::isa_integer(boxEleTy) || boxEleTy.dyn_cast<fir::LogicalType>() ||
1286+
fir::isa_real(boxEleTy) || fir::isa_complex(boxEleTy))
1287+
return {genTypeStrideInBytes(loc, i64Ty, rewriter,
1288+
this->convertType(boxEleTy)),
1289+
typeCodeVal};
1290+
if (auto charTy = boxEleTy.dyn_cast<fir::CharacterType>()) {
1291+
mlir::Value size =
1292+
genTypeStrideInBytes(loc, i64Ty, rewriter, this->convertType(charTy));
1293+
if (charTy.getLen() == fir::CharacterType::unknownLen()) {
1294+
// Multiply the single character size by the length.
13271295
assert(!lenParams.empty());
13281296
auto len64 = FIROpConversion<OP>::integerCast(loc, rewriter, i64Ty,
13291297
lenParams.back());
1330-
eleSize =
1331-
rewriter.create<mlir::LLVM::MulOp>(loc, i64Ty, eleSize, len64);
1298+
size = rewriter.create<mlir::LLVM::MulOp>(loc, i64Ty, size, len64);
13321299
}
1333-
return {eleSize, typeCodeVal};
1300+
return {size, typeCodeVal};
13341301
};
1335-
// Pointer-like types.
1336-
if (auto eleTy = fir::dyn_cast_ptrEleTy(boxEleTy))
1337-
boxEleTy = eleTy;
1338-
// Integer types.
1339-
if (fir::isa_integer(boxEleTy)) {
1340-
if (auto ty = boxEleTy.dyn_cast<mlir::IntegerType>())
1341-
return doInteger(ty, ty.getWidth());
1342-
auto ty = boxEleTy.cast<fir::IntegerType>();
1343-
return doInteger(ty, getKindMap().getIntegerBitsize(ty.getFKind()));
1344-
}
1345-
// Floating point types.
1346-
if (fir::isa_real(boxEleTy)) {
1347-
if (auto ty = boxEleTy.dyn_cast<mlir::FloatType>())
1348-
return doFloat(ty, ty.getWidth());
1349-
auto ty = boxEleTy.cast<fir::RealType>();
1350-
return doFloat(ty, getKindMap().getRealBitsize(ty.getFKind()));
1351-
}
1352-
// Complex types.
1353-
if (fir::isa_complex(boxEleTy)) {
1354-
if (auto ty = boxEleTy.dyn_cast<mlir::ComplexType>())
1355-
return doComplex(
1356-
ty, ty.getElementType().cast<mlir::FloatType>().getWidth());
1357-
auto ty = boxEleTy.cast<fir::ComplexType>();
1358-
return doComplex(ty, getKindMap().getRealBitsize(ty.getFKind()));
1359-
}
1360-
// Character types.
1361-
if (auto ty = boxEleTy.dyn_cast<fir::CharacterType>())
1362-
return doCharacter(ty, lenParams);
1363-
// Logical type.
1364-
if (auto ty = boxEleTy.dyn_cast<fir::LogicalType>())
1365-
return doLogical(ty, getKindMap().getLogicalBitsize(ty.getFKind()));
1366-
// Array types.
1367-
if (auto seqTy = boxEleTy.dyn_cast<fir::SequenceType>())
1368-
return getSizeAndTypeCode(loc, rewriter, seqTy.getEleTy(), lenParams);
1369-
// Derived-type types.
1370-
if (boxEleTy.isa<fir::RecordType>()) {
1371-
auto eleSize = genTypeStrideInBytes(loc, i64Ty, rewriter,
1372-
this->convertType(boxEleTy));
1373-
return {eleSize,
1374-
this->genConstantOffset(loc, rewriter, fir::derivedToTypeCode())};
1375-
}
1376-
// Reference type.
13771302
if (fir::isa_ref_type(boxEleTy)) {
13781303
auto ptrTy = mlir::LLVM::LLVMPointerType::get(
13791304
mlir::LLVM::LLVMVoidType::get(rewriter.getContext()));
1380-
mlir::Value size = genTypeStrideInBytes(loc, i64Ty, rewriter, ptrTy);
1381-
return {size, this->genConstantOffset(loc, rewriter, CFI_type_cptr)};
1305+
return {genTypeStrideInBytes(loc, i64Ty, rewriter, ptrTy), typeCodeVal};
13821306
}
1383-
// Unlimited polymorphic or assumed type. Use 0 and CFI_type_other since the
1384-
// information is not none at this point.
1385-
if (boxEleTy.isa<mlir::NoneType>())
1386-
return {rewriter.create<mlir::LLVM::ConstantOp>(loc, i64Ty, 0),
1387-
this->genConstantOffset(loc, rewriter, CFI_type_other)};
1307+
if (boxEleTy.isa<fir::RecordType>())
1308+
return {genTypeStrideInBytes(loc, i64Ty, rewriter,
1309+
this->convertType(boxEleTy)),
1310+
typeCodeVal};
13881311
fir::emitFatalError(loc, "unhandled type in fir.box code generation");
13891312
}
13901313

flang/lib/Optimizer/Dialect/FIRType.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "flang/Optimizer/Dialect/FIRType.h"
14+
#include "flang/ISO_Fortran_binding.h"
1415
#include "flang/Optimizer/Dialect/FIRDialect.h"
1516
#include "flang/Optimizer/Dialect/Support/KindMapping.h"
1617
#include "flang/Tools/PointerModels.h"
@@ -381,6 +382,97 @@ mlir::Type unwrapSeqOrBoxedSeqType(mlir::Type ty) {
381382
return ty;
382383
}
383384

385+
/// Return the ISO_C_BINDING intrinsic module value of type \p ty.
386+
int getTypeCode(mlir::Type ty, fir::KindMapping &kindMap) {
387+
unsigned width = 0;
388+
if (mlir::IntegerType intTy = ty.dyn_cast<mlir::IntegerType>()) {
389+
switch (intTy.getWidth()) {
390+
case 8:
391+
return CFI_type_int8_t;
392+
case 16:
393+
return CFI_type_int16_t;
394+
case 32:
395+
return CFI_type_int32_t;
396+
case 64:
397+
return CFI_type_int64_t;
398+
case 128:
399+
return CFI_type_int128_t;
400+
}
401+
llvm_unreachable("unsupported integer type");
402+
}
403+
if (fir::LogicalType logicalTy = ty.dyn_cast<fir::LogicalType>()) {
404+
switch (kindMap.getLogicalBitsize(logicalTy.getFKind())) {
405+
case 8:
406+
return CFI_type_Bool;
407+
case 16:
408+
return CFI_type_int_least16_t;
409+
case 32:
410+
return CFI_type_int_least32_t;
411+
case 64:
412+
return CFI_type_int_least64_t;
413+
}
414+
llvm_unreachable("unsupported logical type");
415+
}
416+
if (mlir::FloatType floatTy = ty.dyn_cast<mlir::FloatType>()) {
417+
switch (floatTy.getWidth()) {
418+
case 16:
419+
return floatTy.isBF16() ? CFI_type_bfloat : CFI_type_half_float;
420+
case 32:
421+
return CFI_type_float;
422+
case 64:
423+
return CFI_type_double;
424+
case 80:
425+
return CFI_type_extended_double;
426+
case 128:
427+
return CFI_type_float128;
428+
}
429+
llvm_unreachable("unsupported real type");
430+
}
431+
if (fir::isa_complex(ty)) {
432+
if (mlir::ComplexType complexTy = ty.dyn_cast<mlir::ComplexType>()) {
433+
mlir::FloatType floatTy =
434+
complexTy.getElementType().cast<mlir::FloatType>();
435+
if (floatTy.isBF16())
436+
return CFI_type_bfloat_Complex;
437+
width = floatTy.getWidth();
438+
} else if (fir::ComplexType complexTy = ty.dyn_cast<fir::ComplexType>()) {
439+
auto FKind = complexTy.getFKind();
440+
if (FKind == 3)
441+
return CFI_type_bfloat_Complex;
442+
width = kindMap.getRealBitsize(FKind);
443+
}
444+
switch (width) {
445+
case 16:
446+
return CFI_type_half_float_Complex;
447+
case 32:
448+
return CFI_type_float_Complex;
449+
case 64:
450+
return CFI_type_double_Complex;
451+
case 80:
452+
return CFI_type_extended_double_Complex;
453+
case 128:
454+
return CFI_type_float128_Complex;
455+
}
456+
llvm_unreachable("unsupported complex size");
457+
}
458+
if (fir::CharacterType charTy = ty.dyn_cast<fir::CharacterType>()) {
459+
switch (kindMap.getCharacterBitsize(charTy.getFKind())) {
460+
case 8:
461+
return CFI_type_char;
462+
case 16:
463+
return CFI_type_char16_t;
464+
case 32:
465+
return CFI_type_char32_t;
466+
}
467+
llvm_unreachable("unsupported character type");
468+
}
469+
if (fir::isa_ref_type(ty))
470+
return CFI_type_cptr;
471+
if (ty.isa<fir::RecordType>())
472+
return CFI_type_struct;
473+
llvm_unreachable("unsupported type");
474+
}
475+
384476
} // namespace fir
385477

386478
namespace {

flang/lib/Optimizer/Transforms/PolymorphicOpConversion.cpp

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ class SelectTypeConv : public OpConversionPattern<fir::SelectTypeOp> {
6262
mlir::Type ty, mlir::ModuleOp mod,
6363
mlir::PatternRewriter &rewriter) const;
6464

65-
static int getTypeCode(mlir::Type ty, fir::KindMapping &kindMap);
66-
6765
mlir::LogicalResult genTypeLadderStep(mlir::Location loc,
6866
mlir::Value selector,
6967
mlir::Attribute attr, mlir::Block *dest,
@@ -362,7 +360,7 @@ mlir::LogicalResult SelectTypeConv::genTypeLadderStep(
362360
a.getType().isa<fir::CharacterType>()) {
363361
// For type guard statement with Intrinsic type spec the type code of
364362
// the descriptor is compared.
365-
int code = getTypeCode(a.getType(), kindMap);
363+
int code = fir::getTypeCode(a.getType(), kindMap);
366364
if (code == 0)
367365
return mlir::emitError(loc)
368366
<< "type code unavailable for " << a.getType();
@@ -461,28 +459,6 @@ SelectTypeConv::genTypeDescCompare(mlir::Location loc, mlir::Value selector,
461459
loc, mlir::arith::CmpIPredicate::eq, typeDescInt, selectorTdescInt);
462460
}
463461

464-
int SelectTypeConv::getTypeCode(mlir::Type ty, fir::KindMapping &kindMap) {
465-
if (auto intTy = ty.dyn_cast<mlir::IntegerType>())
466-
return fir::integerBitsToTypeCode(intTy.getWidth());
467-
if (auto floatTy = ty.dyn_cast<mlir::FloatType>())
468-
return fir::realBitsToTypeCode(floatTy.getWidth());
469-
if (auto logicalTy = ty.dyn_cast<fir::LogicalType>())
470-
return fir::logicalBitsToTypeCode(
471-
kindMap.getLogicalBitsize(logicalTy.getFKind()));
472-
if (fir::isa_complex(ty)) {
473-
if (auto cmplxTy = ty.dyn_cast<mlir::ComplexType>())
474-
return fir::complexBitsToTypeCode(
475-
cmplxTy.getElementType().cast<mlir::FloatType>().getWidth());
476-
auto cmplxTy = ty.cast<fir::ComplexType>();
477-
return fir::complexBitsToTypeCode(
478-
kindMap.getRealBitsize(cmplxTy.getFKind()));
479-
}
480-
if (auto charTy = ty.dyn_cast<fir::CharacterType>())
481-
return fir::characterBitsToTypeCode(
482-
kindMap.getCharacterBitsize(charTy.getFKind()));
483-
return 0;
484-
}
485-
486462
llvm::SmallSet<llvm::StringRef, 4>
487463
SelectTypeConv::collectAncestors(fir::DispatchTableOp dt,
488464
mlir::ModuleOp mod) const {

0 commit comments

Comments
 (0)