[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