diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp index b6a8dddb08e9f..44d59fbe29c69 100644 --- a/flang/lib/Lower/IntrinsicCall.cpp +++ b/flang/lib/Lower/IntrinsicCall.cpp @@ -457,6 +457,7 @@ struct IntrinsicLibrary { /// Lowering for the IAND intrinsic. The IAND intrinsic expects two arguments /// in the llvm::ArrayRef. mlir::Value genIand(mlir::Type, llvm::ArrayRef); + mlir::Value genIbclr(mlir::Type, llvm::ArrayRef); mlir::Value genIbits(mlir::Type, llvm::ArrayRef); mlir::Value genIbset(mlir::Type, llvm::ArrayRef); mlir::Value genIeor(mlir::Type, llvm::ArrayRef); @@ -634,6 +635,7 @@ static constexpr IntrinsicHandler handlers[]{ {"dim", asValue}}}, /*isElemental=*/false}, {"iand", &I::genIand}, + {"ibclr", &I::genIbclr}, {"ibits", &I::genIbits}, {"ibset", &I::genIbset}, {"ieor", &I::genIeor}, @@ -1891,6 +1893,22 @@ mlir::Value IntrinsicLibrary::genIand(mlir::Type resultType, return builder.create(loc, args[0], args[1]); } +// IBCLR +mlir::Value IntrinsicLibrary::genIbclr(mlir::Type resultType, + llvm::ArrayRef args) { + // A conformant IBCLR(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); + mlir::Value ones = builder.createIntegerConstant(loc, resultType, -1); + auto mask = builder.create(loc, one, pos); + auto res = builder.create(loc, ones, mask); + return builder.create(loc, args[0], res); +} + // IBITS mlir::Value IntrinsicLibrary::genIbits(mlir::Type resultType, llvm::ArrayRef args) { diff --git a/flang/test/Lower/Intrinsics/ibclr.f90 b/flang/test/Lower/Intrinsics/ibclr.f90 new file mode 100644 index 0000000000000..ec30b251a867b --- /dev/null +++ b/flang/test/Lower/Intrinsics/ibclr.f90 @@ -0,0 +1,19 @@ +! RUN: bbc -emit-fir %s -o - | FileCheck %s +! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s + +! CHECK-LABEL: ibclr_test +function ibclr_test(i, j) + ! CHECK-DAG: %[[result:.*]] = fir.alloca i32 {bindc_name = "ibclr_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-DAG: %[[VAL_6:.*]] = arith.constant -1 : i32 + ! CHECK: %[[VAL_7:.*]] = arith.shli %[[VAL_5]], %[[j]] : i32 + ! CHECK: %[[VAL_8:.*]] = arith.xori %[[VAL_6]], %[[VAL_7]] : i32 + ! CHECK: %[[VAL_9:.*]] = arith.andi %[[i]], %[[VAL_8]] : i32 + ! CHECK: fir.store %[[VAL_9]] to %[[result]] : !fir.ref + ! CHECK: %[[VAL_10:.*]] = fir.load %[[result]] : !fir.ref + ! CHECK: return %[[VAL_10]] : i32 + ibclr_test = ibclr(i, j) +end +