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

Andrzej Warzynski via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 11 05:37:42 PST 2021


awarzynski created this revision.
awarzynski added a reviewer: clementval.
Herald added subscribers: Chia-hungDuan, mehdi_amini, rriddle.
Herald added a project: Flang.
awarzynski requested review of this revision.
Herald added subscribers: llvm-commits, stephenneuendorffer, jdoerfert.
Herald added a project: LLVM.

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

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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D113666

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


Index: flang/test/Fir/convert-to-llvm.fir
===================================================================
--- flang/test/Fir/convert-to-llvm.fir
+++ flang/test/Fir/convert-to-llvm.fir
@@ -961,3 +961,21 @@
 // CHECK: [[PROD3:%.*]] = llvm.mul [[PROD2]], [[B]] : i64
 // CHECK: [[RES:%.*]] = llvm.alloca [[PROD3]] x i32 {in_type = !fir.array<4x?x3x?x5xi32>
 // CHECK: llvm.return [[RES]] : !llvm.ptr<i32>
+
+// -----
+
+// 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
+}
+
+// CHECK-LABEL: test_embox
+// CHECK-SAME: (%[[char_array:.*]]: !llvm.ptr<i8>)
+// CHECK:    %[[c10:.*]] = llvm.mlir.constant(10 : i64) : i64
+// CHECK:    %[[empty_struct:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<i8>, i{{.*}})>
+// CHECK:    %[[struct_with_buffer:.*]] = llvm.insertvalue %[[char_array]], %[[empty_struct]][0 : i32] : !llvm.struct<(ptr<i8>, i{{.*}})>
+// CHECK:    %{{.*}} = llvm.insertvalue %[[c10]], %[[struct_with_buffer]][1 : i32] : !llvm.struct<(ptr<i8>, i{{.*}})>
+// CHECK-NEXT:    llvm.return
Index: flang/lib/Optimizer/CodeGen/CodeGen.cpp
===================================================================
--- flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -1162,6 +1162,37 @@
   }
 };
 
+/// Convert `!fir.emboxchar<!fir.char<KIND, ?>, #n>` into a sequence of
+/// instructions that generates `!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 {
+    auto operands = adaptor.getOperands();
+
+    mlir::Value char_buffer = operands[0];
+    mlir::Value char_buffer_len = operands[1];
+    mlir::Location loc = emboxChar.getLoc();
+    MLIRContext *ctx = emboxChar.getContext();
+    auto ty = convertType(emboxChar.getType());
+
+    auto c0 = mlir::ArrayAttr::get(ctx, rewriter.getI32IntegerAttr(0));
+    auto c1 = mlir::ArrayAttr::get(ctx, rewriter.getI32IntegerAttr(1));
+    auto un = rewriter.create<mlir::LLVM::UndefOp>(loc, ty);
+    auto lenTy = ty.cast<mlir::LLVM::LLVMStructType>().getBody()[1];
+    auto b = integerCast(loc, rewriter, lenTy, char_buffer_len);
+    auto r = rewriter.create<mlir::LLVM::InsertValueOp>(loc, ty, un,
+                                                        char_buffer, c0);
+    rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(emboxChar, ty, r, b,
+                                                           c1);
+    return success();
+  }
+};
+
 } // namespace
 
 namespace {
@@ -1189,12 +1220,12 @@
         BoxAddrOpConversion, BoxDimsOpConversion, BoxEleSizeOpConversion,
         BoxIsAllocOpConversion, BoxIsArrayOpConversion, BoxIsPtrOpConversion,
         BoxRankOpConversion, CallOpConversion, ConvertOpConversion,
-        DivcOpConversion, ExtractValueOpConversion, HasValueOpConversion,
-        GlobalOpConversion, InsertOnRangeOpConversion, InsertValueOpConversion,
-        LoadOpConversion, NegcOpConversion, MulcOpConversion,
-        SelectOpConversion, SelectRankOpConversion, StoreOpConversion,
-        SubcOpConversion, UndefOpConversion, UnreachableOpConversion,
-        ZeroOpConversion>(typeConverter);
+        DivcOpConversion, EmboxCharOpConversion, ExtractValueOpConversion,
+        HasValueOpConversion, GlobalOpConversion, InsertOnRangeOpConversion,
+        InsertValueOpConversion, LoadOpConversion, NegcOpConversion,
+        MulcOpConversion, SelectOpConversion, SelectRankOpConversion,
+        StoreOpConversion, SubcOpConversion, UndefOpConversion,
+        UnreachableOpConversion, ZeroOpConversion>(typeConverter);
     mlir::populateStdToLLVMConversionPatterns(typeConverter, pattern);
     mlir::arith::populateArithmeticToLLVMConversionPatterns(typeConverter,
                                                             pattern);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D113666.386484.patch
Type: text/x-patch
Size: 4278 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211111/d6a857e9/attachment.bin>


More information about the llvm-commits mailing list