diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp index 3a5a6148bc288..d884f9b16e344 100644 --- a/flang/lib/Lower/IntrinsicCall.cpp +++ b/flang/lib/Lower/IntrinsicCall.cpp @@ -449,6 +449,7 @@ struct IntrinsicLibrary { /// in the llvm::ArrayRef. mlir::Value genIand(mlir::Type, llvm::ArrayRef); mlir::Value genIbits(mlir::Type, llvm::ArrayRef); + mlir::Value genIbset(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genLbound(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genNull(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genLen(mlir::Type, llvm::ArrayRef); @@ -595,6 +596,7 @@ static constexpr IntrinsicHandler handlers[]{ /*isElemental=*/false}, {"iand", &I::genIand}, {"ibits", &I::genIbits}, + {"ibset", &I::genIbset}, {"len", &I::genLen, {{{"string", asInquired}, {"kind", asValue}}}, @@ -1682,6 +1684,20 @@ mlir::Value IntrinsicLibrary::genIbits(mlir::Type resultType, return builder.create(loc, lenIsZero, zero, res2); } +// IBSET +mlir::Value IntrinsicLibrary::genIbset(mlir::Type resultType, + llvm::ArrayRef args) { + // A conformant IBSET(I,POS) call satisfies: + // POS >= 0 + // POS < BIT_SIZE(I) + // Return: I | (1 << POS) + assert(args.size() == 2); + mlir::Value pos = builder.createConvert(loc, resultType, args[1]); + mlir::Value one = builder.createIntegerConstant(loc, resultType, 1); + auto mask = builder.create(loc, one, pos); + return builder.create(loc, args[0], mask); +} + // LEN // Note that this is only used for an unrestricted intrinsic LEN call. // Other uses of LEN are rewritten as descriptor inquiries by the front-end. diff --git a/flang/test/Lower/Intrinsics/ibset.f90 b/flang/test/Lower/Intrinsics/ibset.f90 new file mode 100644 index 0000000000000..7dcaf9f475ea0 --- /dev/null +++ b/flang/test/Lower/Intrinsics/ibset.f90 @@ -0,0 +1,17 @@ +! RUN: bbc -emit-fir %s -o - | FileCheck %s +! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s + +! CHECK-LABEL: ibset_test +function ibset_test(i, j) + ! CHECK-DAG: %[[result:.*]] = fir.alloca i32 {bindc_name = "ibset_test" + ! CHECK-DAG: %[[i:.*]] = fir.load %arg0 : !fir.ref + ! CHECK-DAG: %[[j:.*]] = fir.load %arg1 : !fir.ref + ! CHECK-DAG: %[[VAL_5:.*]] = arith.constant 1 : i32 + ! CHECK: %[[VAL_6:.*]] = arith.shli %[[VAL_5]], %[[j]] : i32 + ! CHECK: %[[VAL_7:.*]] = arith.ori %[[i]], %[[VAL_6]] : i32 + ! CHECK: fir.store %[[VAL_7]] to %[[result]] : !fir.ref + ! CHECK: %[[VAL_8:.*]] = fir.load %[[result]] : !fir.ref + ! CHECK: return %[[VAL_8]] : i32 + ibset_test = ibset(i, j) +end +