[flang-commits] [flang] 2c8d338 - [flang] Enable target rewrite for int args/rets of bind(c) functions.

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Tue Mar 7 19:10:41 PST 2023


Author: Slava Zakharin
Date: 2023-03-07T19:08:02-08:00
New Revision: 2c8d33897d90a6651842120805e28364c84c11a1

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

LOG: [flang] Enable target rewrite for int args/rets of bind(c) functions.

BIND(C) subprograms must use the same target ABI as the C processor,
so 1/2-byte int args/rets must be rewritten to use signext attribute.
This change-set also sets fir.bindc_name for the math functions used
during lowering so that they can be fixed up as well (though, currently
none of them needs to be affected).

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

Added: 
    

Modified: 
    flang/lib/Optimizer/Builder/IntrinsicCall.cpp
    flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
    flang/test/Fir/target-rewrite-integer.fir
    flang/test/Lower/math-lowering.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index eff53b397509..53bc24cdc6df 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -1081,6 +1081,9 @@ static mlir::Value genLibCall(fir::FirOpBuilder &builder, mlir::Location loc,
              libFuncType.dump(); llvm::dbgs() << "\n");
   mlir::func::FuncOp funcOp =
       builder.addNamedFunction(loc, libFuncName, libFuncType);
+  // C-interoperability rules apply to these library functions.
+  funcOp->setAttr(fir::getSymbolAttrName(),
+                  mlir::StringAttr::get(builder.getContext(), libFuncName));
   // TODO: ensure 'strictfp' setting on the call for "precise/strict"
   //       FP mode. Set appropriate Fast-Math Flags otherwise.
   // TODO: we should also mark as many libm function as possible

diff  --git a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
index c51bf5f6993b..3cd17cd027a0 100644
--- a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
+++ b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
@@ -468,6 +468,16 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase<TargetRewrite> {
     return mlir::success();
   }
 
+  // Returns true if the function should be interoperable with C.
+  static bool isFuncWithCCallingConvention(mlir::Operation *op) {
+    auto funcOp = mlir::dyn_cast<mlir::func::FuncOp>(op);
+    if (!funcOp)
+      return false;
+    return op->hasAttrOfType<mlir::UnitAttr>(
+               fir::FIROpsDialect::getFirRuntimeAttrName()) ||
+           op->hasAttrOfType<mlir::StringAttr>(fir::getSymbolAttrName());
+  }
+
   /// If the signature does not need any special target-specific conversions,
   /// then it is considered portable for any target, and this function will
   /// return `true`. Otherwise, the signature is not portable and `false` is
@@ -475,12 +485,11 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase<TargetRewrite> {
   bool hasPortableSignature(mlir::Type signature, mlir::Operation *op) {
     assert(signature.isa<mlir::FunctionType>());
     auto func = signature.dyn_cast<mlir::FunctionType>();
-    bool hasFirRuntime = op->hasAttrOfType<mlir::UnitAttr>(
-        fir::FIROpsDialect::getFirRuntimeAttrName());
+    bool hasCCallingConv = isFuncWithCCallingConvention(op);
     for (auto ty : func.getResults())
       if ((ty.isa<fir::BoxCharType>() && !noCharacterConversion) ||
           (fir::isa_complex(ty) && !noComplexConversion) ||
-          (ty.isa<mlir::IntegerType>() && hasFirRuntime)) {
+          (ty.isa<mlir::IntegerType>() && hasCCallingConv)) {
         LLVM_DEBUG(llvm::dbgs() << "rewrite " << signature << " for target\n");
         return false;
       }
@@ -488,7 +497,7 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase<TargetRewrite> {
       if (((ty.isa<fir::BoxCharType>() || fir::isCharacterProcedureTuple(ty)) &&
            !noCharacterConversion) ||
           (fir::isa_complex(ty) && !noComplexConversion) ||
-          (ty.isa<mlir::IntegerType>() && hasFirRuntime)) {
+          (ty.isa<mlir::IntegerType>() && hasCCallingConv)) {
         LLVM_DEBUG(llvm::dbgs() << "rewrite " << signature << " for target\n");
         return false;
       }
@@ -552,9 +561,7 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase<TargetRewrite> {
             std::size_t resId = newResTys.size();
             llvm::StringRef extensionAttrName = attr.getIntExtensionAttrName();
             if (!extensionAttrName.empty() &&
-                // TODO: we have to do the same for BIND(C) routines.
-                func->hasAttrOfType<mlir::UnitAttr>(
-                    fir::FIROpsDialect::getFirRuntimeAttrName()))
+                isFuncWithCCallingConvention(func))
               resultAttrs.emplace_back(
                   resId, rewriter->getNamedAttr(extensionAttrName,
                                                 rewriter->getUnitAttr()));
@@ -631,16 +638,14 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase<TargetRewrite> {
             auto argNo = newInTys.size();
             llvm::StringRef extensionAttrName = attr.getIntExtensionAttrName();
             if (!extensionAttrName.empty() &&
-                // TODO: we have to do the same for BIND(C) routines.
-                func->hasAttrOfType<mlir::UnitAttr>(
-                    fir::FIROpsDialect::getFirRuntimeAttrName())) {
+                isFuncWithCCallingConvention(func))
               fixups.emplace_back(FixupTy::Codes::ArgumentType, argNo,
                                   [=](mlir::func::FuncOp func) {
                                     func.setArgAttr(
                                         argNo, extensionAttrName,
                                         mlir::UnitAttr::get(func.getContext()));
                                   });
-            }
+
             newInTys.push_back(argTy);
           })
           .Default([&](mlir::Type ty) { newInTys.push_back(ty); });

diff  --git a/flang/test/Fir/target-rewrite-integer.fir b/flang/test/Fir/target-rewrite-integer.fir
index 7bc4e4a31a3a..ad64ca80b473 100644
--- a/flang/test/Fir/target-rewrite-integer.fir
+++ b/flang/test/Fir/target-rewrite-integer.fir
@@ -79,3 +79,36 @@ func.func @_QPtest_ui1(%arg0: !fir.ref<!fir.logical<4>> {fir.bindc_name = "x"})
   return
 }
 func.func private @_SomeFunc_ui1(ui1) -> ui1 attributes {fir.runtime}
+
+// -----
+
+// subroutine test(x, y)
+//   use iso_c_binding
+//   interface
+//      integer(c_int8_t) function cfun8(x) bind(C)
+//        integer(c_int8_t),value :: x
+//      end function cfun8
+//      integer(c_int16_t) function cfun16(x) bind(C)
+//        integer(c_int16_t),value :: x
+//      end function cfun16
+//   end interface
+//   integer(c_int8_t) :: x
+//   integer(c_int16_t) :: y
+//   x = cfun8(x)
+//   y = cfun16(y)
+// end subroutine test
+
+// ALL-LABEL: @_QPtest_bindc
+// ALL: func.func private @cfun8(i8 {llvm.signext}) -> (i8 {llvm.signext}) attributes {fir.bindc_name = "cfun8"}
+// ALL: func.func private @cfun16(i16 {llvm.signext}) -> (i16 {llvm.signext}) attributes {fir.bindc_name = "cfun16"}
+func.func @_QPtest_bindc(%arg0: !fir.ref<i8> {fir.bindc_name = "x"}, %arg1: !fir.ref<i16> {fir.bindc_name = "y"}) {
+  %0 = fir.load %arg0 : !fir.ref<i8>
+  %1 = fir.call @cfun8(%0) fastmath<contract> : (i8) -> i8
+  fir.store %1 to %arg0 : !fir.ref<i8>
+  %2 = fir.load %arg1 : !fir.ref<i16>
+  %3 = fir.call @cfun16(%2) fastmath<contract> : (i16) -> i16
+  fir.store %3 to %arg1 : !fir.ref<i16>
+  return
+}
+func.func private @cfun8(i8) -> i8 attributes {fir.bindc_name = "cfun8"}
+func.func private @cfun16(i16) -> i16 attributes {fir.bindc_name = "cfun16"}

diff  --git a/flang/test/Lower/math-lowering.f90 b/flang/test/Lower/math-lowering.f90
index b6b720045f24..857c9883c65d 100644
--- a/flang/test/Lower/math-lowering.f90
+++ b/flang/test/Lower/math-lowering.f90
@@ -57,6 +57,12 @@ function test_complex8(c)
 ! RELAXED: {{%[A-Za-z0-9._]+}} = complex.abs {{%[A-Za-z0-9._]+}} : complex<f64>
 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @cabs({{%[A-Za-z0-9._]+}}) {{.*}}: (!fir.complex<8>) -> f64
 
+! PRECISE-DAG: func.func private @fabsf(f32) -> f32 attributes {fir.bindc_name = "fabsf"}
+! PRECISE-DAG: func.func private @fabs(f64) -> f64 attributes {fir.bindc_name = "fabs"}
+! PRECISE-DAG: func.func private @llvm.fabs.f128(f128) -> f128 attributes {fir.bindc_name = "llvm.fabs.f128"}
+! PRECISE-DAG: func.func private @cabsf(!fir.complex<4>) -> f32 attributes {fir.bindc_name = "cabsf"}
+! PRECISE-DAG: func.func private @cabs(!fir.complex<8>) -> f64 attributes {fir.bindc_name = "cabs"}
+
 //--- aint.f90
 ! RUN: bbc -emit-fir %t/aint.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL %t/aint.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/aint.f90 -o - | FileCheck --check-prefixes=ALL %t/aint.f90
@@ -95,6 +101,10 @@ function test_real10(x)
 !  test_real16 = aint(x)
 !end function
 
+! ALL-DAG: func.func private @llvm.trunc.f32(f32) -> f32 attributes {fir.bindc_name = "llvm.trunc.f32"}
+! ALL-DAG: func.func private @llvm.trunc.f64(f64) -> f64 attributes {fir.bindc_name = "llvm.trunc.f64"}
+! ALL-DAG: func.func private @llvm.trunc.f80(f80) -> f80 attributes {fir.bindc_name = "llvm.trunc.f80"}
+
 //--- anint.f90
 ! RUN: bbc -emit-fir %t/anint.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/anint.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/anint.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/anint.f90
@@ -139,6 +149,10 @@ function test_real10(x)
 !  test_real16 = anint(x)
 !end function
 
+! PRECISE-DAG: func.func private @llvm.round.f32(f32) -> f32 attributes {fir.bindc_name = "llvm.round.f32"}
+! PRECISE-DAG: func.func private @llvm.round.f64(f64) -> f64 attributes {fir.bindc_name = "llvm.round.f64"}
+! PRECISE-DAG: func.func private @llvm.round.f80(f80) -> f80 attributes {fir.bindc_name = "llvm.round.f80"}
+
 //--- atan.f90
 ! RUN: bbc -emit-fir %t/atan.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/atan.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/atan.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/atan.f90
@@ -167,6 +181,9 @@ function test_real8(x)
 ! RELAXED: {{%[A-Za-z0-9._]+}} = math.atan {{%[A-Za-z0-9._]+}} {{.*}}: f64
 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @atan({{%[A-Za-z0-9._]+}}) {{.*}}: (f64) -> f64
 
+! PRECISE-DAG: func.func private @atanf(f32) -> f32 attributes {fir.bindc_name = "atanf"}
+! PRECISE-DAG: func.func private @atan(f64) -> f64 attributes {fir.bindc_name = "atan"}
+
 //--- atan2.f90
 ! RUN: bbc -emit-fir %t/atan2.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/atan2.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/atan2.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/atan2.f90
@@ -195,6 +212,9 @@ function test_real8(x, y)
 ! RELAXED: {{%[A-Za-z0-9._]+}} = math.atan2 {{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}} {{.*}}: f64
 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @atan2({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) {{.*}}: (f64, f64) -> f64
 
+! PRECISE-DAG: func.func private @atan2f(f32, f32) -> f32 attributes {fir.bindc_name = "atan2f"}
+! PRECISE-DAG: func.func private @atan2(f64, f64) -> f64 attributes {fir.bindc_name = "atan2"}
+
 //--- ceiling.f90
 ! RUN: bbc -emit-fir %t/ceiling.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/ceiling.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/ceiling.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/ceiling.f90
@@ -223,6 +243,9 @@ function test_real8(x)
 ! RELAXED: {{%[A-Za-z0-9._]+}} = math.ceil {{%[A-Za-z0-9._]+}} {{.*}}: f64
 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @ceil({{%[A-Za-z0-9._]+}}) {{.*}}: (f64) -> f64
 
+! PRECISE-DAG: func.func private @ceilf(f32) -> f32 attributes {fir.bindc_name = "ceilf"}
+! PRECISE-DAG: func.func private @ceil(f64) -> f64 attributes {fir.bindc_name = "ceil"}
+
 //--- cos.f90
 ! RUN: bbc -emit-fir %t/cos.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/cos.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/cos.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/cos.f90
@@ -251,6 +274,9 @@ function test_real8(x)
 ! RELAXED: {{%[A-Za-z0-9._]+}} = math.cos {{%[A-Za-z0-9._]+}} {{.*}}: f64
 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @cos({{%[A-Za-z0-9._]+}}) {{.*}}: (f64) -> f64
 
+! PRECISE-DAG: func.func private @cosf(f32) -> f32 attributes {fir.bindc_name = "cosf"}
+! PRECISE-DAG: func.func private @cos(f64) -> f64 attributes {fir.bindc_name = "cos"}
+
 //--- cosh.f90
 ! RUN: bbc -emit-fir %t/cosh.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL %t/cosh.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/cosh.f90 -o - | FileCheck --check-prefixes=ALL %t/cosh.f90
@@ -275,6 +301,9 @@ function test_real8(x)
 ! ALL-LABEL: @_QPtest_real8
 ! ALL: {{%[A-Za-z0-9._]+}} = fir.call @cosh({{%[A-Za-z0-9._]+}}) {{.*}}: (f64) -> f64
 
+! ALL-DAG: func.func private @coshf(f32) -> f32 attributes {fir.bindc_name = "coshf"}
+! ALL-DAG: func.func private @cosh(f64) -> f64 attributes {fir.bindc_name = "cosh"}
+
 //--- erf.f90
 ! RUN: bbc -emit-fir %t/erf.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/erf.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/erf.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/erf.f90
@@ -303,6 +332,9 @@ function test_real8(x)
 ! RELAXED: {{%[A-Za-z0-9._]+}} = math.erf {{%[A-Za-z0-9._]+}} {{.*}}: f64
 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @erf({{%[A-Za-z0-9._]+}}) {{.*}}: (f64) -> f64
 
+! PRECISE-DAG: func.func private @erff(f32) -> f32 attributes {fir.bindc_name = "erff"}
+! PRECISE-DAG: func.func private @erf(f64) -> f64 attributes {fir.bindc_name = "erf"}
+
 //--- exp.f90
 ! RUN: bbc -emit-fir %t/exp.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/exp.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/exp.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/exp.f90
@@ -331,6 +363,9 @@ function test_real8(x)
 ! RELAXED: {{%[A-Za-z0-9._]+}} = math.exp {{%[A-Za-z0-9._]+}} {{.*}}: f64
 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @exp({{%[A-Za-z0-9._]+}}) {{.*}}: (f64) -> f64
 
+! PRECISE-DAG: func.func private @expf(f32) -> f32 attributes {fir.bindc_name = "expf"}
+! PRECISE-DAG: func.func private @exp(f64) -> f64 attributes {fir.bindc_name = "exp"}
+
 //--- floor.f90
 ! RUN: bbc -emit-fir %t/floor.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/floor.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/floor.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/floor.f90
@@ -359,6 +394,9 @@ function test_real8(x)
 ! RELAXED: {{%[A-Za-z0-9._]+}} = math.floor {{%[A-Za-z0-9._]+}} {{.*}}: f64
 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @floor({{%[A-Za-z0-9._]+}}) {{.*}}: (f64) -> f64
 
+! PRECISE-DAG: func.func private @floorf(f32) -> f32 attributes {fir.bindc_name = "floorf"}
+! PRECISE-DAG: func.func private @floor(f64) -> f64 attributes {fir.bindc_name = "floor"}
+
 //--- log.f90
 ! RUN: bbc -emit-fir %t/log.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/log.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/log.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/log.f90
@@ -387,6 +425,9 @@ function test_real8(x)
 ! RELAXED: {{%[A-Za-z0-9._]+}} = math.log {{%[A-Za-z0-9._]+}} {{.*}}: f64
 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @log({{%[A-Za-z0-9._]+}}) {{.*}}: (f64) -> f64
 
+! PRECISE-DAG: func.func private @logf(f32) -> f32 attributes {fir.bindc_name = "logf"}
+! PRECISE-DAG: func.func private @log(f64) -> f64 attributes {fir.bindc_name = "log"}
+
 //--- log10.f90
 ! RUN: bbc -emit-fir %t/log10.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/log10.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/log10.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/log10.f90
@@ -415,6 +456,9 @@ function test_real8(x)
 ! RELAXED: {{%[A-Za-z0-9._]+}} = math.log10 {{%[A-Za-z0-9._]+}} {{.*}}: f64
 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @log10({{%[A-Za-z0-9._]+}}) {{.*}}: (f64) -> f64
 
+! PRECISE-DAG: func.func private @log10f(f32) -> f32 attributes {fir.bindc_name = "log10f"}
+! PRECISE-DAG: func.func private @log10(f64) -> f64 attributes {fir.bindc_name = "log10"}
+
 //--- nint.f90
 ! RUN: bbc -emit-fir %t/nint.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL %t/nint.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/nint.f90 -o - | FileCheck --check-prefixes=ALL %t/nint.f90
@@ -441,6 +485,11 @@ function test_real8(x)
 ! ALL: {{%[A-Za-z0-9._]+}} = fir.call @llvm.lround.i32.f64({{%[A-Za-z0-9._]+}}) {{.*}}: (f64) -> i32
 ! ALL: {{%[A-Za-z0-9._]+}} = fir.call @llvm.lround.i64.f64({{%[A-Za-z0-9._]+}}) {{.*}}: (f64) -> i64
 
+! ALL-DAG: func.func private @llvm.lround.i32.f32(f32) -> i32 attributes {fir.bindc_name = "llvm.lround.i32.f32"}
+! ALL-DAG: func.func private @llvm.lround.i64.f32(f32) -> i64 attributes {fir.bindc_name = "llvm.lround.i64.f32"}
+! ALL-DAG: func.func private @llvm.lround.i32.f64(f64) -> i32 attributes {fir.bindc_name = "llvm.lround.i32.f64"}
+! ALL-DAG: func.func private @llvm.lround.i64.f64(f64) -> i64 attributes {fir.bindc_name = "llvm.lround.i64.f64"}
+
 //--- exponentiation.f90
 ! RUN: bbc -emit-fir %t/exponentiation.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/exponentiation.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/exponentiation.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/exponentiation.f90
@@ -495,6 +544,13 @@ function test_real8(x, y, s, i, k)
 ! RELAXED: {{%[A-Za-z0-9._]+}} = math.fpowi {{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}} {{.*}}: f64, i64
 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @_FortranAFPow8k({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) {{.*}}: (f64, i64) -> f64
 
+! PRECISE-DAG: func.func private @_FortranAFPow4i(f32, i32) -> f32 attributes {fir.bindc_name = "_FortranAFPow4i"}
+! PRECISE-DAG: func.func private @powf(f32, f32) -> f32 attributes {fir.bindc_name = "powf"}
+! PRECISE-DAG: func.func private @_FortranAFPow4k(f32, i64) -> f32 attributes {fir.bindc_name = "_FortranAFPow4k"}
+! PRECISE-DAG: func.func private @_FortranAFPow8i(f64, i32) -> f64 attributes {fir.bindc_name = "_FortranAFPow8i"}
+! PRECISE-DAG: func.func private @pow(f64, f64) -> f64 attributes {fir.bindc_name = "pow"}
+! PRECISE-DAG: func.func private @_FortranAFPow8k(f64, i64) -> f64 attributes {fir.bindc_name = "_FortranAFPow8k"}
+
 //--- sign.f90
 ! RUN: bbc -emit-fir %t/sign.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/sign.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/sign.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/sign.f90
@@ -543,6 +599,11 @@ function test_real16(x, y)
 ! RELAXED: {{%[A-Za-z0-9._]+}} = math.copysign {{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}} {{.*}}: f128
 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @llvm.copysign.f128({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) {{.*}}: (f128, f128) -> f128
 
+! PRECISE-DAG: func.func private @copysignf(f32, f32) -> f32 attributes {fir.bindc_name = "copysignf"}
+! PRECISE-DAG: func.func private @copysign(f64, f64) -> f64 attributes {fir.bindc_name = "copysign"}
+! PRECISE-DAG: func.func private @copysignl(f80, f80) -> f80 attributes {fir.bindc_name = "copysignl"}
+! PRECISE-DAG: func.func private @llvm.copysign.f128(f128, f128) -> f128 attributes {fir.bindc_name = "llvm.copysign.f128"}
+
 //--- sin.f90
 ! RUN: bbc -emit-fir %t/sin.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/sin.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/sin.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/sin.f90
@@ -571,6 +632,9 @@ function test_real8(x)
 ! RELAXED: {{%[A-Za-z0-9._]+}} = math.sin {{%[A-Za-z0-9._]+}} {{.*}}: f64
 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @sin({{%[A-Za-z0-9._]+}}) {{.*}}: (f64) -> f64
 
+! PRECISE-DAG: func.func private @sinf(f32) -> f32 attributes {fir.bindc_name = "sinf"}
+! PRECISE-DAG: func.func private @sin(f64) -> f64 attributes {fir.bindc_name = "sin"}
+
 //--- sinh.f90
 ! RUN: bbc -emit-fir %t/sinh.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL %t/sinh.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/sinh.f90 -o - | FileCheck --check-prefixes=ALL %t/sinh.f90
@@ -595,6 +659,9 @@ function test_real8(x)
 ! ALL-LABEL: @_QPtest_real8
 ! ALL: {{%[A-Za-z0-9._]+}} = fir.call @sinh({{%[A-Za-z0-9._]+}}) {{.*}}: (f64) -> f64
 
+! ALL-DAG: func.func private @sinhf(f32) -> f32 attributes {fir.bindc_name = "sinhf"}
+! ALL-DAG: func.func private @sinh(f64) -> f64 attributes {fir.bindc_name = "sinh"}
+
 //--- tanh.f90
 ! RUN: bbc -emit-fir %t/tanh.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/tanh.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/tanh.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/tanh.f90
@@ -623,6 +690,9 @@ function test_real8(x)
 ! RELAXED: {{%[A-Za-z0-9._]+}} = math.tanh {{%[A-Za-z0-9._]+}} {{.*}}: f64
 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @tanh({{%[A-Za-z0-9._]+}}) {{.*}}: (f64) -> f64
 
+! PRECISE-DAG: func.func private @tanhf(f32) -> f32 attributes {fir.bindc_name = "tanhf"}
+! PRECISE-DAG: func.func private @tanh(f64) -> f64 attributes {fir.bindc_name = "tanh"}
+
 //--- tan.f90
 ! RUN: bbc -emit-fir %t/tan.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/tan.f90
 ! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/tan.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/tan.f90
@@ -650,3 +720,6 @@ function test_real8(x)
 ! FAST: {{%[A-Za-z0-9._]+}} = math.tan {{%[A-Za-z0-9._]+}} {{.*}}: f64
 ! RELAXED: {{%[A-Za-z0-9._]+}} = math.tan {{%[A-Za-z0-9._]+}} {{.*}}: f64
 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @tan({{%[A-Za-z0-9._]+}}) {{.*}}: (f64) -> f64
+
+! PRECISE-DAG: func.func private @tanf(f32) -> f32 attributes {fir.bindc_name = "tanf"}
+! PRECISE-DAG: func.func private @tan(f64) -> f64 attributes {fir.bindc_name = "tan"}


        


More information about the flang-commits mailing list