Index: flang/lib/Optimizer/CodeGen/CodeGen.cpp =================================================================== --- flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -3325,6 +3325,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 /// @@ -3406,6 +3443,33 @@ std::move(pattern)))) { signalPassFailure(); } + + // If we're on Windows, we might need to rename some libm calls. + bool isMSVC = fir::getTargetTriple(mod).isOSMSVCRT(); + if (isMSVC) { + mlir::RewritePatternSet patterns(context); + patterns.insert(context); + + mlir::ConversionTarget target{*context}; + target + .addLegalDialect(); + 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"); + }); + + if (mlir::failed(mlir::applyPartialConversion(getModule(), target, + std::move(patterns)))) { + signalPassFailure(); + } + } } private: Index: flang/test/Fir/rename-msvc-libm.fir =================================================================== --- /dev/null +++ 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