[clang] 9e6b46a - [flang] Implement -mcmodel flag (#95411)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 3 10:49:46 PDT 2024
Author: David Truby
Date: 2024-07-03T18:49:42+01:00
New Revision: 9e6b46a9846cf5051c2aaef361af0fe1a76c856e
URL: https://github.com/llvm/llvm-project/commit/9e6b46a9846cf5051c2aaef361af0fe1a76c856e
DIFF: https://github.com/llvm/llvm-project/commit/9e6b46a9846cf5051c2aaef361af0fe1a76c856e.diff
LOG: [flang] Implement -mcmodel flag (#95411)
This patch implements the -mcmodel flag from clang, allowing the Code
Model to be changed for the LLVM module. The same set of mcmodel
flags are accepted as in clang and the same Code Model attributes are
added to the LLVM module for those flags.
Also add `-mlarge-data-threshold` for x86-64, which is automatically set
by the shared command-line code (see below). This is also added as an
attribute into the LLVM module and on the target machine.
A function is created for `addMCModel` that is copied out of clang's
argument handling so that it can be shared with flang.
---------
Co-authored-by: Mats Petersson <mats.petersson at arm.com>
Added:
flang/test/Driver/large-data-threshold.f90
flang/test/Driver/mcmodel.f90
flang/test/Lower/large-data-threshold.f90
flang/test/Lower/mcmodel.f90
Modified:
clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/lib/Driver/ToolChains/CommonArgs.h
clang/lib/Driver/ToolChains/Flang.cpp
flang/include/flang/Frontend/CodeGenOptions.h
flang/lib/Frontend/CodeGenOptions.cpp
flang/lib/Frontend/CompilerInstance.cpp
flang/lib/Frontend/CompilerInvocation.cpp
flang/lib/Frontend/FrontendActions.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 1ede75d3782cd..af5ed95510ceb 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4612,10 +4612,10 @@ def inline_asm_EQ : Joined<["-"], "inline-asm=">, Group<m_Group>,
NormalizedValuesScope<"CodeGenOptions">, NormalizedValues<["IAD_ATT", "IAD_Intel"]>,
MarshallingInfoEnum<CodeGenOpts<"InlineAsmDialect">, "IAD_ATT">;
def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>,
- Visibility<[ClangOption, CC1Option]>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
MarshallingInfoString<TargetOpts<"CodeModel">, [{"default"}]>;
def mlarge_data_threshold_EQ : Joined<["-"], "mlarge-data-threshold=">, Group<m_Group>,
- Flags<[TargetSpecific]>, Visibility<[ClangOption, CC1Option]>,
+ Flags<[TargetSpecific]>, Visibility<[ClangOption, CC1Option,FlangOption, FC1Option]>,
MarshallingInfoInt<TargetOpts<"LargeDataThreshold">, "0">;
def mtls_size_EQ : Joined<["-"], "mtls-size=">, Group<m_Group>,
Visibility<[ClangOption, CC1Option]>,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 27c451c565f2b..cf1767a1f644f 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5909,81 +5909,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
TC.addClangTargetOptions(Args, CmdArgs, JA.getOffloadingDeviceKind());
- if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
- StringRef CM = A->getValue();
- bool Ok = false;
- if (Triple.isOSAIX() && CM == "medium")
- CM = "large";
- if (Triple.isAArch64(64)) {
- Ok = CM == "tiny" || CM == "small" || CM == "large";
- if (CM == "large" && !Triple.isOSBinFormatMachO() &&
- RelocationModel != llvm::Reloc::Static)
- D.Diag(diag::err_drv_argument_only_allowed_with)
- << A->getAsString(Args) << "-fno-pic";
- } else if (Triple.isLoongArch()) {
- if (CM == "extreme" &&
- Args.hasFlagNoClaim(options::OPT_fplt, options::OPT_fno_plt, false))
- D.Diag(diag::err_drv_argument_not_allowed_with)
- << A->getAsString(Args) << "-fplt";
- Ok = CM == "normal" || CM == "medium" || CM == "extreme";
- // Convert to LLVM recognizable names.
- if (Ok)
- CM = llvm::StringSwitch<StringRef>(CM)
- .Case("normal", "small")
- .Case("extreme", "large")
- .Default(CM);
- } else if (Triple.isPPC64() || Triple.isOSAIX()) {
- Ok = CM == "small" || CM == "medium" || CM == "large";
- } else if (Triple.isRISCV()) {
- if (CM == "medlow")
- CM = "small";
- else if (CM == "medany")
- CM = "medium";
- Ok = CM == "small" || CM == "medium";
- } else if (Triple.getArch() == llvm::Triple::x86_64) {
- Ok = llvm::is_contained({"small", "kernel", "medium", "large", "tiny"},
- CM);
- } else if (Triple.isNVPTX() || Triple.isAMDGPU() || Triple.isSPIRV()) {
- // NVPTX/AMDGPU/SPIRV does not care about the code model and will accept
- // whatever works for the host.
- Ok = true;
- } else if (Triple.isSPARC64()) {
- if (CM == "medlow")
- CM = "small";
- else if (CM == "medmid")
- CM = "medium";
- else if (CM == "medany")
- CM = "large";
- Ok = CM == "small" || CM == "medium" || CM == "large";
- }
- if (Ok) {
- CmdArgs.push_back(Args.MakeArgString("-mcmodel=" + CM));
- } else {
- D.Diag(diag::err_drv_unsupported_option_argument_for_target)
- << A->getSpelling() << CM << TripleStr;
- }
- }
-
- if (Triple.getArch() == llvm::Triple::x86_64) {
- bool IsMediumCM = false;
- bool IsLargeCM = false;
- if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
- IsMediumCM = StringRef(A->getValue()) == "medium";
- IsLargeCM = StringRef(A->getValue()) == "large";
- }
- if (Arg *A = Args.getLastArg(options::OPT_mlarge_data_threshold_EQ)) {
- if (!IsMediumCM && !IsLargeCM) {
- D.Diag(diag::warn_drv_large_data_threshold_invalid_code_model)
- << A->getOption().getRenderName();
- } else {
- A->render(Args, CmdArgs);
- }
- } else if (IsMediumCM) {
- CmdArgs.push_back("-mlarge-data-threshold=65536");
- } else if (IsLargeCM) {
- CmdArgs.push_back("-mlarge-data-threshold=0");
- }
- }
+ addMCModel(D, Args, Triple, RelocationModel, CmdArgs);
if (Arg *A = Args.getLastArg(options::OPT_mtls_size_EQ)) {
StringRef Value = A->getValue();
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index be4d7d2cffb16..2cb152f77e501 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -2825,3 +2825,84 @@ void tools::addOffloadCompressArgs(const llvm::opt::ArgList &TCArgs,
CmdArgs.push_back(
TCArgs.MakeArgString(Twine("-compression-level=") + Arg->getValue()));
}
+
+void tools::addMCModel(const Driver &D, const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple,
+ const llvm::Reloc::Model &RelocationModel,
+ llvm::opt::ArgStringList &CmdArgs) {
+ if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
+ StringRef CM = A->getValue();
+ bool Ok = false;
+ if (Triple.isOSAIX() && CM == "medium")
+ CM = "large";
+ if (Triple.isAArch64(64)) {
+ Ok = CM == "tiny" || CM == "small" || CM == "large";
+ if (CM == "large" && !Triple.isOSBinFormatMachO() &&
+ RelocationModel != llvm::Reloc::Static)
+ D.Diag(diag::err_drv_argument_only_allowed_with)
+ << A->getAsString(Args) << "-fno-pic";
+ } else if (Triple.isLoongArch()) {
+ if (CM == "extreme" &&
+ Args.hasFlagNoClaim(options::OPT_fplt, options::OPT_fno_plt, false))
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << A->getAsString(Args) << "-fplt";
+ Ok = CM == "normal" || CM == "medium" || CM == "extreme";
+ // Convert to LLVM recognizable names.
+ if (Ok)
+ CM = llvm::StringSwitch<StringRef>(CM)
+ .Case("normal", "small")
+ .Case("extreme", "large")
+ .Default(CM);
+ } else if (Triple.isPPC64() || Triple.isOSAIX()) {
+ Ok = CM == "small" || CM == "medium" || CM == "large";
+ } else if (Triple.isRISCV()) {
+ if (CM == "medlow")
+ CM = "small";
+ else if (CM == "medany")
+ CM = "medium";
+ Ok = CM == "small" || CM == "medium";
+ } else if (Triple.getArch() == llvm::Triple::x86_64) {
+ Ok = llvm::is_contained({"small", "kernel", "medium", "large", "tiny"},
+ CM);
+ } else if (Triple.isNVPTX() || Triple.isAMDGPU() || Triple.isSPIRV()) {
+ // NVPTX/AMDGPU/SPIRV does not care about the code model and will accept
+ // whatever works for the host.
+ Ok = true;
+ } else if (Triple.isSPARC64()) {
+ if (CM == "medlow")
+ CM = "small";
+ else if (CM == "medmid")
+ CM = "medium";
+ else if (CM == "medany")
+ CM = "large";
+ Ok = CM == "small" || CM == "medium" || CM == "large";
+ }
+ if (Ok) {
+ CmdArgs.push_back(Args.MakeArgString("-mcmodel=" + CM));
+ } else {
+ D.Diag(diag::err_drv_unsupported_option_argument_for_target)
+ << A->getSpelling() << CM << Triple.getTriple();
+ }
+ }
+
+ if (Triple.getArch() == llvm::Triple::x86_64) {
+ bool IsMediumCM = false;
+ bool IsLargeCM = false;
+ if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
+ IsMediumCM = StringRef(A->getValue()) == "medium";
+ IsLargeCM = StringRef(A->getValue()) == "large";
+ }
+ if (Arg *A = Args.getLastArg(options::OPT_mlarge_data_threshold_EQ)) {
+ if (!IsMediumCM && !IsLargeCM) {
+ D.Diag(diag::warn_drv_large_data_threshold_invalid_code_model)
+ << A->getOption().getRenderName();
+ } else {
+ A->render(Args, CmdArgs);
+ }
+ } else if (IsMediumCM) {
+ CmdArgs.push_back("-mlarge-data-threshold=65536");
+ } else if (IsLargeCM) {
+ CmdArgs.push_back("-mlarge-data-threshold=0");
+ }
+ }
+}
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h
index 5581905db3114..52818ecde924b 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.h
+++ b/clang/lib/Driver/ToolChains/CommonArgs.h
@@ -223,6 +223,10 @@ void addOutlineAtomicsArgs(const Driver &D, const ToolChain &TC,
const llvm::Triple &Triple);
void addOffloadCompressArgs(const llvm::opt::ArgList &TCArgs,
llvm::opt::ArgStringList &CmdArgs);
+void addMCModel(const Driver &D, const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple,
+ const llvm::Reloc::Model &RelocationModel,
+ llvm::opt::ArgStringList &CmdArgs);
} // end namespace tools
} // end namespace driver
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 42b45dba2bd31..962a6c2c6b298 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -735,6 +735,11 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
// Add target args, features, etc.
addTargetOptions(Args, CmdArgs);
+ llvm::Reloc::Model RelocationModel =
+ std::get<0>(ParsePICArgs(getToolChain(), Args));
+ // Add MCModel information
+ addMCModel(D, Args, Triple, RelocationModel, CmdArgs);
+
// Add Codegen options
addCodegenOptions(Args, CmdArgs);
diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h
index 3bc5d93c4c43e..ac7fcbcba4f74 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.h
+++ b/flang/include/flang/Frontend/CodeGenOptions.h
@@ -133,6 +133,13 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// transformation.
OptRemark OptimizationRemarkAnalysis;
+ /// The code model to use (-mcmodel).
+ std::string CodeModel;
+
+ /// The code model-specific large data threshold to use
+ /// (-mlarge-data-threshold).
+ uint64_t LargeDataThreshold;
+
// Define accessors/mutators for code generation options of enumeration type.
#define CODEGENOPT(Name, Bits, Default)
#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \
@@ -143,6 +150,8 @@ class CodeGenOptions : public CodeGenOptionsBase {
CodeGenOptions();
};
+std::optional<llvm::CodeModel::Model> getCodeModel(llvm::StringRef string);
+
} // end namespace Fortran::frontend
#endif // FORTRAN_FRONTEND_CODEGENOPTIONS_H
diff --git a/flang/lib/Frontend/CodeGenOptions.cpp b/flang/lib/Frontend/CodeGenOptions.cpp
index a7947182decce..8a9d3c27c8bc3 100644
--- a/flang/lib/Frontend/CodeGenOptions.cpp
+++ b/flang/lib/Frontend/CodeGenOptions.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "flang/Frontend/CodeGenOptions.h"
+#include <optional>
#include <string.h>
namespace Fortran::frontend {
@@ -21,4 +22,14 @@ CodeGenOptions::CodeGenOptions() {
#include "flang/Frontend/CodeGenOptions.def"
}
+std::optional<llvm::CodeModel::Model> getCodeModel(llvm::StringRef string) {
+ return llvm::StringSwitch<std::optional<llvm::CodeModel::Model>>(string)
+ .Case("tiny", llvm::CodeModel::Model::Tiny)
+ .Case("small", llvm::CodeModel::Model::Small)
+ .Case("kernel", llvm::CodeModel::Model::Kernel)
+ .Case("medium", llvm::CodeModel::Model::Medium)
+ .Case("large", llvm::CodeModel::Model::Large)
+ .Default(std::nullopt);
+}
+
} // end namespace Fortran::frontend
diff --git a/flang/lib/Frontend/CompilerInstance.cpp b/flang/lib/Frontend/CompilerInstance.cpp
index c78137346640a..27c36b7f84d89 100644
--- a/flang/lib/Frontend/CompilerInstance.cpp
+++ b/flang/lib/Frontend/CompilerInstance.cpp
@@ -321,11 +321,19 @@ bool CompilerInstance::setUpTargetMachine() {
assert(OptLevelOrNone && "Invalid optimization level!");
llvm::CodeGenOptLevel OptLevel = *OptLevelOrNone;
std::string featuresStr = getTargetFeatures();
+ std::optional<llvm::CodeModel::Model> cm = getCodeModel(CGOpts.CodeModel);
targetMachine.reset(theTarget->createTargetMachine(
theTriple, /*CPU=*/targetOpts.cpu,
/*Features=*/featuresStr, llvm::TargetOptions(),
/*Reloc::Model=*/CGOpts.getRelocationModel(),
- /*CodeModel::Model=*/std::nullopt, OptLevel));
+ /*CodeModel::Model=*/cm, OptLevel));
assert(targetMachine && "Failed to create TargetMachine");
+ if (cm.has_value()) {
+ const llvm::Triple triple(theTriple);
+ if ((cm == llvm::CodeModel::Medium || cm == llvm::CodeModel::Large) &&
+ triple.getArch() == llvm::Triple::x86_64) {
+ targetMachine->setLargeDataThreshold(CGOpts.LargeDataThreshold);
+ }
+ }
return true;
}
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index f96d72f1ad691..e2d60ad46f14f 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -32,6 +32,7 @@
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Path.h"
@@ -386,6 +387,29 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
opts.IsPIE = 1;
}
+ // -mcmodel option.
+ if (const llvm::opt::Arg *a =
+ args.getLastArg(clang::driver::options::OPT_mcmodel_EQ)) {
+ llvm::StringRef modelName = a->getValue();
+ std::optional<llvm::CodeModel::Model> codeModel = getCodeModel(modelName);
+
+ if (codeModel.has_value())
+ opts.CodeModel = modelName;
+ else
+ diags.Report(clang::diag::err_drv_invalid_value)
+ << a->getAsString(args) << modelName;
+ }
+
+ if (const llvm::opt::Arg *arg = args.getLastArg(
+ clang::driver::options::OPT_mlarge_data_threshold_EQ)) {
+ uint64_t LDT;
+ if (llvm::StringRef(arg->getValue()).getAsInteger(/*Radix=*/10, LDT)) {
+ diags.Report(clang::diag::err_drv_invalid_value)
+ << arg->getSpelling() << arg->getValue();
+ }
+ opts.LargeDataThreshold = LDT;
+ }
+
// This option is compatible with -f[no-]underscoring in gfortran.
if (args.hasFlag(clang::driver::options::OPT_fno_underscoring,
clang::driver::options::OPT_funderscoring, false)) {
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 24db4df31279a..a85ecd1ac71b3 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -866,6 +866,17 @@ void CodeGenAction::generateLLVMIR() {
llvmModule->setPIELevel(
static_cast<llvm::PIELevel::Level>(opts.PICLevel));
}
+
+ // Set mcmodel level LLVM module flags
+ std::optional<llvm::CodeModel::Model> cm = getCodeModel(opts.CodeModel);
+ if (cm.has_value()) {
+ const llvm::Triple triple(ci.getInvocation().getTargetOpts().triple);
+ llvmModule->setCodeModel(*cm);
+ if ((cm == llvm::CodeModel::Medium || cm == llvm::CodeModel::Large) &&
+ triple.getArch() == llvm::Triple::x86_64) {
+ llvmModule->setLargeDataThreshold(opts.LargeDataThreshold);
+ }
+ }
}
static std::unique_ptr<llvm::raw_pwrite_stream>
@@ -1280,6 +1291,7 @@ void CodeGenAction::executeAction() {
// and the command-line target option if specified, or the default if not
// given on the command-line).
llvm::TargetMachine &targetMachine = ci.getTargetMachine();
+
const std::string &theTriple = targetMachine.getTargetTriple().str();
if (llvmModule->getTargetTriple() != theTriple) {
diff --git a/flang/test/Driver/large-data-threshold.f90 b/flang/test/Driver/large-data-threshold.f90
new file mode 100644
index 0000000000000..320566c4b2e43
--- /dev/null
+++ b/flang/test/Driver/large-data-threshold.f90
@@ -0,0 +1,18 @@
+! RUN: %flang -### -c --target=x86_64 -mcmodel=large -mlarge-data-threshold=32768 %s 2>&1 | FileCheck %s
+! RUN: %flang -### -c --target=x86_64 -mcmodel=large -mlarge-data-threshold=59000 %s 2>&1 | FileCheck %s --check-prefix=CHECK-59000
+! RUN: %flang -### -c --target=x86_64 -mcmodel=large -mlarge-data-threshold=1048576 %s 2>&1 | FileCheck %s --check-prefix=CHECK-1M
+! RUN: not %flang -c --target=x86_64 -mcmodel=large -mlarge-data-threshold=nonsense %s 2>&1 | FileCheck %s --check-prefix=INVALID
+! RUN: %flang -### -c --target=x86_64 -mlarge-data-threshold=32768 %s 2>&1 | FileCheck %s --check-prefix=NO-MCMODEL
+! RUN: %flang -### -c --target=x86_64 -mcmodel=small -mlarge-data-threshold=32768 %s 2>&1 | FileCheck %s --check-prefix=NO-MCMODEL
+! RUN: not %flang -### -c --target=aarch64 -mcmodel=small -mlarge-data-threshold=32768 %s 2>&1 | FileCheck %s --check-prefix=NOT-SUPPORTED
+
+
+! CHECK: "{{.*}}flang-new" "-fc1"
+! CHECK-SAME: "-mlarge-data-threshold=32768"
+! CHECK-59000: "{{.*}}flang-new" "-fc1"
+! CHECK-59000-SAME: "-mlarge-data-threshold=59000"
+! CHECK-1M: "{{.*}}flang-new" "-fc1"
+! CHECK-1M-SAME: "-mlarge-data-threshold=1048576"
+! NO-MCMODEL: 'mlarge-data-threshold=' only applies to medium and large code models
+! INVALID: error: invalid value 'nonsense' in '-mlarge-data-threshold='
+! NOT-SUPPORTED: error: unsupported option '-mlarge-data-threshold=' for target 'aarch64'
diff --git a/flang/test/Driver/mcmodel.f90 b/flang/test/Driver/mcmodel.f90
new file mode 100644
index 0000000000000..12d90ece2f24f
--- /dev/null
+++ b/flang/test/Driver/mcmodel.f90
@@ -0,0 +1,44 @@
+! RUN: not %flang -### -c --target=i686 -mcmodel=medium %s 2>&1 | FileCheck --check-prefix=ERR-MEDIUM %s
+! RUN: %flang --target=x86_64 -### -c -mcmodel=tiny %s 2>&1 | FileCheck --check-prefix=TINY %s
+! RUN: %flang --target=x86_64 -### -c -mcmodel=small %s 2>&1 | FileCheck --check-prefix=SMALL %s
+! RUN: %flang --target=x86_64 -### -S -mcmodel=kernel %s 2>&1 | FileCheck --check-prefix=KERNEL %s
+! RUN: %flang --target=x86_64 -### -c -mcmodel=medium %s 2>&1 | FileCheck --check-prefix=MEDIUM %s
+! RUN: %flang --target=x86_64 -### -S -mcmodel=large %s 2>&1 | FileCheck --check-prefix=LARGE %s
+! RUN: not %flang -### -c --target=powerpc-linux-gnu -mcmodel=medium %s 2>&1 | FileCheck --check-prefix=ERR-MEDIUM %s
+! RUN: %flang --target=powerpc-unknown-aix -### -S -mcmodel=small %s 2>&1 | FileCheck --check-prefix=SMALL %s
+! RUN: %flang --target=powerpc-unknown-aix -### -S -mcmodel=large %s 2>&1 | FileCheck --check-prefix=LARGE %s
+! RUN: %flang --target=powerpc-unknown-aix -### -S -mcmodel=medium %s 2> %t.log
+! RUN: FileCheck --check-prefix=AIX-MCMEDIUM-OVERRIDE %s < %t.log
+! RUN: not %flang -### -c -mcmodel=lager %s 2>&1 | FileCheck --check-prefix=INVALID %s
+! RUN: %flang --target=aarch64 -### -S -mcmodel=large -fno-pic %s 2>&1 | FileCheck --check-prefix=LARGE %s
+! RUN: %flang --target=aarch64-apple-macosx -### -S -mcmodel=large %s 2>&1 | FileCheck --check-prefix=LARGE %s
+! RUN: not %flang --target=aarch64 -### -S -mcmodel=large -fpic %s 2>&1 | FileCheck --check-prefix=AARCH64-PIC-LARGE %s
+! RUN: not %flang -### -c --target=aarch64 -mcmodel=medium %s 2>&1 | FileCheck --check-prefix=ERR-MEDIUM %s
+! RUN: not %flang -### -c --target=aarch64 -mcmodel=kernel %s 2>&1 | FileCheck --check-prefix=ERR-KERNEL %s
+! RUN: not %flang --target=aarch64_32-linux -### -S -mcmodel=small %s 2>&1 | FileCheck --check-prefix=ERR-AARCH64_32 %s
+! RUN: %flang --target=loongarch64 -### -S -mcmodel=normal %s 2>&1 | FileCheck --check-prefix=SMALL %s
+! RUN: %flang --target=loongarch64 -### -S -mcmodel=medium %s 2>&1 | FileCheck --check-prefix=MEDIUM %s
+! RUN: %flang --target=loongarch64 -### -S -mcmodel=extreme %s 2>&1 | FileCheck --check-prefix=LARGE %s
+! RUN: not %flang --target=loongarch64 -### -S -mcmodel=tiny %s 2>&1 | FileCheck --check-prefix=ERR-TINY %s
+! RUN: not %flang --target=loongarch64 -### -S -mcmodel=small %s 2>&1 | FileCheck --check-prefix=ERR-SMALL %s
+! RUN: not %flang --target=loongarch64 -### -S -mcmodel=kernel %s 2>&1 | FileCheck --check-prefix=ERR-KERNEL %s
+! RUN: not %flang --target=loongarch64 -### -S -mcmodel=large %s 2>&1 | FileCheck --check-prefix=ERR-LARGE %s
+
+! TINY: "-mcmodel=tiny"
+! SMALL: "-mcmodel=small"
+! KERNEL: "-mcmodel=kernel"
+! MEDIUM: "-mcmodel=medium"
+! LARGE: "-mcmodel=large"
+! AIX-MCMEDIUM-OVERRIDE: "-mcmodel=large"
+
+! INVALID: error: unsupported argument 'lager' to option '-mcmodel=' for target '{{.*}}'
+
+! ERR-TINY: error: unsupported argument 'tiny' to option '-mcmodel=' for target '{{.*}}'
+! ERR-SMALL: error: unsupported argument 'small' to option '-mcmodel=' for target '{{.*}}'
+! ERR-MEDIUM: error: unsupported argument 'medium' to option '-mcmodel=' for target '{{.*}}'
+! ERR-KERNEL: error: unsupported argument 'kernel' to option '-mcmodel=' for target '{{.*}}'
+! ERR-LARGE: error: unsupported argument 'large' to option '-mcmodel=' for target '{{.*}}'
+
+! AARCH64-PIC-LARGE: error: invalid argument '-mcmodel=large' only allowed with '-fno-pic'
+! ERR-AARCH64_32: error: unsupported argument 'small' to option '-mcmodel=' for target 'aarch64_32-unknown-linux'
+
diff --git a/flang/test/Lower/large-data-threshold.f90 b/flang/test/Lower/large-data-threshold.f90
new file mode 100644
index 0000000000000..51ddd429d770a
--- /dev/null
+++ b/flang/test/Lower/large-data-threshold.f90
@@ -0,0 +1,21 @@
+! REQUIRES: x86-registered-target
+
+! RUN: %flang_fc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -mcmodel=medium | FileCheck %s --check-prefix=IR-DEFAULT
+! RUN: %flang_fc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -mcmodel=medium -mlarge-data-threshold=200 | FileCheck %s --check-prefix=IR-CUSTOM
+! RUN: %flang_fc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -mcmodel=large -mlarge-data-threshold=200 | FileCheck %s --check-prefix=IR-CUSTOM
+! RUN: %flang_fc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -mcmodel=small -mlarge-data-threshold=200 | FileCheck %s --check-prefix=IR-SMALL
+! RUN: %flang_fc1 -triple x86_64-unknown-unknown -S %s -o - -mcmodel=medium -mlarge-data-threshold=200 | FileCheck %s --check-prefix=ASM-SMALL
+! RUN: %flang_fc1 -triple x86_64-unknown-unknown -S %s -o - -mcmodel=medium -mlarge-data-threshold=2 | FileCheck %s --check-prefix=ASM-LARGE
+
+! IR-DEFAULT: !{i32 1, !"Large Data Threshold", i64 0}
+! IR-CUSTOM: !{i32 1, !"Large Data Threshold", i64 200}
+! IR-SMALL-NOT: !"Large Data Threshold"
+
+! ASM-SMALL-NOT: movabsq
+! ASM-LARGE: movabsq
+
+function f
+ integer :: f
+ integer, save :: i
+ f = i
+end function f
diff --git a/flang/test/Lower/mcmodel.f90 b/flang/test/Lower/mcmodel.f90
new file mode 100644
index 0000000000000..dd9eb145f5e2a
--- /dev/null
+++ b/flang/test/Lower/mcmodel.f90
@@ -0,0 +1,16 @@
+! RUN: %flang_fc1 -triple aarch64 -emit-llvm -mcmodel=tiny %s -o - | FileCheck %s -check-prefix=CHECK-TINY
+! RUN: %flang_fc1 -emit-llvm -mcmodel=small %s -o - | FileCheck %s -check-prefix=CHECK-SMALL
+! RUN: %flang_fc1 -triple x86_64-unknown-linux-gnu -emit-llvm -mcmodel=kernel %s -o - | FileCheck %s -check-prefix=CHECK-KERNEL
+! RUN: %flang_fc1 -triple x86_64-unknown-linux-gnu -emit-llvm -mcmodel=medium %s -o - | FileCheck %s -check-prefix=CHECK-MEDIUM
+! RUN: %flang_fc1 -emit-llvm -mcmodel=large %s -o - | FileCheck %s -check-prefix=CHECK-LARGE
+
+! CHECK-TINY: !llvm.module.flags = !{{{.*}}}
+! CHECK-TINY: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 0}
+! CHECK-SMALL: !llvm.module.flags = !{{{.*}}}
+! CHECK-SMALL: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 1}
+! CHECK-KERNEL: !llvm.module.flags = !{{{.*}}}
+! CHECK-KERNEL: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 2}
+! CHECK-MEDIUM: !llvm.module.flags = !{{{.*}}}
+! CHECK-MEDIUM: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 3}
+! CHECK-LARGE: !llvm.module.flags = !{{{.*}}}
+! CHECK-LARGE: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 4}
More information about the cfe-commits
mailing list