diff options
author | Kareem Ergawy <kareem.ergawy@amd.com> | 2024-01-19 10:40:25 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-19 10:40:25 +0100 |
commit | 10317da20309378365e116ce5d4f87c40d6ad25d (patch) | |
tree | c6387adb5e06b382c703d3e6b304b8864d0a0a7a /flang/unittests | |
parent | 4fc128f817b425657049922175619addb04c8f41 (diff) | |
download | llvm-10317da20309378365e116ce5d4f87c40d6ad25d.zip llvm-10317da20309378365e116ce5d4f87c40d6ad25d.tar.gz llvm-10317da20309378365e116ce5d4f87c40d6ad25d.tar.bz2 |
[flang][re-apply] Fix seg fault CodeGenAction::executeAction() (#78672)
If `generateLLVMIR()` fails, we still continue using the module we
failed to generate which causes a seg fault if LLVM code-gen failed for
some reason or another. This commit fixes this issue.
Re-applies PR #78269 and adds LLVM and MLIR dependencies that were
missed in the PR. The missing libs were: `LLVMCore` & `MLIRIR`.
This reverts commit 4fc75062745eb5232ea60c37b9ffe61177efa12a.
Diffstat (limited to 'flang/unittests')
-rw-r--r-- | flang/unittests/Frontend/CMakeLists.txt | 3 | ||||
-rw-r--r-- | flang/unittests/Frontend/CodeGenActionTest.cpp | 109 |
2 files changed, 112 insertions, 0 deletions
diff --git a/flang/unittests/Frontend/CMakeLists.txt b/flang/unittests/Frontend/CMakeLists.txt index 79a394f..22c568a 100644 --- a/flang/unittests/Frontend/CMakeLists.txt +++ b/flang/unittests/Frontend/CMakeLists.txt @@ -1,9 +1,11 @@ set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} TargetParser + Core ) add_flang_unittest(FlangFrontendTests + CodeGenActionTest.cpp CompilerInstanceTest.cpp FrontendActionTest.cpp ) @@ -18,4 +20,5 @@ target_link_libraries(FlangFrontendTests FortranSemantics FortranCommon FortranEvaluate + MLIRIR ) diff --git a/flang/unittests/Frontend/CodeGenActionTest.cpp b/flang/unittests/Frontend/CodeGenActionTest.cpp new file mode 100644 index 0000000..9d798c7 --- /dev/null +++ b/flang/unittests/Frontend/CodeGenActionTest.cpp @@ -0,0 +1,109 @@ +//===- unittests/Frontend/CodeGenActionTest.cpp --- FrontendAction tests --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Unit tests for CodeGenAction. +// +//===----------------------------------------------------------------------===// + +#include "mlir/IR/Builders.h" +#include "flang/Frontend/CompilerInstance.h" +#include "flang/Frontend/FrontendActions.h" +#include "flang/Frontend/TextDiagnosticPrinter.h" + +#include "gtest/gtest.h" + +#include <memory> + +using namespace Fortran::frontend; + +namespace test { +class DummyDialect : public ::mlir::Dialect { + explicit DummyDialect(::mlir::MLIRContext *context) + : ::mlir::Dialect(getDialectNamespace(), context, + ::mlir::TypeID::get<DummyDialect>()) { + initialize(); + } + + void initialize(); + friend class ::mlir::MLIRContext; + +public: + ~DummyDialect() override = default; + static constexpr ::llvm::StringLiteral getDialectNamespace() { + return ::llvm::StringLiteral("dummy"); + } +}; + +namespace dummy { +class FakeOp : public ::mlir::Op<FakeOp> { +public: + using Op::Op; + + static llvm::StringRef getOperationName() { return "dummy.fake"; } + + static ::llvm::ArrayRef<::llvm::StringRef> getAttributeNames() { return {}; } + + static void build( + ::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState) {} +}; +} // namespace dummy +} // namespace test + +MLIR_DECLARE_EXPLICIT_TYPE_ID(::test::DummyDialect) +MLIR_DEFINE_EXPLICIT_TYPE_ID(::test::DummyDialect) + +namespace test { + +void DummyDialect::initialize() { addOperations<::test::dummy::FakeOp>(); } +} // namespace test + +// A test CodeGenAction to verify that we gracefully handle failure to convert +// from MLIR to LLVM IR. +class LLVMConversionFailureCodeGenAction : public CodeGenAction { +public: + LLVMConversionFailureCodeGenAction() + : CodeGenAction(BackendActionTy::Backend_EmitLL) { + mlirCtx = std::make_unique<mlir::MLIRContext>(); + mlirCtx->loadDialect<test::DummyDialect>(); + + mlir::Location loc(mlir::UnknownLoc::get(mlirCtx.get())); + mlirModule = + std::make_unique<mlir::ModuleOp>(mlir::ModuleOp::create(loc, "mod")); + + mlir::OpBuilder builder(mlirCtx.get()); + builder.setInsertionPointToStart(&mlirModule->getRegion().front()); + // Create a fake op to trip conversion to LLVM. + builder.create<test::dummy::FakeOp>(loc); + + llvmCtx = std::make_unique<llvm::LLVMContext>(); + } +}; + +TEST(CodeGenAction, GracefullyHandleLLVMConversionFailure) { + std::string diagnosticOutput; + llvm::raw_string_ostream diagnosticsOS(diagnosticOutput); + auto diagPrinter = std::make_unique<Fortran::frontend::TextDiagnosticPrinter>( + diagnosticsOS, new clang::DiagnosticOptions()); + + CompilerInstance ci; + ci.createDiagnostics(diagPrinter.get(), /*ShouldOwnClient=*/false); + ci.setInvocation(std::make_shared<CompilerInvocation>()); + ci.setOutputStream(std::make_unique<llvm::raw_null_ostream>()); + ci.getInvocation().getCodeGenOpts().OptimizationLevel = 0; + + FrontendInputFile file("/dev/null", InputKind()); + + LLVMConversionFailureCodeGenAction action; + action.setInstance(&ci); + action.setCurrentInput(file); + + consumeError(action.execute()); + ASSERT_EQ(diagnosticsOS.str(), + "error: Lowering to LLVM IR failed\n" + "error: failed to create the LLVM module\n"); +} |