[flang-commits] [flang] 6c3d7fd - [flang][CodeGen] Transform `fir.boxchar_len` to a sequence of LLVM MLIR

Andrzej Warzynski via flang-commits flang-commits at lists.llvm.org
Tue Nov 16 05:49:31 PST 2021


Author: Andrzej Warzynski
Date: 2021-11-16T13:49:23Z
New Revision: 6c3d7fd4c55cfacbf9536373857eb496b3cfedcf

URL: https://github.com/llvm/llvm-project/commit/6c3d7fd4c55cfacbf9536373857eb496b3cfedcf
DIFF: https://github.com/llvm/llvm-project/commit/6c3d7fd4c55cfacbf9536373857eb496b3cfedcf.diff

LOG: [flang][CodeGen] Transform `fir.boxchar_len` to a sequence of LLVM MLIR

This patch extends the `FIRToLLVMLowering` pass in Flang by adding a
hook to transform `fir.boxchar_len` to a sequence of LLVM MLIR
instructions.

This is part of the upstreaming effort from the `fir-dev` branch in [1].

[1] https://github.com/flang-compiler/f18-llvm-project

Differential Revision: https://reviews.llvm.org/D113763

Originally written by:
Co-authored-by: Eric Schweitz <eschweitz at nvidia.com>

Added: 
    

Modified: 
    flang/lib/Optimizer/CodeGen/CodeGen.cpp
    flang/test/Fir/convert-to-llvm-target.fir

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 8cf335294718..c7b0a81b4efe 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -1517,6 +1517,29 @@ genExtractValueWithIndex(mlir::Location loc, mlir::Value tuple, mlir::Type ty,
   return rewriter.create<mlir::LLVM::ExtractValueOp>(loc, xty, tuple, cx);
 }
 
+/// Convert `!fir.boxchar_len` to  `!llvm.extractvalue` for the 2nd part of the
+/// boxchar.
+struct BoxCharLenOpConversion : public FIROpConversion<fir::BoxCharLenOp> {
+  using FIROpConversion::FIROpConversion;
+
+  mlir::LogicalResult
+  matchAndRewrite(fir::BoxCharLenOp boxCharLen, OpAdaptor adaptor,
+                  mlir::ConversionPatternRewriter &rewriter) const override {
+    mlir::Value boxChar = adaptor.getOperands()[0];
+    mlir::Location loc = boxChar.getLoc();
+    mlir::MLIRContext *ctx = boxChar.getContext();
+    mlir::Type returnValTy = boxCharLen.getResult().getType();
+
+    constexpr int boxcharLenIdx = 1;
+    mlir::LLVM::ExtractValueOp len = genExtractValueWithIndex(
+        loc, boxChar, boxChar.getType(), rewriter, ctx, boxcharLenIdx);
+    mlir::Value lenAfterCast = integerCast(loc, rewriter, returnValTy, len);
+    rewriter.replaceOp(boxCharLen, lenAfterCast);
+
+    return success();
+  }
+};
+
 /// Convert `fir.unboxchar` into two `llvm.extractvalue` instructions. One for
 /// the character buffer and one for the buffer length.
 struct UnboxCharOpConversion : public FIROpConversion<fir::UnboxCharOp> {
@@ -1569,7 +1592,7 @@ class FIRToLLVMLowering : public fir::FIRToLLVMLoweringBase<FIRToLLVMLowering> {
     mlir::OwningRewritePatternList pattern(context);
     pattern.insert<
         AbsentOpConversion, AddcOpConversion, AddrOfOpConversion,
-        AllocaOpConversion, BoxAddrOpConversion, BoxDimsOpConversion,
+        AllocaOpConversion, BoxAddrOpConversion, BoxCharLenOpConversion, BoxDimsOpConversion,
         BoxEleSizeOpConversion, BoxIsAllocOpConversion, BoxIsArrayOpConversion,
         BoxIsPtrOpConversion, BoxRankOpConversion, CallOpConversion,
         CmpcOpConversion, ConvertOpConversion, DispatchOpConversion,

diff  --git a/flang/test/Fir/convert-to-llvm-target.fir b/flang/test/Fir/convert-to-llvm-target.fir
index 501e68741a8e..7f79dbd25513 100644
--- a/flang/test/Fir/convert-to-llvm-target.fir
+++ b/flang/test/Fir/convert-to-llvm-target.fir
@@ -71,3 +71,79 @@ func @unboxchar_i32(%arg0 : !fir.boxchar<4>) -> () {
 // INT32:  %[[len_unextended:.*]] = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i32>, i32)>
 // INT32:  %{{.*}} = llvm.sext %[[len_unextended]] : i32 to i64
 // INT32-NEXT:  llvm.return
+
+// -----
+
+// Test fir.boxchar_len
+
+func @boxchar_len_i8_i32(%arg0 : !fir.boxchar<1>) -> () {
+  fir.boxchar_len %arg0 : (!fir.boxchar<1>) -> i32
+  return
+}
+
+// INT64-LABEL: llvm.func @boxchar_len_i8_i32
+// INT64-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i8>, i64)>
+// INT64:  %[[len:.*]] = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i8>, i64)>
+// INT64: %{{.*}} = llvm.trunc %[[len]] : i64 to i32
+// INT64-NEXT:  llvm.return
+
+// INT32-LABEL: llvm.func @boxchar_len_i8_i32
+// INT32-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i8>, i32)>
+// INT32:  %{{.*}} = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i8>, i32)>
+// INT32-NOT:  llvm.trunc
+// INT32-NOT:  llvm.sext
+// INT32-NEXT:  llvm.return
+
+func @boxchar_len_i8_i64(%arg0 : !fir.boxchar<1>) -> () {
+  fir.boxchar_len %arg0 : (!fir.boxchar<1>) -> i64
+  return
+}
+
+// INT64-LABEL: llvm.func @boxchar_len_i8_i64
+// INT64-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i8>, i64)>
+// INT64:  %{{.*}} = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i8>, i64)>
+// INT64-NOT:  llvm.trunc
+// INT64-NOT:  llvm.sext
+// INT64-NEXT:  llvm.return
+
+// INT32-LABEL: llvm.func @boxchar_len_i8_i64
+// INT32-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i8>, i32)>
+// INT32:  %[[len:.*]] = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i8>, i32)>
+// INT32:  %{{.*}} = llvm.sext %0 : i32 to i64
+// INT32-NEXT:  llvm.return
+
+func @boxchar_len_i32_i32(%arg0 : !fir.boxchar<4>) -> () {
+  fir.boxchar_len %arg0 : (!fir.boxchar<4>) -> i32
+  return
+}
+
+// INT64-LABEL: llvm.func @boxchar_len_i32_i32
+// INT64-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i32>, i64)>
+// INT64:  %[[len:.*]] = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i32>, i64)>
+// INT64: %{{.*}} = llvm.trunc %[[len]] : i64 to i32
+// INT64-NEXT:  llvm.return
+
+// INT32-LABEL: llvm.func @boxchar_len_i32_i32
+// INT32-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i32>, i32)>
+// INT32:  %{{.*}} = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i32>, i32)>
+// INT32-NOT:  llvm.trunc
+// INT32-NOT:  llvm.sext
+// INT32-NEXT:  llvm.return
+
+func @boxchar_len_i32_i64(%arg0 : !fir.boxchar<4>) -> (i64) {
+  %0 = fir.boxchar_len %arg0 : (!fir.boxchar<4>) -> i64
+  return %0 : i64
+}
+
+// INT64-LABEL: llvm.func @boxchar_len_i32_i64
+// INT64-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i32>, i64)>
+// INT64:  %{{.*}} = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i32>, i64)>
+// INT64-NOT:  llvm.trunc
+// INT64-NOT:  llvm.sext
+// INT64-NEXT:  llvm.return
+
+// INT32-LABEL: llvm.func @boxchar_len_i32_i64
+// INT32-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i32>, i32)>
+// INT32:  %[[len:.*]] = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i32>, i32)>
+// INT32:  %{{.*}} = llvm.sext %0 : i32 to i64
+// INT32-NEXT:  llvm.return


        


More information about the flang-commits mailing list