[flang-commits] [flang] b6fef08 - [flang] Lower F08 merge_bits intrinsic.
Tarun Prabhu via flang-commits
flang-commits at lists.llvm.org
Thu Jul 21 09:42:34 PDT 2022
Author: Tarun Prabhu
Date: 2022-07-21T10:42:25-06:00
New Revision: b6fef088533376e16ca6b47f87c6c50f6f6cd014
URL: https://github.com/llvm/llvm-project/commit/b6fef088533376e16ca6b47f87c6c50f6f6cd014
DIFF: https://github.com/llvm/llvm-project/commit/b6fef088533376e16ca6b47f87c6c50f6f6cd014.diff
LOG: [flang] Lower F08 merge_bits intrinsic.
Lower F08 merge_bits intrinsic.
Differential Revision: https://reviews.llvm.org/D129779
Added:
flang/test/Lower/Intrinsics/merge_bits.f90
Modified:
flang/lib/Lower/IntrinsicCall.cpp
Removed:
################################################################################
diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp
index 6167b28f7870f..7d8aac5f2bf2b 100644
--- a/flang/lib/Lower/IntrinsicCall.cpp
+++ b/flang/lib/Lower/IntrinsicCall.cpp
@@ -516,6 +516,7 @@ struct IntrinsicLibrary {
fir::ExtendedValue genMaxloc(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genMaxval(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genMerge(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
+ mlir::Value genMergeBits(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genMinloc(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genMinval(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genMod(mlir::Type, llvm::ArrayRef<mlir::Value>);
@@ -821,6 +822,7 @@ static constexpr IntrinsicHandler handlers[]{
{"mask", asBox, handleDynamicOptional}}},
/*isElemental=*/false},
{"merge", &I::genMerge},
+ {"merge_bits", &I::genMergeBits},
{"min", &I::genExtremum<Extremum::Min, ExtremumBehavior::MinMaxss>},
{"minloc",
&I::genMinloc,
@@ -3292,6 +3294,24 @@ IntrinsicLibrary::genMerge(mlir::Type,
return rslt;
}
+// MERGE_BITS
+mlir::Value IntrinsicLibrary::genMergeBits(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args) {
+ assert(args.size() == 3);
+
+ mlir::Value i = builder.createConvert(loc, resultType, args[0]);
+ mlir::Value j = builder.createConvert(loc, resultType, args[1]);
+ mlir::Value mask = builder.createConvert(loc, resultType, args[2]);
+ mlir::Value ones = builder.createIntegerConstant(loc, resultType, -1);
+
+ // MERGE_BITS(I, J, MASK) = IOR(IAND(I, MASK), IAND(J, NOT(MASK)))
+ mlir::Value notMask = builder.create<mlir::arith::XOrIOp>(loc, mask, ones);
+ mlir::Value lft = builder.create<mlir::arith::AndIOp>(loc, i, mask);
+ mlir::Value rgt = builder.create<mlir::arith::AndIOp>(loc, j, notMask);
+
+ return builder.create<mlir::arith::OrIOp>(loc, lft, rgt);
+}
+
// MOD
mlir::Value IntrinsicLibrary::genMod(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args) {
diff --git a/flang/test/Lower/Intrinsics/merge_bits.f90 b/flang/test/Lower/Intrinsics/merge_bits.f90
new file mode 100644
index 0000000000000..b5c2745d2b2ff
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/merge_bits.f90
@@ -0,0 +1,110 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+
+! CHECK-LABEL: merge_bits1_test
+! CHECK-SAME: %[[IREF:.*]]: !fir.ref<i8>{{.*}}, %[[JREF:.*]]: !fir.ref<i8>{{.*}}, %[[MREF:.*]]: !fir.ref<i8>{{.*}}, %[[RREF:.*]]: !fir.ref<i8>{{.*}}
+subroutine merge_bits1_test(i, j, m, r)
+ integer(1) :: i, j, m
+ integer(1) :: r
+
+ ! CHECK: %[[I:.*]] = fir.load %[[IREF]] : !fir.ref<i8>
+ ! CHECK: %[[J:.*]] = fir.load %[[JREF]] : !fir.ref<i8>
+ ! CHECK: %[[M:.*]] = fir.load %[[MREF]] : !fir.ref<i8>
+ r = merge_bits(i, j, m)
+ ! CHECK: %[[C__1:.*]] = arith.constant -1 : i8
+ ! CHECK: %[[NM:.*]] = arith.xori %[[M]], %[[C__1]] : i8
+ ! CHECK: %[[LFT:.*]] = arith.andi %[[I]], %[[M]] : i8
+ ! CHECK: %[[RGT:.*]] = arith.andi %[[J]], %[[NM]] : i8
+ ! CHECK: %[[RES:.*]] = arith.ori %[[LFT]], %[[RGT]] : i8
+ ! CHECK: fir.store %[[RES]] to %[[RREF]] : !fir.ref<i8>
+end subroutine merge_bits1_test
+
+! CHECK-LABEL: merge_bits2_test
+! CHECK-SAME: %[[IREF:.*]]: !fir.ref<i16>{{.*}}, %[[JREF:.*]]: !fir.ref<i16>{{.*}}, %[[MREF:.*]]: !fir.ref<i16>{{.*}}, %[[RREF:.*]]: !fir.ref<i16>{{.*}}
+subroutine merge_bits2_test(i, j, m, r)
+ integer(2) :: i, j, m
+ integer(2) :: r
+
+ ! CHECK: %[[I:.*]] = fir.load %[[IREF]] : !fir.ref<i16>
+ ! CHECK: %[[J:.*]] = fir.load %[[JREF]] : !fir.ref<i16>
+ ! CHECK: %[[M:.*]] = fir.load %[[MREF]] : !fir.ref<i16>
+ r = merge_bits(i, j, m)
+ ! CHECK: %[[C__1:.*]] = arith.constant -1 : i16
+ ! CHECK: %[[NM:.*]] = arith.xori %[[M]], %[[C__1]] : i16
+ ! CHECK: %[[LFT:.*]] = arith.andi %[[I]], %[[M]] : i16
+ ! CHECK: %[[RGT:.*]] = arith.andi %[[J]], %[[NM]] : i16
+ ! CHECK: %[[RES:.*]] = arith.ori %[[LFT]], %[[RGT]] : i16
+ ! CHECK: fir.store %[[RES]] to %[[RREF]] : !fir.ref<i16>
+end subroutine merge_bits2_test
+
+! CHECK-LABEL: merge_bits4_test
+! CHECK-SAME: %[[IREF:.*]]: !fir.ref<i32>{{.*}}, %[[JREF:.*]]: !fir.ref<i32>{{.*}}, %[[MREF:.*]]: !fir.ref<i32>{{.*}}, %[[RREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine merge_bits4_test(i, j, m, r)
+ integer(4) :: i, j, m
+ integer(4) :: r
+
+ ! CHECK: %[[I:.*]] = fir.load %[[IREF]] : !fir.ref<i32>
+ ! CHECK: %[[J:.*]] = fir.load %[[JREF]] : !fir.ref<i32>
+ ! CHECK: %[[M:.*]] = fir.load %[[MREF]] : !fir.ref<i32>
+ r = merge_bits(i, j, m)
+ ! CHECK: %[[C__1:.*]] = arith.constant -1 : i32
+ ! CHECK: %[[NM:.*]] = arith.xori %[[M]], %[[C__1]] : i32
+ ! CHECK: %[[LFT:.*]] = arith.andi %[[I]], %[[M]] : i32
+ ! CHECK: %[[RGT:.*]] = arith.andi %[[J]], %[[NM]] : i32
+ ! CHECK: %[[RES:.*]] = arith.ori %[[LFT]], %[[RGT]] : i32
+ ! CHECK: fir.store %[[RES]] to %[[RREF]] : !fir.ref<i32>
+end subroutine merge_bits4_test
+
+! CHECK-LABEL: merge_bits8_test
+! CHECK-SAME: %[[IREF:.*]]: !fir.ref<i64>{{.*}}, %[[JREF:.*]]: !fir.ref<i64>{{.*}}, %[[MREF:.*]]: !fir.ref<i64>{{.*}}, %[[RREF:.*]]: !fir.ref<i64>{{.*}}
+subroutine merge_bits8_test(i, j, m, r)
+ integer(8) :: i, j, m
+ integer(8) :: r
+
+ ! CHECK: %[[I:.*]] = fir.load %[[IREF]] : !fir.ref<i64>
+ ! CHECK: %[[J:.*]] = fir.load %[[JREF]] : !fir.ref<i64>
+ ! CHECK: %[[M:.*]] = fir.load %[[MREF]] : !fir.ref<i64>
+ r = merge_bits(i, j, m)
+ ! CHECK: %[[C__1:.*]] = arith.constant -1 : i64
+ ! CHECK: %[[NM:.*]] = arith.xori %[[M]], %[[C__1]] : i64
+ ! CHECK: %[[LFT:.*]] = arith.andi %[[I]], %[[M]] : i64
+ ! CHECK: %[[RGT:.*]] = arith.andi %[[J]], %[[NM]] : i64
+ ! CHECK: %[[RES:.*]] = arith.ori %[[LFT]], %[[RGT]] : i64
+ ! CHECK: fir.store %[[RES]] to %[[RREF]] : !fir.ref<i64>
+end subroutine merge_bits8_test
+
+! CHECK-LABEL: merge_bitsz0_test
+! CHECK-SAME: %[[JREF:.*]]: !fir.ref<i32>{{.*}}, %[[MREF:.*]]: !fir.ref<i32>{{.*}}, %[[RREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine merge_bitsz0_test(j, m, r)
+ integer :: j, m
+ integer :: r
+
+ ! CHECK: %[[I:.*]] = arith.constant 13 : i32
+ ! CHECK: %[[J:.*]] = fir.load %[[JREF]] : !fir.ref<i32>
+ ! CHECK: %[[M:.*]] = fir.load %[[MREF]] : !fir.ref<i32>
+ r = merge_bits(B'1101', j, m)
+ ! CHECK: %[[C__1:.*]] = arith.constant -1 : i32
+ ! CHECK: %[[NM:.*]] = arith.xori %[[M]], %[[C__1]] : i32
+ ! CHECK: %[[LFT:.*]] = arith.andi %[[I]], %[[M]] : i32
+ ! CHECK: %[[RGT:.*]] = arith.andi %[[J]], %[[NM]] : i32
+ ! CHECK: %[[RES:.*]] = arith.ori %[[LFT]], %[[RGT]] : i32
+ ! CHECK: fir.store %[[RES]] to %[[RREF]] : !fir.ref<i32>
+end subroutine merge_bitsz0_test
+
+! CHECK-LABEL: merge_bitsz1_test
+! CHECK-SAME: %[[IREF:.*]]: !fir.ref<i32>{{.*}}, %[[MREF:.*]]: !fir.ref<i32>{{.*}}, %[[RREF:.*]]: !fir.ref<i32>{{.*}}
+subroutine merge_bitsz1_test(i, m, r)
+ integer :: i, m
+ integer :: r
+
+ ! CHECK: %[[I:.*]] = fir.load %[[IREF]] : !fir.ref<i32>
+ ! CHECK: %[[J:.*]] = arith.constant 13 : i32
+ ! CHECK: %[[M:.*]] = fir.load %[[MREF]] : !fir.ref<i32>
+ r = merge_bits(i, Z'0D', m)
+ ! CHECK: %[[C__1:.*]] = arith.constant -1 : i32
+ ! CHECK: %[[NM:.*]] = arith.xori %[[M]], %[[C__1]] : i32
+ ! CHECK: %[[LFT:.*]] = arith.andi %[[I]], %[[M]] : i32
+ ! CHECK: %[[RGT:.*]] = arith.andi %[[J]], %[[NM]] : i32
+ ! CHECK: %[[RES:.*]] = arith.ori %[[LFT]], %[[RGT]] : i32
+ ! CHECK: fir.store %[[RES]] to %[[RREF]] : !fir.ref<i32>
+end subroutine merge_bitsz1_test
More information about the flang-commits
mailing list