diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -3447,6 +3447,43 @@ } // namespace +namespace { +class RenameMSVCLibmCallees + : public mlir::OpRewritePattern { +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 { +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 @@ // required NOPs for applying a full conversion target.addLegalOp(); + // If we're on Windows, we might need to rename some libm calls. + bool isMSVC = fir::getTargetTriple(mod).isOSMSVCRT(); + if (isMSVC) { + pattern.insert(context); + + target.addDynamicallyLegalOp( + [](mlir::LLVM::CallOp op) { + auto callee = op.getCallee(); + if (!callee) + return true; + return !callee->equals("hypotf"); + }); + target.addDynamicallyLegalOp( + [](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 --- /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