diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp --- a/flang/lib/Lower/IntrinsicCall.cpp +++ b/flang/lib/Lower/IntrinsicCall.cpp @@ -276,6 +276,7 @@ /// 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 genSize(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genSum(mlir::Type, llvm::ArrayRef); @@ -389,6 +390,7 @@ /*isElemental=*/false}, {"iand", &I::genIand}, {"ibits", &I::genIbits}, + {"ibset", &I::genIbset}, {"min", &I::genExtremum}, {"sum", &I::genSum, @@ -1324,6 +1326,20 @@ 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); +} + // Compare two FIR values and return boolean result as i1. template static mlir::Value createExtremumCompare(mlir::Location loc, diff --git a/flang/test/Lower/Intrinsics/ibset.f90 b/flang/test/Lower/Intrinsics/ibset.f90 new file mode 100644 --- /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 +