@@ -4138,17 +4138,46 @@ IntrinsicLibrary::genCharacterCompare(mlir::Type resultType,
4138
4138
fir::getBase (args[1 ]), fir::getLen (args[1 ]));
4139
4139
}
4140
4140
4141
+ static bool isOptional (mlir::Value value) {
4142
+ auto varIface = mlir::dyn_cast_or_null<fir::FortranVariableOpInterface>(
4143
+ value.getDefiningOp ());
4144
+ return varIface && varIface.isOptional ();
4145
+ }
4146
+
4141
4147
// LOC
4142
4148
fir::ExtendedValue
4143
4149
IntrinsicLibrary::genLoc (mlir::Type resultType,
4144
4150
llvm::ArrayRef<fir::ExtendedValue> args) {
4145
4151
assert (args.size () == 1 );
4146
- mlir::Value argValue = fir::getBase (args[0 ]);
4147
- assert (fir::isa_box_type (argValue .getType ()) &&
4152
+ mlir::Value box = fir::getBase (args[0 ]);
4153
+ assert (fir::isa_box_type (box .getType ()) &&
4148
4154
" argument must have been lowered to box type" );
4149
- bool isFunc = argValue.getType ().isa <fir::BoxProcType>();
4150
- mlir::Value argAddr = getAddrFromBox (builder, loc, args[0 ], isFunc);
4151
- return builder.createConvert (loc, fir::unwrapRefType (resultType), argAddr);
4155
+ bool isFunc = box.getType ().isa <fir::BoxProcType>();
4156
+ if (!isOptional (box)) {
4157
+ mlir::Value argAddr = getAddrFromBox (builder, loc, args[0 ], isFunc);
4158
+ return builder.createConvert (loc, resultType, argAddr);
4159
+ }
4160
+ // Optional assumed shape case. Although this is not specified in this GNU
4161
+ // intrinsic extension, LOC accepts absent optional and returns zero in that
4162
+ // case.
4163
+ // Note that the other OPTIONAL cases do not fall here since `box` was
4164
+ // created when preparing the argument cases, but the box can be safely be
4165
+ // used for all those cases and the address will be null if absent.
4166
+ mlir::Value isPresent =
4167
+ builder.create <fir::IsPresentOp>(loc, builder.getI1Type (), box);
4168
+ return builder
4169
+ .genIfOp (loc, {resultType}, isPresent,
4170
+ /* withElseRegion=*/ true )
4171
+ .genThen ([&]() {
4172
+ mlir::Value argAddr = getAddrFromBox (builder, loc, args[0 ], isFunc);
4173
+ mlir::Value cast = builder.createConvert (loc, resultType, argAddr);
4174
+ builder.create <fir::ResultOp>(loc, cast);
4175
+ })
4176
+ .genElse ([&]() {
4177
+ mlir::Value zero = builder.createIntegerConstant (loc, resultType, 0 );
4178
+ builder.create <fir::ResultOp>(loc, zero);
4179
+ })
4180
+ .getResults ()[0 ];
4152
4181
}
4153
4182
4154
4183
// MASKL, MASKR
0 commit comments