[clang] [Driver] Support -mcmodel= for LoongArch (PR #72514)

Lu Weining via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 23 22:00:17 PST 2023


https://github.com/SixWeining updated https://github.com/llvm/llvm-project/pull/72514

>From 8dd5bebcd4681e5e7849743aba0ce90c2959ee23 Mon Sep 17 00:00:00 2001
From: Weining Lu <luweining at loongson.cn>
Date: Thu, 16 Nov 2023 21:57:03 +0800
Subject: [PATCH 1/2] [Driver] Support -mcmodel= for LoongArch

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
---
 clang/lib/Driver/ToolChains/Clang.cpp | 10 ++++++++++
 clang/test/Driver/mcmodel.c           | 13 +++++++++++++
 2 files changed, 23 insertions(+)

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'

>From 240149f7196c88d418d9c39c60b478b5c3aeb11c Mon Sep 17 00:00:00 2001
From: Weining Lu <luweining at loongson.cn>
Date: Fri, 24 Nov 2023 13:56:28 +0800
Subject: [PATCH 2/2] Reject small and large. Only accept normal, medium and
 extreme

---
 clang/lib/Driver/ToolChains/Clang.cpp | 16 +++++++++-------
 clang/test/Driver/mcmodel.c           |  8 ++++----
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 3a7e56f37259cb8..ad8ade737008225 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5740,15 +5740,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
         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))
+      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 == "small" || CM == "medium" || CM == "large";
+      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()) {
diff --git a/clang/test/Driver/mcmodel.c b/clang/test/Driver/mcmodel.c
index 72be740216a81b3..1eb6ae16ff472d9 100644
--- a/clang/test/Driver/mcmodel.c
+++ b/clang/test/Driver/mcmodel.c
@@ -15,14 +15,13 @@
 // 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=small %s 2>&1 | FileCheck --check-prefix=ERR-SMALL %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=large %s 2>&1 | FileCheck --check-prefix=ERR-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"
@@ -34,7 +33,8 @@
 
 // INVALID: error: unsupported argument 'lager' to option '-mcmodel=' for target '{{.*}}'
 
-// ERR-TINY: error: unsupported argument 'tiny' 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 '{{.*}}'



More information about the cfe-commits mailing list