[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