[flang-commits] [flang] 1e77b09 - [flang][CodeGen] Transform `fir.emboxchar` to a sequence of LLVM MLIR

Andrzej Warzynski via flang-commits flang-commits at lists.llvm.org
Mon Nov 15 03:12:00 PST 2021


Author: Andrzej Warzynski
Date: 2021-11-15T11:09:12Z
New Revision: 1e77b09538c1bcba4936fee2e3f1a54de2467157

URL: https://github.com/llvm/llvm-project/commit/1e77b09538c1bcba4936fee2e3f1a54de2467157
DIFF: https://github.com/llvm/llvm-project/commit/1e77b09538c1bcba4936fee2e3f1a54de2467157.diff

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

This patch extends the `FIRToLLVMLowering` pass in Flang by adding a
hook to transform `fir.emboxchar` 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/D113666

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

Added: 
    flang/test/Fir/convert-to-llvm-target.fir

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

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 65f044ce58e6..fdf8449a64d9 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -1388,6 +1388,41 @@ struct IsPresentOpConversion : public FIROpConversion<fir::IsPresentOp> {
     return success();
   }
 };
+
+/// Convert `!fir.emboxchar<!fir.char<KIND, ?>, #n>` into a sequence of
+/// instructions that generate `!llvm.struct<(ptr<ik>, i64)>`. The 1st element
+/// in this struct is a pointer. Its type is determined from `KIND`. The 2nd
+/// element is the length of the character buffer (`#n`).
+struct EmboxCharOpConversion : public FIROpConversion<fir::EmboxCharOp> {
+  using FIROpConversion::FIROpConversion;
+
+  mlir::LogicalResult
+  matchAndRewrite(fir::EmboxCharOp emboxChar, OpAdaptor adaptor,
+                  mlir::ConversionPatternRewriter &rewriter) const override {
+    mlir::ValueRange operands = adaptor.getOperands();
+    MLIRContext *ctx = emboxChar.getContext();
+
+    mlir::Value charBuffer = operands[0];
+    mlir::Value charBufferLen = operands[1];
+
+    mlir::Location loc = emboxChar.getLoc();
+    mlir::Type llvmStructTy = convertType(emboxChar.getType());
+    auto llvmStruct = rewriter.create<mlir::LLVM::UndefOp>(loc, llvmStructTy);
+
+    mlir::Type lenTy =
+        llvmStructTy.cast<mlir::LLVM::LLVMStructType>().getBody()[1];
+    mlir::Value lenAfterCast = integerCast(loc, rewriter, lenTy, charBufferLen);
+
+    auto c0 = mlir::ArrayAttr::get(ctx, rewriter.getI32IntegerAttr(0));
+    auto c1 = mlir::ArrayAttr::get(ctx, rewriter.getI32IntegerAttr(1));
+    auto insertBufferOp = rewriter.create<mlir::LLVM::InsertValueOp>(
+        loc, llvmStructTy, llvmStruct, charBuffer, c0);
+    rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(
+        emboxChar, llvmStructTy, insertBufferOp, lenAfterCast, c1);
+
+    return success();
+  }
+};
 } // namespace
 
 namespace {
@@ -1416,13 +1451,14 @@ class FIRToLLVMLowering : public fir::FIRToLLVMLoweringBase<FIRToLLVMLowering> {
         BoxEleSizeOpConversion, BoxIsAllocOpConversion, BoxIsArrayOpConversion,
         BoxIsPtrOpConversion, BoxRankOpConversion, CallOpConversion,
         ConvertOpConversion, DispatchOpConversion, DispatchTableOpConversion,
-        DTEntryOpConversion, DivcOpConversion, ExtractValueOpConversion,
-        HasValueOpConversion, GlobalOpConversion, InsertOnRangeOpConversion,
-        InsertValueOpConversion, IsPresentOpConversion, LoadOpConversion,
-        NegcOpConversion, MulcOpConversion, SelectCaseOpConversion,
-        SelectOpConversion, SelectRankOpConversion, StoreOpConversion,
-        SubcOpConversion, UndefOpConversion, UnreachableOpConversion,
-        ZeroOpConversion>(typeConverter);
+        DTEntryOpConversion, DivcOpConversion, EmboxCharOpConversion,
+        ExtractValueOpConversion, HasValueOpConversion, GlobalOpConversion,
+        InsertOnRangeOpConversion, InsertValueOpConversion,
+        IsPresentOpConversion, LoadOpConversion, NegcOpConversion,
+        MulcOpConversion, SelectCaseOpConversion, SelectOpConversion,
+        SelectRankOpConversion, StoreOpConversion, SubcOpConversion,
+        UndefOpConversion, UnreachableOpConversion, ZeroOpConversion>(
+        typeConverter);
     mlir::populateStdToLLVMConversionPatterns(typeConverter, pattern);
     mlir::arith::populateArithmeticToLLVMConversionPatterns(typeConverter,
                                                             pattern);

diff  --git a/flang/test/Fir/convert-to-llvm-target.fir b/flang/test/Fir/convert-to-llvm-target.fir
new file mode 100644
index 000000000000..46e693ca52e3
--- /dev/null
+++ b/flang/test/Fir/convert-to-llvm-target.fir
@@ -0,0 +1,33 @@
+// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" %s | FileCheck %s --check-prefix INT64
+// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=aarch64-unknown-linux-gnu" %s | FileCheck %s --check-prefixes INT64
+// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=i386-unknown-linux-gnu" %s | FileCheck %s --check-prefixes INT32
+// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=powerpc64le-unknown-linux-gn" %s | FileCheck %s --check-prefixes INT64
+
+//=============================================================================
+// SUMMARY: Tests for FIR --> LLVM MLIR conversion that *depend* on the target
+//=============================================================================
+
+// Test fir.emboxchar
+
+func @test_embox(%char_array : !fir.ref<!fir.char<1,?>>) -> () {
+  %c10 = arith.constant 10 : i64
+  %box_char = fir.emboxchar %char_array, %c10 : (!fir.ref<!fir.char<1,?>>, i64) -> !fir.boxchar<1>
+  return
+}
+
+// INT64-LABEL: test_embox
+// INT64-SAME: (%[[char_array:.*]]: !llvm.ptr<i8>)
+// INT64:    %[[c10:.*]] = llvm.mlir.constant(10 : i64) : i64
+// INT64:    %[[empty_struct:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<i8>, i{{.*}})>
+// INT64:    %[[struct_with_buffer:.*]] = llvm.insertvalue %[[char_array]], %[[empty_struct]][0 : i32] : !llvm.struct<(ptr<i8>, i{{.*}})>
+// INT64:    %{{.*}} = llvm.insertvalue %[[c10]], %[[struct_with_buffer]][1 : i32] : !llvm.struct<(ptr<i8>, i{{.*}})>
+// INT64-NEXT:    llvm.return
+
+// INT32-LABEL:  llvm.func @test_embox
+// INT32-SAME: %[[char_array:.*]]: !llvm.ptr<i8>)
+// INT32:    %[[c10:.*]] = llvm.mlir.constant(10 : i64) : i64
+// INT32:    %[[empty_struct:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<i8>, i32)>
+// INT32:    %[[c10_truncated:.*]] = llvm.trunc %[[c10]] : i64 to i32
+// INT32:    %[[struct_with_buffer:.*]] = llvm.insertvalue %[[char_array]], %[[empty_struct]][0 : i32] : !llvm.struct<(ptr<i8>, i32)>
+// INT32:    %{{.*}} = llvm.insertvalue %[[c10_truncated:.*]], %[[struct_with_buffer]][1 : i32] : !llvm.struct<(ptr<i8>, i32)>
+// INT32-NEXT:    llvm.return

diff  --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index 743a9facc7ec..a804825eb75f 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -3,6 +3,9 @@
 // RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=i386-unknown-linux-gnu" %s | FileCheck %s
 // RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=powerpc64le-unknown-linux-gn" %s | FileCheck %s
 
+//=============================================================================
+// SUMMARY: Tests for FIR --> LLVM MLIR conversion independent of the target
+//=============================================================================
 
 // Test simple global LLVM conversion
 


        


More information about the flang-commits mailing list