@@ -1443,14 +1443,35 @@ struct TargetAMDGPU : public GenericTarget<TargetAMDGPU> {
14431443 CodeGenSpecifics::Marshalling
14441444 complexArgumentType (mlir::Location loc, mlir::Type eleTy) const override {
14451445 CodeGenSpecifics::Marshalling marshal;
1446- TODO (loc, " handle complex argument types" );
1446+ const auto *sem = &floatToSemantics (kindMap, eleTy);
1447+ if (sem == &llvm::APFloat::IEEEsingle ()) {
1448+ // Lower COMPLEX(KIND=4) as an array of two element values.
1449+ marshal.emplace_back (fir::SequenceType::get ({2 }, eleTy), AT{});
1450+ } else if (sem == &llvm::APFloat::IEEEdouble ()) {
1451+ // Pass COMPLEX(KIND=8) as two separate arguments.
1452+ marshal.emplace_back (eleTy, AT{});
1453+ marshal.emplace_back (eleTy, AT{});
1454+ } else {
1455+ typeTodo (sem, loc, " argument" );
1456+ }
14471457 return marshal;
14481458 }
14491459
14501460 CodeGenSpecifics::Marshalling
14511461 complexReturnType (mlir::Location loc, mlir::Type eleTy) const override {
14521462 CodeGenSpecifics::Marshalling marshal;
1453- TODO (loc, " handle complex return types" );
1463+ const auto *sem = &floatToSemantics (kindMap, eleTy);
1464+ if (sem == &llvm::APFloat::IEEEsingle ()) {
1465+ // Return COMPLEX(KIND=4) as an array of two elements.
1466+ marshal.emplace_back (fir::SequenceType::get ({2 }, eleTy), AT{});
1467+ } else if (sem == &llvm::APFloat::IEEEdouble ()) {
1468+ // Return COMPLEX(KIND=8) via an aggregate with two fields.
1469+ marshal.emplace_back (mlir::TupleType::get (eleTy.getContext (),
1470+ mlir::TypeRange{eleTy, eleTy}),
1471+ AT{});
1472+ } else {
1473+ typeTodo (sem, loc, " return" );
1474+ }
14541475 return marshal;
14551476 }
14561477};
0 commit comments