[flang-commits] [flang] ff8742d - [flang] Fixed selective TargetRewrite.

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Fri Feb 10 09:11:39 PST 2023


Author: Slava Zakharin
Date: 2023-02-10T08:57:37-08:00
New Revision: ff8742df9e65c60de2fce0b19c0f52fd663626a1

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

LOG: [flang] Fixed selective TargetRewrite.

Some conversions were still happening under no-complex/character-conversion
options. This change fixes that and adds a LIT test.

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

Added: 
    flang/test/Fir/target-rewrite-selective.fir

Modified: 
    flang/lib/Optimizer/CodeGen/TargetRewrite.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
index bddeffb98519..c51bf5f6993b 100644
--- a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
+++ b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
@@ -119,9 +119,13 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase<TargetRewrite> {
   mlir::ModuleOp getModule() { return getOperation(); }
 
   template <typename A, typename B, typename C>
-  std::function<mlir::Value(mlir::Operation *)>
+  std::optional<std::function<mlir::Value(mlir::Operation *)>>
   rewriteCallComplexResultType(mlir::Location loc, A ty, B &newResTys,
                                B &newInTys, C &newOpers) {
+    if (noComplexConversion) {
+      newResTys.push_back(ty);
+      return std::nullopt;
+    }
     auto m = specifics->complexReturnType(loc, ty.getElementType());
     // Currently targets mandate COMPLEX is a single aggregate or packed
     // scalar, including the sret case.
@@ -153,6 +157,12 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase<TargetRewrite> {
   template <typename A, typename B, typename C>
   void rewriteCallComplexInputType(A ty, mlir::Value oper, B &newInTys,
                                    C &newOpers) {
+    if (noComplexConversion) {
+      newInTys.push_back(ty);
+      newOpers.push_back(oper);
+      return;
+    }
+
     auto *ctx = ty.getContext();
     mlir::Location loc = mlir::UnknownLoc::get(ctx);
     if (auto *op = oper.getDefiningOp())
@@ -245,6 +255,11 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase<TargetRewrite> {
           .template Case<fir::BoxCharType>([&](fir::BoxCharType boxTy) {
             bool sret;
             if constexpr (std::is_same_v<std::decay_t<A>, fir::CallOp>) {
+              if (noCharacterConversion) {
+                newInTys.push_back(boxTy);
+                newOpers.push_back(oper);
+                return;
+              }
               sret = callOp.getCallee() &&
                      functionArgIsSRet(
                          index, getModule().lookupSymbol<mlir::func::FuncOp>(

diff  --git a/flang/test/Fir/target-rewrite-selective.fir b/flang/test/Fir/target-rewrite-selective.fir
new file mode 100644
index 000000000000..4b54235d2d48
--- /dev/null
+++ b/flang/test/Fir/target-rewrite-selective.fir
@@ -0,0 +1,70 @@
+// RUN: fir-opt --target-rewrite="target=x86_64-unknown-linux-gnu no-complex-conversion" %s | FileCheck --check-prefix=CMPLXOFF %s
+// RUN: fir-opt --target-rewrite="target=x86_64-unknown-linux-gnu no-character-conversion" %s | FileCheck --check-prefix=CHAROFF %s
+
+// Verify that selective TargetRewrite with no-complex-conversion and
+// no-character-conversion options works as expected.
+//
+// Original code:
+// complex function test(value)
+//   interface
+//      complex function test1(name, c)
+//        character(*) :: name
+//        complex, value :: c
+//      end function
+//      character(10) function test2(c)
+//        complex, value :: c
+//      end function
+//   end interface
+//   complex, value :: value
+//   character(10) :: r
+//   test = test1("", value)
+//   r = test2(value)
+// end function
+
+// CMPLXOFF-DAG: fir.call @_QPtest1({{.*}}, {{.*}}, {{.*}}) : (!fir.ref<!fir.char<1,?>>, !fir.complex<4>, i64) -> !fir.complex<4>
+// CMPLXOFF-DAG: fir.call @_QPtest2({{.*}}, {{.*}}, {{.*}}) : (!fir.ref<!fir.char<1,10>>, index, !fir.complex<4>) -> !fir.boxchar<1>
+// CMPLXOFF-DAG: func.func private @_QPtest1(!fir.ref<!fir.char<1,?>>, !fir.complex<4>, i64) -> !fir.complex<4>
+// CMPLXOFF-DAG: func.func private @_QPtest2(!fir.ref<!fir.char<1,10>>, index, !fir.complex<4>) -> !fir.boxchar<1>
+
+// CHAROFF-DAG: fir.call @_QPtest1({{.*}}, {{.*}}) : (!fir.boxchar<1>, !fir.vector<2:!fir.real<4>>) -> !fir.vector<2:!fir.real<4>>
+// CHAROFF-DAG: fir.call @_QPtest2({{.*}}, {{.*}}, {{.*}}) : (!fir.ref<!fir.char<1,10>>, index, !fir.vector<2:!fir.real<4>>) -> !fir.boxchar<1>
+// CHAROFF-DAG: func.func private @_QPtest1(!fir.boxchar<1>, !fir.vector<2:!fir.real<4>>) -> !fir.vector<2:!fir.real<4>>
+// CHAROFF-DAG: func.func private @_QPtest2(!fir.ref<!fir.char<1,10>>, index, !fir.vector<2:!fir.real<4>>) -> !fir.boxchar<1>
+
+module {
+  func.func @_QPtest(%arg0: !fir.complex<4> {fir.bindc_name = "value"}) -> !fir.complex<4> {
+    %c10 = arith.constant 10 : index
+    %false = arith.constant false
+    %c0 = arith.constant 0 : index
+    %0 = fir.alloca !fir.char<1,10> {bindc_name = ".result"}
+    %1 = fir.alloca !fir.complex<4>
+    fir.store %arg0 to %1 : !fir.ref<!fir.complex<4>>
+    %2 = fir.alloca !fir.char<1,10> {bindc_name = "r", uniq_name = "_QFtestEr"}
+    %3 = fir.alloca !fir.complex<4> {bindc_name = "test", uniq_name = "_QFtestEtest"}
+    %4 = fir.address_of(@_QQcl.) : !fir.ref<!fir.char<1,0>>
+    %5 = fir.convert %4 : (!fir.ref<!fir.char<1,0>>) -> !fir.ref<!fir.char<1,?>>
+    %6 = fir.emboxchar %5, %c0 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
+    %7 = fir.load %1 : !fir.ref<!fir.complex<4>>
+    %8 = fir.call @_QPtest1(%6, %7) fastmath<contract> : (!fir.boxchar<1>, !fir.complex<4>) -> !fir.complex<4>
+    fir.store %8 to %3 : !fir.ref<!fir.complex<4>>
+    %9 = fir.load %1 : !fir.ref<!fir.complex<4>>
+    %10 = fir.call @llvm.stacksave() fastmath<contract> : () -> !fir.ref<i8>
+    %11 = fir.call @_QPtest2(%0, %c10, %9) fastmath<contract> : (!fir.ref<!fir.char<1,10>>, index, !fir.complex<4>) -> !fir.boxchar<1>
+    %12 = fir.convert %c10 : (index) -> i64
+    %13 = fir.convert %2 : (!fir.ref<!fir.char<1,10>>) -> !fir.ref<i8>
+    %14 = fir.convert %0 : (!fir.ref<!fir.char<1,10>>) -> !fir.ref<i8>
+    fir.call @llvm.memmove.p0.p0.i64(%13, %14, %12, %false) fastmath<contract> : (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
+    fir.call @llvm.stackrestore(%10) fastmath<contract> : (!fir.ref<i8>) -> ()
+    %15 = fir.load %3 : !fir.ref<!fir.complex<4>>
+    return %15 : !fir.complex<4>
+  }
+  func.func private @_QPtest1(!fir.boxchar<1>, !fir.complex<4>) -> !fir.complex<4>
+  fir.global linkonce @_QQcl. constant : !fir.char<1,0> {
+    %0 = fir.string_lit ""(0) : !fir.char<1,0>
+    fir.has_value %0 : !fir.char<1,0>
+  }
+  func.func private @_QPtest2(!fir.ref<!fir.char<1,10>>, index, !fir.complex<4>) -> !fir.boxchar<1>
+  func.func private @llvm.stacksave() -> !fir.ref<i8>
+  func.func private @llvm.memmove.p0.p0.i64(!fir.ref<i8>, !fir.ref<i8>, i64, i1)
+  func.func private @llvm.stackrestore(!fir.ref<i8>)
+}


        


More information about the flang-commits mailing list