[Driver] Reject unsupported -mcmodel= (#70262)

-mcmodel= is supported for a few architectures. Reject the option for
other architectures.

* -mcmodel= is unsupported on x86-32.
* -mcmodel=large is unsupported for PIC on AArch64.
* -mcmodel= is unsupported for aarch64_32 triples.
* https://reviews.llvm.org/D67066 (for RISC-V) made
-mcmodel=medany/-mcmodel=medlow aliases for all architectures. Restrict
this to RISC-V.
* llvm/lib/Target/Sparc has some small/medium/large support, but the
values listed on https://gcc.gnu.org/onlinedocs/gcc/SPARC-Options.html
had been supported before https://reviews.llvm.org/D67066. Consider
-mcmodel= unsupported for Sparc.
* https://reviews.llvm.org/D106371 translated -mcmodel=medium to
-mcmodel=large on AIX, even for 32-bit systems. Retain this behavior but
reject -mcmodel= for other PPC32 systems.

In general the accept/reject behavior is more similar to GCC.

err_drv_invalid_argument_to_option is less clear than
err_drv_unsupported_option_argument. As the supported values are
different for
different architectures, add a
err_drv_unsupported_option_argument_for_target
for better clarity.
This commit is contained in:
Fangrui Song 2023-10-26 14:15:36 -07:00 committed by GitHub
parent cf0f6a1460
commit 7e42545524
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 39 additions and 35 deletions

View File

@ -20,6 +20,8 @@ def err_drv_unsupported_opt_for_language_mode : Error<
"unsupported option '%0' for language mode '%1'">;
def err_drv_unsupported_option_argument : Error<
"unsupported argument '%1' to option '%0'">;
def err_drv_unsupported_option_argument_for_target : Error<
"unsupported argument '%1' to option '%0' for target '%2'">;
def err_drv_unknown_stdin_type : Error<
"-E or -x required when input is from standard input">;
def err_drv_unknown_stdin_type_clang_cl : Error<

View File

@ -4480,14 +4480,6 @@ def msave_restore : Flag<["-"], "msave-restore">, Group<m_riscv_Features_Group>,
def mno_save_restore : Flag<["-"], "mno-save-restore">, Group<m_riscv_Features_Group>,
HelpText<"Disable using library calls for save and restore">;
} // let Flags = [TargetSpecific]
def mcmodel_EQ_medlow : Flag<["-"], "mcmodel=medlow">, Group<m_Group>,
Visibility<[ClangOption, CC1Option]>,
Alias<mcmodel_EQ>, AliasArgs<["small"]>,
HelpText<"Equivalent to -mcmodel=small, compatible with RISC-V gcc.">;
def mcmodel_EQ_medany : Flag<["-"], "mcmodel=medany">, Group<m_Group>,
Visibility<[ClangOption, CC1Option]>,
Alias<mcmodel_EQ>, AliasArgs<["medium"]>,
HelpText<"Equivalent to -mcmodel=medium, compatible with RISC-V gcc.">;
let Flags = [TargetSpecific] in {
def menable_experimental_extensions : Flag<["-"], "menable-experimental-extensions">, Group<m_Group>,
HelpText<"Enable use of experimental RISC-V extensions.">;

View File

@ -5722,18 +5722,33 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
StringRef CM = A->getValue();
if (CM == "small" || CM == "kernel" || CM == "medium" || CM == "large" ||
CM == "tiny") {
if (Triple.isOSAIX() && CM == "medium")
CmdArgs.push_back("-mcmodel=large");
else if (Triple.isAArch64() && (CM == "kernel" || CM == "medium"))
D.Diag(diag::err_drv_invalid_argument_to_option)
<< CM << A->getOption().getName();
else
A->render(Args, CmdArgs);
bool Ok = false;
if (Triple.isOSAIX() && CM == "medium") {
CM = "large";
Ok = true;
}
if (Triple.isAArch64(64)) {
Ok = CM == "tiny" || CM == "small" || CM == "large";
if (CM == "large" && RelocationModel != llvm::Reloc::Static)
D.Diag(diag::err_drv_argument_only_allowed_with)
<< A->getAsString(Args) << "-fno-pic";
} else if (Triple.isPPC64()) {
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);
}
if (Ok) {
CmdArgs.push_back(Args.MakeArgString("-mcmodel=" + CM));
} else {
D.Diag(diag::err_drv_invalid_argument_to_option)
<< CM << A->getOption().getName();
D.Diag(diag::err_drv_unsupported_option_argument_for_target)
<< A->getSpelling() << CM << TripleStr;
}
}

View File

@ -27,8 +27,6 @@
// RUN: | FileCheck %s -check-prefix=RV64-ANDROID
// RUN: %clang --target=riscv64-unknown-elf %s -S -emit-llvm -fpic -o - \
// RUN: | FileCheck %s -check-prefix=RV64-PIC
// RUN: %clang --target=riscv64-unknown-elf %s -S -emit-llvm -mcmodel=large -o - \
// RUN: | FileCheck %s -check-prefix=RV64-LARGE
void test(void) {}

View File

@ -1,14 +1,18 @@
// RUN: not %clang -### -c --target=i686 -mcmodel=medium %s 2>&1 | FileCheck --check-prefix=ERR-MEDIUM %s
// RUN: %clang --target=x86_64 -### -c -mcmodel=tiny %s 2>&1 | FileCheck --check-prefix=TINY %s
// RUN: %clang --target=x86_64 -### -c -mcmodel=small %s 2>&1 | FileCheck --check-prefix=SMALL %s
// RUN: %clang --target=x86_64 -### -S -mcmodel=kernel %s 2>&1 | FileCheck --check-prefix=KERNEL %s
// RUN: %clang --target=x86_64 -### -c -mcmodel=medium %s 2>&1 | FileCheck --check-prefix=MEDIUM %s
// RUN: %clang --target=x86_64 -### -S -mcmodel=large %s 2>&1 | FileCheck --check-prefix=LARGE %s
// RUN: not %clang -### -c --target=powerpc-linux-gnu -mcmodel=medium %s 2>&1 | FileCheck --check-prefix=ERR-MEDIUM %s
// RUN: %clang --target=powerpc-unknown-aix -### -S -mcmodel=medium %s 2> %t.log
// RUN: FileCheck --check-prefix=AIX-MCMEDIUM-OVERRIDE %s < %t.log
// RUN: not %clang -### -c -mcmodel=lager %s 2>&1 | FileCheck --check-prefix=INVALID %s
// RUN: %clang --target=aarch64 -### -S -mcmodel=large -fno-pic %s 2>&1 | FileCheck --check-prefix=LARGE %s
// RUN: not %clang --target=aarch64 -### -S -mcmodel=large -fpic %s 2>&1 | FileCheck --check-prefix=AARCH64-PIC-LARGE %s
// RUN: not %clang -### -c --target=aarch64 -mcmodel=medium %s 2>&1 | FileCheck --check-prefix=ERR-MEDIUM %s
// RUN: not %clang -### -c --target=aarch64 -mcmodel=kernel %s 2>&1 | FileCheck --check-prefix=ERR-KERNEL %s
// RUN: not %clang --target=aarch64_32-linux -### -S -mcmodel=small %s 2>&1 | FileCheck --check-prefix=ERR-AARCH64_32 %s
// TINY: "-mcmodel=tiny"
// SMALL: "-mcmodel=small"
@ -17,7 +21,11 @@
// LARGE: "-mcmodel=large"
// AIX-MCMEDIUM-OVERRIDE: "-mcmodel=large"
// INVALID: error: invalid argument 'lager' to -mcmodel=
// INVALID: error: unsupported argument 'lager' to option '-mcmodel=' for target '{{.*}}'
// ERR-MEDIUM: error: invalid argument 'medium' to -mcmodel=
// ERR-KERNEL: error: invalid argument 'kernel' to -mcmodel=
// 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'

View File

@ -2,11 +2,3 @@
// RUN: %clang -S --target=riscv32-unknown-elf -fpic -msmall-data-limit=8 %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-PIC-SDATA %s
// CHECK-PIC-SDATA: warning: ignoring '-msmall-data-limit=' with -mcmodel=large for -fpic or RV64
// RUN: %clang -S --target=riscv64-unknown-elf -mcmodel=large -msmall-data-limit=8 %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-RV64-LARGE-SDATA %s
// CHECK-RV64-LARGE-SDATA: warning: ignoring '-msmall-data-limit=' with -mcmodel=large for -fpic or RV64
// RUN: %clang -S --target=riscv64-linux-android -msmall-data-limit=8 %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-RV64-LARGE-SDATA-ANDROID %s
// CHECK-RV64-LARGE-SDATA-ANDROID: warning: ignoring '-msmall-data-limit=' with -mcmodel=large for -fpic or RV64

View File

@ -802,9 +802,6 @@
// X86_64H:#define __x86_64h 1
// X86_64H:#define __x86_64h__ 1
// RUN: %clang -xc - -E -dM -mcmodel=medium --target=i386-unknown-linux < /dev/null | FileCheck -match-full-lines -check-prefix X86_MEDIUM %s
// X86_MEDIUM:#define __code_model_medium__ 1
// RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=x86_64-none-none-gnux32 < /dev/null | FileCheck -match-full-lines -check-prefix X32 %s
// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=x86_64-none-none-gnux32 < /dev/null | FileCheck -match-full-lines -check-prefix X32 -check-prefix X32-CXX %s
//