@@ -477,6 +477,7 @@ struct IntrinsicLibrary {
477
477
mlir::Value genIor (mlir::Type, llvm::ArrayRef<mlir::Value>);
478
478
mlir::Value genIshft (mlir::Type, llvm::ArrayRef<mlir::Value>);
479
479
mlir::Value genIshftc (mlir::Type, llvm::ArrayRef<mlir::Value>);
480
+ fir::ExtendedValue genLbound (mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
480
481
fir::ExtendedValue genLen (mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
481
482
fir::ExtendedValue genLenTrim (mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
482
483
fir::ExtendedValue genMatmul (mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
@@ -518,6 +519,7 @@ struct IntrinsicLibrary {
518
519
fir::ExtendedValue genTranspose (mlir::Type,
519
520
llvm::ArrayRef<fir::ExtendedValue>);
520
521
fir::ExtendedValue genTrim (mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
522
+ fir::ExtendedValue genUbound (mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
521
523
fir::ExtendedValue genUnpack (mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
522
524
fir::ExtendedValue genVerify (mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
523
525
// / Implement all conversion functions like DBLE, the first argument is
@@ -711,6 +713,10 @@ static constexpr IntrinsicHandler handlers[]{
711
713
{" ior" , &I::genIor},
712
714
{" ishft" , &I::genIshft},
713
715
{" ishftc" , &I::genIshftc},
716
+ {" lbound" ,
717
+ &I::genLbound,
718
+ {{{" array" , asBox}, {" dim" , asValue}, {" kind" , asValue}}},
719
+ /* isElemental=*/ false },
714
720
{" len" , &I::genLen},
715
721
{" len_trim" , &I::genLenTrim},
716
722
{" lge" , &I::genCharacterCompare<mlir::arith::CmpIPredicate::sge>},
@@ -812,7 +818,7 @@ static constexpr IntrinsicHandler handlers[]{
812
818
{" sign" , &I::genSign},
813
819
{" size" ,
814
820
&I::genSize,
815
- {{{" array" , asAddr }, {" dim" , asValue}, {" kind" , asValue}}},
821
+ {{{" array" , asBox }, {" dim" , asValue}, {" kind" , asValue}}},
816
822
/* isElemental=*/ false },
817
823
{" spacing" , &I::genSpacing},
818
824
{" spread" ,
@@ -836,6 +842,10 @@ static constexpr IntrinsicHandler handlers[]{
836
842
{{{" matrix" , asAddr}}},
837
843
/* isElemental=*/ false },
838
844
{" trim" , &I::genTrim, {{{" string" , asAddr}}}, /* isElemental=*/ false },
845
+ {" ubound" ,
846
+ &I::genUbound,
847
+ {{{" array" , asBox}, {" dim" , asValue}, {" kind" , asValue}}},
848
+ /* isElemental=*/ false },
839
849
{" unpack" ,
840
850
&I::genUnpack,
841
851
{{{" vector" , asAddr}, {" mask" , asAddr}, {" field" , asAddr}}},
@@ -1916,7 +1926,7 @@ IntrinsicLibrary::genAssociated(mlir::Type resultType,
1916
1926
fir::factory::getMutableIRBox (builder, loc, *pointer);
1917
1927
auto pointerBox = builder.create <fir::LoadOp>(loc, pointerBoxRef);
1918
1928
return Fortran::lower::genAssociated (builder, loc, pointerBox,
1919
- * args[1 ]. getUnboxed ( ));
1929
+ fir::getBase ( args[1 ]));
1920
1930
}
1921
1931
1922
1932
// AINT
@@ -2796,23 +2806,23 @@ IntrinsicLibrary::genProduct(mlir::Type resultType,
2796
2806
// RANDOM_INIT
2797
2807
void IntrinsicLibrary::genRandomInit (llvm::ArrayRef<fir::ExtendedValue> args) {
2798
2808
assert (args.size () == 2 );
2799
- Fortran::lower::genRandomInit (builder, loc, * args[0 ]. getUnboxed ( ),
2800
- * args[1 ]. getUnboxed ( ));
2809
+ Fortran::lower::genRandomInit (builder, loc, fir::getBase ( args[0 ]),
2810
+ fir::getBase ( args[1 ]));
2801
2811
}
2802
2812
2803
2813
// RANDOM_NUMBER
2804
2814
void IntrinsicLibrary::genRandomNumber (
2805
2815
llvm::ArrayRef<fir::ExtendedValue> args) {
2806
2816
assert (args.size () == 1 );
2807
- Fortran::lower::genRandomNumber (builder, loc, * args[0 ]. getUnboxed ( ));
2817
+ Fortran::lower::genRandomNumber (builder, loc, fir::getBase ( args[0 ]));
2808
2818
}
2809
2819
2810
2820
// RANDOM_SEED
2811
2821
void IntrinsicLibrary::genRandomSeed (llvm::ArrayRef<fir::ExtendedValue> args) {
2812
2822
assert (args.size () == 3 );
2813
2823
for (int i = 0 ; i < 3 ; ++i)
2814
2824
if (isPresent (args[i])) {
2815
- Fortran::lower::genRandomSeed (builder, loc, i, * args[i]. getUnboxed ( ));
2825
+ Fortran::lower::genRandomSeed (builder, loc, i, fir::getBase ( args[i]));
2816
2826
return ;
2817
2827
}
2818
2828
Fortran::lower::genRandomSeed (builder, loc, -1 , mlir::Value{});
@@ -3014,12 +3024,10 @@ mlir::Value IntrinsicLibrary::genSign(mlir::Type resultType,
3014
3024
fir::ExtendedValue
3015
3025
IntrinsicLibrary::genSize (mlir::Type resultType,
3016
3026
llvm::ArrayRef<fir::ExtendedValue> args) {
3017
- // TODO: handle assumed-rank arrays, especially a dummy whose actual argument
3018
- // is an assumed-size array
3019
3027
assert (args.size () == 3 );
3020
-
3021
- // Calls to SIZE that don't have the DIM argument are handled elsewhere
3022
- assert (! isAbsent (args[ 1 ]) );
3028
+ if ( const auto *boxValue = args[ 0 ]. getBoxOf <fir::BoxValue>())
3029
+ if (boxValue-> hasAssumedRank ())
3030
+ TODO (loc, " SIZE intrinsic with assumed rank argument " );
3023
3031
3024
3032
// Handle the ARRAY argument
3025
3033
mlir::Value array = builder.createBox (loc, args[0 ]);
@@ -3049,6 +3057,54 @@ IntrinsicLibrary::genSize(mlir::Type resultType,
3049
3057
return builder.createConvert (loc, resultType, result);
3050
3058
}
3051
3059
3060
+ // LBOUND
3061
+ fir::ExtendedValue
3062
+ IntrinsicLibrary::genLbound (mlir::Type resultType,
3063
+ llvm::ArrayRef<fir::ExtendedValue> args) {
3064
+ assert (args.size () == 3 );
3065
+ if (const auto *boxValue = args[0 ].getBoxOf <fir::BoxValue>())
3066
+ if (boxValue->hasAssumedRank ())
3067
+ TODO (loc, " LBOUND intrinsic with assumed rank argument" );
3068
+
3069
+ // Calls to LBOUND that don't have the DIM argument, or for which
3070
+ // the DIM is a compile time constant, are folded to descriptor inquiries by
3071
+ // semantics.
3072
+ assert (!isAbsent (args[1 ]));
3073
+ const fir::ExtendedValue &array = args[0 ];
3074
+ llvm::SmallVector<mlir::Value> lbounds =
3075
+ fir::factory::getNonDefaultLowerBounds (builder, loc, array);
3076
+ if (lbounds.empty ())
3077
+ return builder.createIntegerConstant (loc, resultType, 1 );
3078
+ mlir::Type lbArrayType = fir::SequenceType::get (
3079
+ {static_cast <fir::SequenceType::Extent>(array.rank ())}, resultType);
3080
+ auto lbArray = builder.createTemporary (loc, lbArrayType);
3081
+ auto lbAddrType = builder.getRefType (resultType);
3082
+ auto indexType = builder.getIndexType ();
3083
+ for (auto lb : llvm::enumerate (lbounds)) {
3084
+ auto index = builder.createIntegerConstant (loc, indexType, lb.index ());
3085
+ auto lbAddr =
3086
+ builder.create <fir::CoordinateOp>(loc, lbAddrType, lbArray, index);
3087
+ mlir::Value lbValue = builder.createConvert (loc, resultType, lb.value ());
3088
+ builder.create <fir::StoreOp>(loc, lbValue, lbAddr);
3089
+ }
3090
+ mlir::Value resAddr = builder.create <fir::CoordinateOp>(
3091
+ loc, lbAddrType, lbArray, fir::getBase (args[1 ]));
3092
+ return builder.create <fir::LoadOp>(loc, resAddr);
3093
+ }
3094
+
3095
+ // UBOUND
3096
+ fir::ExtendedValue
3097
+ IntrinsicLibrary::genUbound (mlir::Type resultType,
3098
+ llvm::ArrayRef<fir::ExtendedValue> args) {
3099
+ assert (args.size () == 3 );
3100
+ mlir::Value extent = fir::getBase (genSize (resultType, args));
3101
+ mlir::Value lbound = fir::getBase (genLbound (resultType, args));
3102
+
3103
+ mlir::Value one = builder.createIntegerConstant (loc, resultType, 1 );
3104
+ mlir::Value ubound = builder.create <mlir::arith::SubIOp>(loc, lbound, one);
3105
+ return builder.create <mlir::arith::AddIOp>(loc, ubound, extent);
3106
+ }
3107
+
3052
3108
// SPACING
3053
3109
mlir::Value IntrinsicLibrary::genSpacing (mlir::Type resultType,
3054
3110
llvm::ArrayRef<mlir::Value> args) {
@@ -3102,8 +3158,8 @@ IntrinsicLibrary::genSum(mlir::Type resultType,
3102
3158
// SYSTEM_CLOCK
3103
3159
void IntrinsicLibrary::genSystemClock (llvm::ArrayRef<fir::ExtendedValue> args) {
3104
3160
assert (args.size () == 3 );
3105
- Fortran::lower::genSystemClock (builder, loc, * args[0 ]. getUnboxed ( ),
3106
- * args[1 ]. getUnboxed ( ), * args[2 ]. getUnboxed ( ));
3161
+ Fortran::lower::genSystemClock (builder, loc, fir::getBase ( args[0 ]),
3162
+ fir::getBase ( args[1 ]), fir::getBase ( args[2 ]));
3107
3163
}
3108
3164
3109
3165
// TRANSFER
0 commit comments