[flang-commits] [flang] 36799df - [flang] Rename hypotf on MSVC platforms

Diana Picus via flang-commits flang-commits at lists.llvm.org
Fri Oct 21 02:09:59 PDT 2022


Author: Diana Picus
Date: 2022-10-21T09:09:25Z
New Revision: 36799dfd519ccaa1170efe36d907c0b513c50203

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

LOG: [flang] Rename hypotf on MSVC platforms

The single precision `hypot` intrinsic is lowered to a call to the libm
`hypotf` function.  However, the MSVC runtime lacks a hypotf function
and instead uses `_hypotf` (*). This patch tries to find and rewrite
calls to `hypotf` if we're on a MSVC platform.

Calls to libm functions can be introduced even after lowering (**).
Therefore, we try to do the rewriting at the very end of FIR to LLVM
lowering.

Fixes https://github.com/llvm/llvm-project/issues/57563

(*) More specifically, MSVC's headers define hypotf as an inline
function that just calls _hypotf. This works fine for clang, since it
will include those headers, but flang only links with the CRT so we
don't get a free ride.

(**) https://github.com/llvm/llvm-project/blob/56f94ede2af9a327e59fe84dbf8cbbb7bb1dfa79/flang/lib/Optimizer/CodeGen/CodeGen.cpp#L3391

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

Added: 
    flang/test/Fir/rename-msvc-libm.fir

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

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 7766d5c4bebe..a49777fdd6b0 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -3447,6 +3447,43 @@ struct SliceOpConversion : public MustBeDeadConversion<fir::SliceOp> {
 
 } // namespace
 
+namespace {
+class RenameMSVCLibmCallees
+    : public mlir::OpRewritePattern<mlir::LLVM::CallOp> {
+public:
+  using OpRewritePattern::OpRewritePattern;
+
+  mlir::LogicalResult
+  matchAndRewrite(mlir::LLVM::CallOp op,
+                  mlir::PatternRewriter &rewriter) const override {
+    rewriter.startRootUpdate(op);
+    auto callee = op.getCallee();
+    if (callee)
+      if (callee->equals("hypotf"))
+        op.setCalleeAttr(mlir::SymbolRefAttr::get(op.getContext(), "_hypotf"));
+
+    rewriter.finalizeRootUpdate(op);
+    return mlir::success();
+  }
+};
+
+class RenameMSVCLibmFuncs
+    : public mlir::OpRewritePattern<mlir::LLVM::LLVMFuncOp> {
+public:
+  using OpRewritePattern::OpRewritePattern;
+
+  mlir::LogicalResult
+  matchAndRewrite(mlir::LLVM::LLVMFuncOp op,
+                  mlir::PatternRewriter &rewriter) const override {
+    rewriter.startRootUpdate(op);
+    if (op.getSymName().equals("hypotf"))
+      op.setSymNameAttr(rewriter.getStringAttr("_hypotf"));
+    rewriter.finalizeRootUpdate(op);
+    return mlir::success();
+  }
+};
+} // namespace
+
 namespace {
 /// Convert FIR dialect to LLVM dialect
 ///
@@ -3549,6 +3586,24 @@ class FIRToLLVMLowering
     // required NOPs for applying a full conversion
     target.addLegalOp<mlir::ModuleOp>();
 
+    // If we're on Windows, we might need to rename some libm calls.
+    bool isMSVC = fir::getTargetTriple(mod).isOSMSVCRT();
+    if (isMSVC) {
+      pattern.insert<RenameMSVCLibmCallees, RenameMSVCLibmFuncs>(context);
+
+      target.addDynamicallyLegalOp<mlir::LLVM::CallOp>(
+          [](mlir::LLVM::CallOp op) {
+            auto callee = op.getCallee();
+            if (!callee)
+              return true;
+            return !callee->equals("hypotf");
+          });
+      target.addDynamicallyLegalOp<mlir::LLVM::LLVMFuncOp>(
+          [](mlir::LLVM::LLVMFuncOp op) {
+            return !op.getSymName().equals("hypotf");
+          });
+    }
+
     // apply the patterns
     if (mlir::failed(mlir::applyFullConversion(getModule(), target,
                                                std::move(pattern)))) {

diff  --git a/flang/test/Fir/rename-msvc-libm.fir b/flang/test/Fir/rename-msvc-libm.fir
new file mode 100644
index 000000000000..1c1f34433bb8
--- /dev/null
+++ b/flang/test/Fir/rename-msvc-libm.fir
@@ -0,0 +1,17 @@
+// RUN: fir-opt --fir-to-llvm-ir="target=aarch64-unknown-linux-gnu" %s | FileCheck %s -DHYPOTF=hypotf
+// RUN: fir-opt --fir-to-llvm-ir="target=aarch64-pc-windows-msvc" %s | FileCheck %s -DHYPOTF=_hypotf
+
+// Test hypotf renaming
+
+func.func private @hypotf(f32, f32) -> f32
+
+// CHECK: llvm.func @[[HYPOTF]](f32, f32) -> f32
+
+func.func @call_hypotf(%arg0 : f32, %arg1 : f32) -> f32 {
+  %0 = fir.call @hypotf(%arg0, %arg1) : (f32, f32) -> f32
+  return %0 : f32
+}
+
+// CHECK-LABEL: llvm.func @call_hypotf
+// CHECK-SAME: %[[arg0:.*]]: f32, %[[arg1:.*]]: f32
+// CHECK: llvm.call @[[HYPOTF]](%[[arg0]], %[[arg1]]) : (f32, f32) -> f32


        


More information about the flang-commits mailing list