[flang-commits] [flang] 0840725 - [Flang] Temporary fix for conversion materialization

Kiran Chandramohan via flang-commits flang-commits at lists.llvm.org
Thu Jun 9 03:13:09 PDT 2022


Author: Kiran Chandramohan
Date: 2022-06-09T10:10:56Z
New Revision: 08407255b2d29968f050e5c2ac81fe85f66ea34f

URL: https://github.com/llvm/llvm-project/commit/08407255b2d29968f050e5c2ac81fe85f66ea34f
DIFF: https://github.com/llvm/llvm-project/commit/08407255b2d29968f050e5c2ac81fe85f66ea34f.diff

LOG: [Flang] Temporary fix for conversion materialization

Simply add a source and target materialization handler that do nothing
and that override the default handlers that would add illegal
LLVM::DialectCastOp otherwise.

This is the simplest workaround, but not an actual fix, something may be
inconsistent after D82831 (most likely fir lowering to llvm happens in a
way that mlir infrastructure is not expecting in D82831).

Here is a minimal reproducer of what the issue was:
```
func @foop(%a : !fir.real<4>) -> ()
func @bar(%a : !fir.real<2>) {
  %1 = fir.convert %a : (!fir.real<2>) -> !fir.real<4>
  call @foop(%1) : (!fir.real<4>) -> ()
  return
}
```
tco -o - output was:
```
error: 'llvm.mlir.cast' op type must be non-index integer types, float types, or vector of mentioned types.
llvm.func @foop(!llvm.float)
llvm.func @bar(%arg0: !llvm.half) {
  %0 = llvm.fpext %arg0 : !llvm.half to !llvm.float
  %1 = llvm.mlir.cast %0 : !llvm.float to !fir.real<4>
  llvm.call @foop(%1) : (!fir.real<4>) -> ()
  llvm.return
}
```
This patch disable the introduction of the llvm.mlir.cast and preserve the previous behavior.

Also fixes https://github.com/llvm/llvm-project/issues/55210.

Note: This is part of upstreaming from the fir-dev branch of
https://github.com/flang-compiler/f18-llvm-project.

Reviewed By: awarzynski

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

Co-authored-by: Jean Perier <jperier at nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz at nvidia.com>

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/CodeGen/TypeConverter.h b/flang/lib/Optimizer/CodeGen/TypeConverter.h
index aefe5923c1396..937f7036a9d84 100644
--- a/flang/lib/Optimizer/CodeGen/TypeConverter.h
+++ b/flang/lib/Optimizer/CodeGen/TypeConverter.h
@@ -128,6 +128,29 @@ class LLVMTypeConverter : public mlir::LLVMTypeConverter {
       return mlir::LLVM::LLVMStructType::getLiteral(
           none.getContext(), llvm::None, /*isPacked=*/false);
     });
+    // FIXME: https://reviews.llvm.org/D82831 introduced an automatic
+    // materliazation of conversion around function calls that is not working
+    // well with fir lowering to llvm (incorrect llvm.mlir.cast are inserted).
+    // Workaround until better analysis: register a handler that does not insert
+    // any conversions.
+    addSourceMaterialization(
+        [&](mlir::OpBuilder &builder, mlir::Type resultType,
+            mlir::ValueRange inputs,
+            mlir::Location loc) -> llvm::Optional<mlir::Value> {
+          if (inputs.size() != 1)
+            return llvm::None;
+          return inputs[0];
+        });
+    // Similar FIXME workaround here (needed for compare.fir/select-type.fir
+    // tests).
+    addTargetMaterialization(
+        [&](mlir::OpBuilder &builder, mlir::Type resultType,
+            mlir::ValueRange inputs,
+            mlir::Location loc) -> llvm::Optional<mlir::Value> {
+          if (inputs.size() != 1)
+            return llvm::None;
+          return inputs[0];
+        });
   }
 
   // i32 is used here because LLVM wants i32 constants when indexing into struct

diff  --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index f91c0ece5aa7a..99379b4433c3f 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -113,6 +113,28 @@ fir.global internal @_QEmultiarray : !fir.array<32xi32> {
 
 // -----
 
+// Test global with box
+
+fir.global internal @_QFEx : !fir.box<!fir.ptr<i32>> {
+  %0 = fir.zero_bits !fir.ptr<i32>
+  %1 = fir.embox %0 : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>>
+  fir.has_value %1 : !fir.box<!fir.ptr<i32>>
+}
+
+// CHECK-LABEL: llvm.mlir.global internal @_QFEx()
+// CHECK-SAME:  !llvm.struct<([[DES_FIELDS:.*]])>
+// CHECK:         %[[T0:.*]] = llvm.mlir.undef : !llvm.struct<([[DES_FIELDS]])>
+// CHECK:         %[[T1:.*]] = llvm.insertvalue %{{.*}}, %[[T0]][1 : i32] : !llvm.struct<([[DES_FIELDS]])>
+// CHECK:         %[[T2:.*]] = llvm.insertvalue %{{.*}}, %[[T1]][2 : i32] : !llvm.struct<([[DES_FIELDS]])>
+// CHECK:         %[[T3:.*]] = llvm.insertvalue %{{.*}}, %[[T2]][3 : i32] : !llvm.struct<([[DES_FIELDS]])>
+// CHECK:         %[[T4:.*]] = llvm.insertvalue %{{.*}}, %[[T3]][4 : i32] : !llvm.struct<([[DES_FIELDS]])>
+// CHECK:         %[[T5:.*]] = llvm.insertvalue %{{.*}}, %[[T4]][5 : i32] : !llvm.struct<([[DES_FIELDS]])>
+// CHECK:         %[[T6:.*]] = llvm.insertvalue %{{.*}}, %[[T5]][6 : i32] : !llvm.struct<([[DES_FIELDS]])>
+// CHECK:         %[[GDES:.*]] = llvm.insertvalue %{{.*}}, %[[T6]][0 : i32] : !llvm.struct<([[DES_FIELDS]])>
+// CHECK:         llvm.return %[[GDES]] : !llvm.struct<([[DES_FIELDS]])>
+
+// -----
+
 // Test fir.zero_bits operation with LLVM ptr type
 
 func.func @zero_test_ptr() {


        


More information about the flang-commits mailing list