Skip to content

[Driver] Support -mcmodel= for LoongArch #72514

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 30, 2023

Conversation

SixWeining
Copy link
Contributor

@SixWeining SixWeining commented Nov 16, 2023

7e42545 rejects unsupported mcmodel options, but normal/medium/extreme should be supported models for LoongArch according to gcc document.

The mappings among gcc, clang driver, clang cc1 and LLVM (i.e. llc --code-model=) are:

gcc clang driver clang cc1 LLVM
normal normal small small
medium medium medium medium
extreme extreme large large

Link: https://reviews.llvm.org/D150522

7e42545 rejects unsupported mcmodel options, but small/medium/large
should be supported models for LoongArch. In addition, to be compatible
with gcc, mapping some of their values to clang's.

The mapping is:
     gcc[1]     vs     clang[2]
   "normal"            "small"
   "medium"            "medium"
   "extreme"           "large"

And AFAIK, gcc side doesn't plan to implement the "large" code model.

[1]: https://gcc.gnu.org/onlinedocs/gcc/LoongArch-Options.html
[2]: https://reviews.llvm.org/D150522
@SixWeining SixWeining requested a review from MaskRay November 16, 2023 14:17
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labels Nov 16, 2023
@llvmbot
Copy link
Member

llvmbot commented Nov 16, 2023

@llvm/pr-subscribers-clang-driver

Author: Lu Weining (SixWeining)

Changes

7e42545 rejects unsupported mcmodel options, but small/medium/large should be supported models for LoongArch. In addition, to be compatible with gcc, mapping some of their values to clang's.

The mapping is:

     gcc          vs     clang
   "normal"            "small"
   "medium"            "medium"
   "extreme"           "large"

And AFAIK, gcc side doesn't plan to implement the "large" code model.

Link: https://gcc.gnu.org/onlinedocs/gcc/LoongArch-Options.html
Link: https://reviews.llvm.org/D150522


Full diff: https://github.com/llvm/llvm-project/pull/72514.diff

2 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+10)
  • (modified) clang/test/Driver/mcmodel.c (+13)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index b462f5a44057d94..3a7e56f37259cb8 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5739,6 +5739,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
       if (CM == "large" && RelocationModel != llvm::Reloc::Static)
         D.Diag(diag::err_drv_argument_only_allowed_with)
             << A->getAsString(Args) << "-fno-pic";
+    } else if (Triple.isLoongArch()) {
+      CM = llvm::StringSwitch<StringRef>(CM)
+               .Case("normal", "small")
+               .Case("extreme", "large")
+               .Default(CM);
+      if (CM == "large" &&
+          Args.hasFlag(options::OPT_fplt, options::OPT_fno_plt, false))
+        D.Diag(diag::err_drv_argument_not_allowed_with)
+            << A->getAsString(Args) << "-fplt";
+      Ok = CM == "small" || CM == "medium" || CM == "large";
     } else if (Triple.isPPC64() || Triple.isOSAIX()) {
       Ok = CM == "small" || CM == "medium" || CM == "large";
     } else if (Triple.isRISCV()) {
diff --git a/clang/test/Driver/mcmodel.c b/clang/test/Driver/mcmodel.c
index d8a41b0f5abd9aa..72be740216a81b3 100644
--- a/clang/test/Driver/mcmodel.c
+++ b/clang/test/Driver/mcmodel.c
@@ -15,6 +15,15 @@
 // 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
+// RUN: %clang --target=loongarch64 -### -S -mcmodel=small %s 2>&1 | FileCheck --check-prefix=SMALL %s
+// RUN: %clang --target=loongarch64 -### -S -mcmodel=normal %s 2>&1 | FileCheck --check-prefix=SMALL %s
+// RUN: %clang --target=loongarch64 -### -S -mcmodel=medium %s 2>&1 | FileCheck --check-prefix=MEDIUM %s
+// RUN: %clang --target=loongarch64 -### -S -mcmodel=large %s 2>&1 | FileCheck --check-prefix=LARGE %s
+// RUN: %clang --target=loongarch64 -### -S -mcmodel=extreme %s 2>&1 | FileCheck --check-prefix=LARGE %s
+// RUN: not %clang --target=loongarch64 -### -S -mcmodel=tiny %s 2>&1 | FileCheck --check-prefix=ERR-TINY %s
+// RUN: not %clang --target=loongarch64 -### -S -mcmodel=kernel %s 2>&1 | FileCheck --check-prefix=ERR-KERNEL %s
+// RUN: not %clang --target=loongarch64 -### -S -mcmodel=large -fplt %s 2>&1 | FileCheck --check-prefix=ERR-LOONGARCH64-PLT-LARGE %s
+// RUN: not %clang --target=loongarch64 -### -S -mcmodel=extreme -fplt %s 2>&1 | FileCheck --check-prefix=ERR-LOONGARCH64-PLT-EXTREME %s
 
 // TINY: "-mcmodel=tiny"
 // SMALL: "-mcmodel=small"
@@ -25,9 +34,13 @@
 
 // INVALID: error: unsupported argument 'lager' to option '-mcmodel=' for target '{{.*}}'
 
+// ERR-TINY: error: unsupported argument 'tiny' 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'
+
+// ERR-LOONGARCH64-PLT-LARGE: error: invalid argument '-mcmodel=large' not allowed with '-fplt'
+// ERR-LOONGARCH64-PLT-EXTREME: error: invalid argument '-mcmodel=extreme' not allowed with '-fplt'

@llvmbot
Copy link
Member

llvmbot commented Nov 16, 2023

@llvm/pr-subscribers-clang

Author: Lu Weining (SixWeining)

Changes

7e42545 rejects unsupported mcmodel options, but small/medium/large should be supported models for LoongArch. In addition, to be compatible with gcc, mapping some of their values to clang's.

The mapping is:

     gcc          vs     clang
   "normal"            "small"
   "medium"            "medium"
   "extreme"           "large"

And AFAIK, gcc side doesn't plan to implement the "large" code model.

Link: https://gcc.gnu.org/onlinedocs/gcc/LoongArch-Options.html
Link: https://reviews.llvm.org/D150522


Full diff: https://github.com/llvm/llvm-project/pull/72514.diff

2 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+10)
  • (modified) clang/test/Driver/mcmodel.c (+13)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index b462f5a44057d94..3a7e56f37259cb8 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5739,6 +5739,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
       if (CM == "large" && RelocationModel != llvm::Reloc::Static)
         D.Diag(diag::err_drv_argument_only_allowed_with)
             << A->getAsString(Args) << "-fno-pic";
+    } else if (Triple.isLoongArch()) {
+      CM = llvm::StringSwitch<StringRef>(CM)
+               .Case("normal", "small")
+               .Case("extreme", "large")
+               .Default(CM);
+      if (CM == "large" &&
+          Args.hasFlag(options::OPT_fplt, options::OPT_fno_plt, false))
+        D.Diag(diag::err_drv_argument_not_allowed_with)
+            << A->getAsString(Args) << "-fplt";
+      Ok = CM == "small" || CM == "medium" || CM == "large";
     } else if (Triple.isPPC64() || Triple.isOSAIX()) {
       Ok = CM == "small" || CM == "medium" || CM == "large";
     } else if (Triple.isRISCV()) {
diff --git a/clang/test/Driver/mcmodel.c b/clang/test/Driver/mcmodel.c
index d8a41b0f5abd9aa..72be740216a81b3 100644
--- a/clang/test/Driver/mcmodel.c
+++ b/clang/test/Driver/mcmodel.c
@@ -15,6 +15,15 @@
 // 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
+// RUN: %clang --target=loongarch64 -### -S -mcmodel=small %s 2>&1 | FileCheck --check-prefix=SMALL %s
+// RUN: %clang --target=loongarch64 -### -S -mcmodel=normal %s 2>&1 | FileCheck --check-prefix=SMALL %s
+// RUN: %clang --target=loongarch64 -### -S -mcmodel=medium %s 2>&1 | FileCheck --check-prefix=MEDIUM %s
+// RUN: %clang --target=loongarch64 -### -S -mcmodel=large %s 2>&1 | FileCheck --check-prefix=LARGE %s
+// RUN: %clang --target=loongarch64 -### -S -mcmodel=extreme %s 2>&1 | FileCheck --check-prefix=LARGE %s
+// RUN: not %clang --target=loongarch64 -### -S -mcmodel=tiny %s 2>&1 | FileCheck --check-prefix=ERR-TINY %s
+// RUN: not %clang --target=loongarch64 -### -S -mcmodel=kernel %s 2>&1 | FileCheck --check-prefix=ERR-KERNEL %s
+// RUN: not %clang --target=loongarch64 -### -S -mcmodel=large -fplt %s 2>&1 | FileCheck --check-prefix=ERR-LOONGARCH64-PLT-LARGE %s
+// RUN: not %clang --target=loongarch64 -### -S -mcmodel=extreme -fplt %s 2>&1 | FileCheck --check-prefix=ERR-LOONGARCH64-PLT-EXTREME %s
 
 // TINY: "-mcmodel=tiny"
 // SMALL: "-mcmodel=small"
@@ -25,9 +34,13 @@
 
 // INVALID: error: unsupported argument 'lager' to option '-mcmodel=' for target '{{.*}}'
 
+// ERR-TINY: error: unsupported argument 'tiny' 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'
+
+// ERR-LOONGARCH64-PLT-LARGE: error: invalid argument '-mcmodel=large' not allowed with '-fplt'
+// ERR-LOONGARCH64-PLT-EXTREME: error: invalid argument '-mcmodel=extreme' not allowed with '-fplt'

@SixWeining
Copy link
Contributor Author

cc @xen0n @xry111

@xry111
Copy link
Contributor

xry111 commented Nov 16, 2023

And AFAIK, gcc side doesn't plan to implement the "large" code model.

Why did we distinguish "large" and "extreme" in the first place? If we don't need a different "large" code model then I guess we should make it an alias of "extreme" for GCC too.

@SixWeining
Copy link
Contributor Author

And AFAIK, gcc side doesn't plan to implement the "large" code model.

Why did we distinguish "large" and "extreme" in the first place? If we don't need a different "large" code model then I guess we should make it an alias of "extreme" for GCC too.

@ChenghuaXu @chenglulu326 What do you think?

.Case("extreme", "large")
.Default(CM);
if (CM == "large" &&
Args.hasFlag(options::OPT_fplt, options::OPT_fno_plt, false))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I consider -fno-pic/-fpic a more fundamental difference than -mcmodel=, so I place the aarch64 compatibility check in this large if condition.

-mcmodel= is a more fundamental difference than -fplt, so the -fplt compatibility check should probably belong to -fplt. You can move

if (Args.hasFlag(options::OPT_fno_plt, options::OPT_fplt, false)) {

below CodeModel check and add the diagnostic there.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nvm. this is fine

.Case("extreme", "large")
.Default(CM);
if (CM == "large" &&
Args.hasFlag(options::OPT_fplt, options::OPT_fno_plt, false))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hasFlagNoClaim is slightly better

@MaskRay
Copy link
Member

MaskRay commented Nov 22, 2023

gcc.gnu.org/onlinedocs/gcc/LoongArch-Options.html says

‘large (Not implemented yet)’
‘extreme’
This mode does not limit the size of the code segment and data segment. The -mcmodel=extreme option is incompatible with -fplt, and it requires -mexplicit-relocs=always.

Is there a psABI defining 'extreme' or 'large'?

@@ -15,6 +15,15 @@
// 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
// RUN: %clang --target=loongarch64 -### -S -mcmodel=small %s 2>&1 | FileCheck --check-prefix=SMALL %s
// RUN: %clang --target=loongarch64 -### -S -mcmodel=normal %s 2>&1 | FileCheck --check-prefix=SMALL %s
Copy link
Member

@MaskRay MaskRay Nov 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If -mcmodel=normal is canonical, we probably should not add Clang-specific alias small. Reject small.

@SixWeining
Copy link
Contributor Author

gcc.gnu.org/onlinedocs/gcc/LoongArch-Options.html says

‘large (Not implemented yet)’ ‘extreme’ This mode does not limit the size of the code segment and data segment. The -mcmodel=extreme option is incompatible with -fplt, and it requires -mexplicit-relocs=always.

Is there a psABI defining 'extreme' or 'large'?

Currently there is no definition in psABI except in gcc doc: https://gcc.gnu.org/onlinedocs/gcc/LoongArch-Options.html. Maybe we can define them in next psABI version.

@zjiaz
Copy link

zjiaz commented Nov 30, 2023

FWIW, mcmodel=medium option is used in chromium's build config file, and now chromium's llvm toolchain has been affected by this issue:

clang++: error: unsupported argument 'medium' to option '-mcmodel=' for target 'loongarch64-unknown-linux-gnu'

Copy link
Contributor

@wangleiat wangleiat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@MaskRay
Copy link
Member

MaskRay commented Dec 1, 2023

LGTM

leecheechen pushed a commit to leecheechen/llvm-project that referenced this pull request Jun 9, 2025
7e42545 rejects unsupported mcmodel options, but normal/medium/extreme
should be supported models for LoongArch according to [gcc
document](https://gcc.gnu.org/onlinedocs/gcc/LoongArch-Options.html).

The mappings among `gcc`, `clang driver`, `clang cc1` and `LLVM (i.e.
llc --code-model=)` are:

|     gcc      |  clang driver |  clang cc1   |    LLVM    |
| -------------  | ------------------ | ----------------- | -------------- |
| normal    |      normal     |   small        |    small    |
| medium  |     medium     |   medium    |    medium |
| extreme  |     extreme     |  large         |     large     |

(cherry picked from commit 1296d20)

Change-Id: I45837ad55bfedaf33a7fc9bc40a654a37694ced0
leecheechen pushed a commit to leecheechen/llvm-project that referenced this pull request Jun 9, 2025
R_LARCH_DELETE and R_LARCH_CFA are marked as reserved in psABI v2.20[1].

This patch copys the changes from an upstream commit. The original
patch link is as below[2].

[1]https://github.com/loongson/la-abi-specs/releases/download/v2.20/la-abi-v2.20.pdf
[2]llvm#72514

(cherry picked from commit 2cdfabe)

Change-Id: I6c01a03d46d7f1b622258403a8863e33ddf8d36d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants