2222
2323using namespace fir ;
2424
25+ namespace fir ::details {
26+ llvm::StringRef Attributes::getIntExtensionAttrName () const {
27+ // The attribute names are available via LLVM dialect interfaces
28+ // like getZExtAttrName(), getByValAttrName(), etc., so we'd better
29+ // use them than literals.
30+ if (isZeroExt ())
31+ return " llvm.zeroext" ;
32+ else if (isSignExt ())
33+ return " llvm.signext" ;
34+ return {};
35+ }
36+ } // namespace fir::details
37+
2538// Reduce a REAL/float type to the floating point semantics.
2639static const llvm::fltSemantics &floatToSemantics (const KindMapping &kindMap,
2740 mlir::Type type) {
@@ -41,17 +54,17 @@ struct GenericTarget : public CodeGenSpecifics {
4154 assert (fir::isa_real (eleTy));
4255 // Use a type that will be translated into LLVM as:
4356 // { t, t } struct of 2 eleTy
44- mlir::TypeRange range = { eleTy, eleTy};
45- return mlir::TupleType::get ( eleTy. getContext (), range );
57+ return mlir::TupleType::get ( eleTy. getContext (),
58+ mlir::TypeRange{ eleTy, eleTy} );
4659 }
4760
4861 mlir::Type boxcharMemoryType (mlir::Type eleTy) const override {
4962 auto idxTy = mlir::IntegerType::get (eleTy.getContext (), S::defaultWidth);
5063 auto ptrTy = fir::ReferenceType::get (eleTy);
5164 // Use a type that will be translated into LLVM as:
5265 // { t*, index }
53- mlir::TypeRange range = {ptrTy, idxTy};
54- return mlir::TupleType::get (eleTy. getContext (), range );
66+ return mlir::TupleType::get (eleTy. getContext (),
67+ mlir::TypeRange{ptrTy, idxTy} );
5568 }
5669
5770 Marshalling boxcharArgumentType (mlir::Type eleTy, bool sret) const override {
@@ -67,6 +80,46 @@ struct GenericTarget : public CodeGenSpecifics {
6780 /* sret=*/ sret, /* append=*/ !sret});
6881 return marshal;
6982 }
83+
84+ CodeGenSpecifics::Marshalling
85+ integerArgumentType (mlir::Location loc,
86+ mlir::IntegerType argTy) const override {
87+ CodeGenSpecifics::Marshalling marshal;
88+ AT::IntegerExtension intExt = AT::IntegerExtension::None;
89+ if (argTy.getWidth () < getCIntTypeWidth ()) {
90+ // isSigned() and isUnsigned() branches below are dead code currently.
91+ // If needed, we can generate calls with signed/unsigned argument types
92+ // to more precisely match C side (e.g. for Fortran runtime functions
93+ // with 'unsigned short' arguments).
94+ if (argTy.isSigned ())
95+ intExt = AT::IntegerExtension::Sign;
96+ else if (argTy.isUnsigned ())
97+ intExt = AT::IntegerExtension::Zero;
98+ else if (argTy.isSignless ()) {
99+ // Zero extend for 'i1' and sign extend for other types.
100+ if (argTy.getWidth () == 1 )
101+ intExt = AT::IntegerExtension::Zero;
102+ else
103+ intExt = AT::IntegerExtension::Sign;
104+ }
105+ }
106+
107+ marshal.emplace_back (argTy, AT{/* alignment=*/ 0 , /* byval=*/ false ,
108+ /* sret=*/ false , /* append=*/ false ,
109+ /* intExt=*/ intExt});
110+ return marshal;
111+ }
112+
113+ CodeGenSpecifics::Marshalling
114+ integerReturnType (mlir::Location loc,
115+ mlir::IntegerType argTy) const override {
116+ return integerArgumentType (loc, argTy);
117+ }
118+
119+ // Width of 'int' type is 32-bits for almost all targets, except
120+ // for AVR and MSP430 (see TargetInfo initializations
121+ // in clang/lib/Basic/Targets).
122+ unsigned char getCIntTypeWidth () const override { return 32 ; }
70123};
71124} // namespace
72125
@@ -86,8 +139,8 @@ struct TargetI386 : public GenericTarget<TargetI386> {
86139 CodeGenSpecifics::Marshalling marshal;
87140 // Use a type that will be translated into LLVM as:
88141 // { t, t } struct of 2 eleTy, byval, align 4
89- mlir::TypeRange range = {eleTy, eleTy};
90- auto structTy = mlir::TupleType::get (eleTy.getContext (), range );
142+ auto structTy =
143+ mlir::TupleType::get (eleTy.getContext (), mlir::TypeRange{eleTy, eleTy} );
91144 marshal.emplace_back (fir::ReferenceType::get (structTy),
92145 AT{/* alignment=*/ 4 , /* byval=*/ true });
93146 return marshal;
@@ -105,8 +158,8 @@ struct TargetI386 : public GenericTarget<TargetI386> {
105158 } else if (sem == &llvm::APFloat::IEEEdouble ()) {
106159 // Use a type that will be translated into LLVM as:
107160 // { t, t } struct of 2 eleTy, sret, align 4
108- mlir::TypeRange range = { eleTy, eleTy};
109- auto structTy = mlir::TupleType::get ( eleTy. getContext (), range );
161+ auto structTy = mlir::TupleType::get ( eleTy. getContext (),
162+ mlir::TypeRange{ eleTy, eleTy} );
110163 marshal.emplace_back (fir::ReferenceType::get (structTy),
111164 AT{/* alignment=*/ 4 , /* byval=*/ false , /* sret=*/ true });
112165 } else {
@@ -141,10 +194,10 @@ struct TargetX86_64 : public GenericTarget<TargetX86_64> {
141194 } else if (sem == &llvm::APFloat::IEEEquad ()) {
142195 // Use a type that will be translated into LLVM as:
143196 // { fp128, fp128 } struct of 2 fp128, byval, align 16
144- mlir::TypeRange range = {eleTy, eleTy};
145- marshal. emplace_back ( fir::ReferenceType::get (
146- mlir::TupleType::get ( eleTy.getContext (), range )),
147- AT{/* align=*/ 16 , /* byval=*/ true });
197+ marshal. emplace_back (
198+ fir::ReferenceType::get ( mlir::TupleType ::get (
199+ eleTy.getContext (), mlir::TypeRange{eleTy, eleTy} )),
200+ AT{/* align=*/ 16 , /* byval=*/ true });
148201 } else {
149202 TODO (loc, " complex for this precision" );
150203 }
@@ -161,16 +214,16 @@ struct TargetX86_64 : public GenericTarget<TargetX86_64> {
161214 } else if (sem == &llvm::APFloat::IEEEdouble ()) {
162215 // Use a type that will be translated into LLVM as:
163216 // { double, double } struct of 2 double
164- mlir::TypeRange range = { eleTy, eleTy};
165- marshal. emplace_back ( mlir::TupleType::get ( eleTy. getContext (), range ),
217+ marshal. emplace_back ( mlir::TupleType::get ( eleTy. getContext (),
218+ mlir::TypeRange{ eleTy, eleTy} ),
166219 AT{});
167220 } else if (sem == &llvm::APFloat::IEEEquad ()) {
168221 // Use a type that will be translated into LLVM as:
169222 // { fp128, fp128 } struct of 2 fp128, sret, align 16
170- mlir::TypeRange range = {eleTy, eleTy};
171- marshal. emplace_back ( fir::ReferenceType::get (
172- mlir::TupleType::get ( eleTy.getContext (), range )),
173- AT{/* align=*/ 16 , /* byval=*/ false , /* sret=*/ true });
223+ marshal. emplace_back (
224+ fir::ReferenceType::get ( mlir::TupleType ::get (
225+ eleTy.getContext (), mlir::TypeRange{eleTy, eleTy} )),
226+ AT{/* align=*/ 16 , /* byval=*/ false , /* sret=*/ true });
174227 } else {
175228 TODO (loc, " complex for this precision" );
176229 }
@@ -211,8 +264,8 @@ struct TargetAArch64 : public GenericTarget<TargetAArch64> {
211264 sem == &llvm::APFloat::IEEEdouble ()) {
212265 // Use a type that will be translated into LLVM as:
213266 // { t, t } struct of 2 eleTy
214- mlir::TypeRange range = { eleTy, eleTy};
215- marshal. emplace_back ( mlir::TupleType::get ( eleTy. getContext (), range ),
267+ marshal. emplace_back ( mlir::TupleType::get ( eleTy. getContext (),
268+ mlir::TypeRange{ eleTy, eleTy} ),
216269 AT{});
217270 } else {
218271 TODO (loc, " complex for this precision" );
@@ -246,8 +299,9 @@ struct TargetPPC64 : public GenericTarget<TargetPPC64> {
246299 CodeGenSpecifics::Marshalling marshal;
247300 // Use a type that will be translated into LLVM as:
248301 // { t, t } struct of 2 element type
249- mlir::TypeRange range = {eleTy, eleTy};
250- marshal.emplace_back (mlir::TupleType::get (eleTy.getContext (), range), AT{});
302+ marshal.emplace_back (
303+ mlir::TupleType::get (eleTy.getContext (), mlir::TypeRange{eleTy, eleTy}),
304+ AT{});
251305 return marshal;
252306 }
253307};
@@ -277,8 +331,9 @@ struct TargetPPC64le : public GenericTarget<TargetPPC64le> {
277331 CodeGenSpecifics::Marshalling marshal;
278332 // Use a type that will be translated into LLVM as:
279333 // { t, t } struct of 2 element type
280- mlir::TypeRange range = {eleTy, eleTy};
281- marshal.emplace_back (mlir::TupleType::get (eleTy.getContext (), range), AT{});
334+ marshal.emplace_back (
335+ mlir::TupleType::get (eleTy.getContext (), mlir::TypeRange{eleTy, eleTy}),
336+ AT{});
282337 return marshal;
283338 }
284339};
@@ -300,8 +355,8 @@ struct TargetSparc : public GenericTarget<TargetSparc> {
300355 CodeGenSpecifics::Marshalling marshal;
301356 // Use a type that will be translated into LLVM as:
302357 // { t, t } struct of 2 eleTy
303- mlir::TypeRange range = {eleTy, eleTy};
304- auto structTy = mlir::TupleType::get (eleTy.getContext (), range );
358+ auto structTy =
359+ mlir::TupleType::get (eleTy.getContext (), mlir::TypeRange{eleTy, eleTy} );
305360 marshal.emplace_back (fir::ReferenceType::get (structTy), AT{});
306361 return marshal;
307362 }
@@ -312,8 +367,8 @@ struct TargetSparc : public GenericTarget<TargetSparc> {
312367 CodeGenSpecifics::Marshalling marshal;
313368 // Use a type that will be translated into LLVM as:
314369 // { t, t } struct of 2 eleTy, byval
315- mlir::TypeRange range = {eleTy, eleTy};
316- auto structTy = mlir::TupleType::get (eleTy.getContext (), range );
370+ auto structTy =
371+ mlir::TupleType::get (eleTy.getContext (), mlir::TypeRange{eleTy, eleTy} );
317372 marshal.emplace_back (fir::ReferenceType::get (structTy),
318373 AT{/* alignment=*/ 0 , /* byval=*/ true });
319374 return marshal;
@@ -343,10 +398,10 @@ struct TargetSparcV9 : public GenericTarget<TargetSparcV9> {
343398 } else if (sem == &llvm::APFloat::IEEEquad ()) {
344399 // Use a type that will be translated into LLVM as:
345400 // { fp128, fp128 } struct of 2 fp128, byval, align 16
346- mlir::TypeRange range = {eleTy, eleTy};
347- marshal. emplace_back ( fir::ReferenceType::get (
348- mlir::TupleType::get ( eleTy.getContext (), range )),
349- AT{/* align=*/ 16 , /* byval=*/ true });
401+ marshal. emplace_back (
402+ fir::ReferenceType::get ( mlir::TupleType ::get (
403+ eleTy.getContext (), mlir::TypeRange{eleTy, eleTy} )),
404+ AT{/* align=*/ 16 , /* byval=*/ true });
350405 } else {
351406 TODO (loc, " complex for this precision" );
352407 }
@@ -358,8 +413,9 @@ struct TargetSparcV9 : public GenericTarget<TargetSparcV9> {
358413 CodeGenSpecifics::Marshalling marshal;
359414 // Use a type that will be translated into LLVM as:
360415 // { eleTy, eleTy } struct of 2 eleTy
361- mlir::TypeRange range = {eleTy, eleTy};
362- marshal.emplace_back (mlir::TupleType::get (eleTy.getContext (), range), AT{});
416+ marshal.emplace_back (
417+ mlir::TupleType::get (eleTy.getContext (), mlir::TypeRange{eleTy, eleTy}),
418+ AT{});
363419 return marshal;
364420 }
365421};
@@ -398,8 +454,8 @@ struct TargetRISCV64 : public GenericTarget<TargetRISCV64> {
398454 sem == &llvm::APFloat::IEEEdouble ()) {
399455 // Use a type that will be translated into LLVM as:
400456 // { t, t } struct of 2 eleTy, byVal
401- mlir::TypeRange range = { eleTy, eleTy};
402- marshal. emplace_back ( mlir::TupleType::get ( eleTy. getContext (), range ),
457+ marshal. emplace_back ( mlir::TupleType::get ( eleTy. getContext (),
458+ mlir::TypeRange{ eleTy, eleTy} ),
403459 AT{/* alignment=*/ 0 , /* byval=*/ true });
404460 } else {
405461 TODO (loc, " complex for this precision" );
0 commit comments