diff --git a/flang/lib/Optimizer/CodeGen/TypeConverter.h b/flang/lib/Optimizer/CodeGen/TypeConverter.h --- a/flang/lib/Optimizer/CodeGen/TypeConverter.h +++ b/flang/lib/Optimizer/CodeGen/TypeConverter.h @@ -37,6 +37,8 @@ // Each conversion should return a value of type mlir::Type. addConversion([&](BoxType box) { return convertBoxType(box); }); + addConversion( + [&](fir::CharacterType charTy) { return convertCharType(charTy); }); addConversion([&](fir::LogicalType boolTy) { return mlir::IntegerType::get( &getContext(), kindMapping.getLogicalBitsize(boolTy.getFKind())); @@ -150,6 +152,18 @@ /*isPacked=*/false)); } + unsigned characterBitsize(fir::CharacterType charTy) { + return kindMapping.getCharacterBitsize(charTy.getFKind()); + } + + // fir.char --> llvm<"ix*"> where ix is scaled by kind mapping + mlir::Type convertCharType(fir::CharacterType charTy) { + auto iTy = mlir::IntegerType::get(&getContext(), characterBitsize(charTy)); + if (charTy.getLen() == fir::CharacterType::unknownLen()) + return iTy; + return mlir::LLVM::LLVMArrayType::get(iTy, charTy.getLen()); + } + // Use the target specifics to figure out how to map complex to LLVM IR. The // use of complex values in function signatures is handled before conversion // to LLVM IR dialect here. diff --git a/flang/test/Fir/types-to-llvm.fir b/flang/test/Fir/types-to-llvm.fir --- a/flang/test/Fir/types-to-llvm.fir +++ b/flang/test/Fir/types-to-llvm.fir @@ -63,6 +63,25 @@ // ----- +// Test char types `!fir.char` + +func private @foo0(%arg0: !fir.char<1, 4>, %arg1: !fir.char<1, ?>) +// CHECK-LABEL: foo0 +// CHECK-SAME: !llvm.array<4 x i8> +// CHECK-SAME: i8 + +func private @foo1(%arg0: !fir.char<2, 12>, %arg1: !fir.char<2, ?>) +// CHECK-LABEL: foo1 +// CHECK-SAME: !llvm.array<12 x i16> +// CHECK-SAME: i16 + +func private @foo2(%arg0: !fir.char<4, 8>, %arg1: !fir.char<4, ?>) +// CHECK-LABEL: foo2 +// CHECK-SAME: !llvm.array<8 x i32> +// CHECK-SAME: i32 + +// ----- + // Test `!fir.logical` conversion. func private @foo0(%arg0: !fir.logical<1>)