diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -34,6 +34,7 @@ #include "mlir/IR/Dialect.h" #include "mlir/Parser/Parser.h" #include "mlir/Pass/PassManager.h" +#include "mlir/Support/LLVM.h" #include "mlir/Target/LLVMIR/ModuleTranslation.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticFrontend.h" @@ -564,11 +565,14 @@ void CodeGenAction::setUpTargetMachine() { CompilerInstance &ci = this->getInstance(); - // Set the triple based on the CompilerInvocation set-up const std::string &theTriple = ci.getInvocation().getTargetOpts().triple; - if (llvmModule->getTargetTriple() != theTriple) { - ci.getDiagnostics().Report(clang::diag::warn_fe_override_module) - << theTriple; + + // Set the triple based on the CompilerInvocation set-up + if (llvmModule) { + if (llvmModule->getTargetTriple() != theTriple) { + ci.getDiagnostics().Report(clang::diag::warn_fe_override_module) + << theTriple; + } llvmModule->setTargetTriple(theTriple); } @@ -697,6 +701,13 @@ mpm.run(*llvmModule, mam); } +static void setMLIRDataLayout(mlir::ModuleOp &mlirModule, + const llvm::DataLayout &dl) { + mlirModule->setAttr(mlir::LLVM::LLVMDialect::getDataLayoutAttrName(), + mlir::StringAttr::get(mlirModule.getContext(), + dl.getStringRepresentation())); +} + void CodeGenAction::executeAction() { CompilerInstance &ci = this->getInstance(); @@ -728,12 +739,20 @@ mlirModule->print(ci.isOutputStreamNull() ? *os : ci.getOutputStream()); return; } + setUpTargetMachine(); + if (mlirModule) { + const llvm::DataLayout &dl = tm->createDataLayout(); + setMLIRDataLayout(*mlirModule, dl); + } // Generate an LLVM module if it's not already present (it will already be // present if the input file is an LLVM IR/BC file). if (!llvmModule) generateLLVMIR(); + if (llvmModule->getDataLayout().isDefault()) { + llvmModule->setDataLayout(tm->createDataLayout()); + } // Run LLVM's middle-end (i.e. the optimizer). runOptimizationPipeline(*os); @@ -743,9 +762,6 @@ return; } - setUpTargetMachine(); - llvmModule->setDataLayout(tm->createDataLayout()); - if (action == BackendActionTy::Backend_EmitBC) { // This action has effectively been completed in runOptimizationPipeline. return; diff --git a/flang/test/Driver/emit-llvm.f90 b/flang/test/Driver/emit-llvm.f90 --- a/flang/test/Driver/emit-llvm.f90 +++ b/flang/test/Driver/emit-llvm.f90 @@ -6,6 +6,7 @@ ! RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s ! CHECK: ; ModuleID = 'FIRModule' +! CHECK: target datalayout = ! CHECK: define void @_QQmain() ! CHECK-NEXT: ret void ! CHECK-NEXT: } diff --git a/flang/test/Driver/pic-flags.f90 b/flang/test/Driver/pic-flags.f90 --- a/flang/test/Driver/pic-flags.f90 +++ b/flang/test/Driver/pic-flags.f90 @@ -1,3 +1,4 @@ +! REQUIRES: aarch64-registered-target && x86-registered-target && arm-registered-target ! RUN: %flang -v -S -emit-llvm -o - %s --target=aarch64-linux-gnu -fno-pie 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-STATIC,CHECK-STATIC-IR ! RUN: %flang -v -S -emit-llvm -o - %s --target=aarch64-linux-gnu 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-PIE-LEVEL2,CHECK-PIE-LEVEL2-IR @@ -14,7 +15,6 @@ ! RUN: %flang -v -### -o - %s --target=arm-none-eabi -frwpi 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-RWPI ! RUN: %flang -v -### -o - %s --target=arm-none-eabi -fropi -frwpi 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-ROPI-RWPI - ! CHECK: -fc1 diff --git a/flang/unittests/Frontend/FrontendActionTest.cpp b/flang/unittests/Frontend/FrontendActionTest.cpp --- a/flang/unittests/Frontend/FrontendActionTest.cpp +++ b/flang/unittests/Frontend/FrontendActionTest.cpp @@ -178,6 +178,11 @@ compInst.getInvocation().getTargetOpts().triple = llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple()); + // Initialise LLVM backend + llvm::InitializeAllTargets(); + llvm::InitializeAllTargetMCs(); + llvm::InitializeAllAsmPrinters(); + // Set-up the output stream. We are using output buffer wrapped as an output // stream, as opposed to an actual file (or a file descriptor). llvm::SmallVector outputFileBuffer;