From 2ff5b258a9972efa42107382f9f5be98a188f7e7 Mon Sep 17 00:00:00 2001
From: Paul Kirth <pk1574@gmail.com>
Date: Mon, 22 Jan 2024 18:42:25 +0000
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
 =?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.4
---
 clang/include/clang/Basic/CodeGenOptions.def |  3 +++
 clang/include/clang/Basic/CodeGenOptions.h   |  5 +++++
 clang/include/clang/Driver/Options.td        |  7 +++++++
 clang/lib/CodeGen/BackendUtil.cpp            |  2 ++
 clang/lib/Driver/ToolChains/Clang.cpp        |  8 ++++++++
 clang/test/Driver/tls-dialect.c              | 15 +++++++++++++++
 6 files changed, 40 insertions(+)
 create mode 100644 clang/test/Driver/tls-dialect.c

diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 2c4fb6745bc17..6b96764b215be 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -359,6 +359,9 @@ ENUM_CODEGENOPT(VecLib, llvm::driver::VectorLibrary, 3, llvm::driver::VectorLibr
 /// The default TLS model to use.
 ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
 
+/// The default TLS model to use.
+ENUM_CODEGENOPT(DefaultTLSDialect, TLSDialect, 2, TraditionalTLSDialect)
+
 /// Bit size of immediate TLS offsets (0 == use the default).
 VALUE_CODEGENOPT(TLSSize, 8, 0)
 
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index 6952b48e898a8..23180ababa956 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -72,6 +72,11 @@ class CodeGenOptions : public CodeGenOptionsBase {
     LocalExecTLSModel
   };
 
+  enum TLSDialect {
+    TraditionalTLSDialect,
+    TLSDescTLSDialect,
+  };
+
   enum StructReturnConventionKind {
     SRCK_Default,  // No special option was passed.
     SRCK_OnStack,  // Small structs on the stack (-fpcc-struct-return).
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index d2e6c3ff721c2..e0923dc2b5469 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4403,6 +4403,13 @@ def mtls_size_EQ : Joined<["-"], "mtls-size=">, Group<m_Group>,
   HelpText<"Specify bit size of immediate TLS offsets (AArch64 ELF only): "
            "12 (for 4KB) | 24 (for 16MB, default) | 32 (for 4GB) | 48 (for 256TB, needs -mcmodel=large)">,
   MarshallingInfoInt<CodeGenOpts<"TLSSize">>;
+def mtls_dialect_EQ : Joined<["-"], "mtls-dialect=">, Group<m_Group>,
+  Visibility<[ClangOption, CC1Option]>,
+  HelpText<"Use the given thread-local storage dialect">,
+  Values<"trad,desc">,
+  NormalizedValuesScope<"CodeGenOptions">,
+  NormalizedValues<["TraditionalTLSDialect", "TLSDescTLSDialect"]>,
+  MarshallingInfoEnum<CodeGenOpts<"DefaultTLSDialect">, "TraditionalTLSDialect">;
 def mimplicit_it_EQ : Joined<["-"], "mimplicit-it=">, Group<m_Group>;
 def mdefault_build_attributes : Joined<["-"], "mdefault-build-attributes">, Group<m_Group>;
 def mno_default_build_attributes : Joined<["-"], "mno-default-build-attributes">, Group<m_Group>;
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index a6142d99f3b68..0ab8156ab1f94 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -401,6 +401,8 @@ static bool initTargetOptions(DiagnosticsEngine &Diags,
   Options.UniqueBasicBlockSectionNames =
       CodeGenOpts.UniqueBasicBlockSectionNames;
   Options.TLSSize = CodeGenOpts.TLSSize;
+  // TODO: Add correct codegen options in LLVM
+  // Options.TLSDesc = CodeGenOpts.getDefaultTLSDialect();
   Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;
   Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning();
   Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index fead2e884030e..232b7c48d56b2 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5812,6 +5812,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
     Args.AddLastArg(CmdArgs, options::OPT_mtls_size_EQ);
   }
 
+  if (Arg *A = Args.getLastArg(options::OPT_mtls_dialect_EQ)) {
+    // mlts-dialect= is ELF only
+    if (!Triple.isOSBinFormatELF())
+      D.Diag(diag::err_drv_unsupported_opt_for_target)
+          << A->getOption().getName() << TripleStr;
+    Args.AddLastArg(CmdArgs, options::OPT_mtls_dialect_EQ);
+  }
+
   // Add the target cpu
   std::string CPU = getCPUName(D, Args, Triple, /*FromAs*/ false);
   if (!CPU.empty()) {
diff --git a/clang/test/Driver/tls-dialect.c b/clang/test/Driver/tls-dialect.c
new file mode 100644
index 0000000000000..42bf9ef42b0aa
--- /dev/null
+++ b/clang/test/Driver/tls-dialect.c
@@ -0,0 +1,15 @@
+/// Options for ELF
+// RUN: %clang -### -target aarch64-linux-gnu -mtls-dialect=trad %s 2>&1 | FileCheck -check-prefix=TRAD %s
+// RUN: %clang -### -target aarch64-linux-gnu -mtls-dialect=desc %s 2>&1 | FileCheck -check-prefix=DESC %s
+
+/// Unsupported target
+// RUN: not %clang -target aarch64-unknown-windows-msvc -mtls-dialect=trad %s 2>&1 | FileCheck -check-prefix=UNSUPPORTED-TARGET %s
+// RUN: not %clang -target aarch64-unknown-windows-msvc -mtls-dialect=desc %s 2>&1 | FileCheck -check-prefix=UNSUPPORTED-TARGET %s
+
+/// Invalid option value
+// RUN: not %clang -target x86_64-linux-gnu -mtls-dialect=foo %s 2>&1 | FileCheck -check-prefix=INVALID-VALUE %s
+
+// TRAD: "-cc1" {{.*}}"-mtls-dialect=trad"
+// DESC: "-cc1" {{.*}}"-mtls-dialect=desc"
+// UNSUPPORTED-TARGET: error: unsupported option
+// INVALID-VALUE: error: invalid value 'foo' in '-mtls-dialect=foo'