diff --git a/0003-PATCH-Make-funwind-tables-the-default-on-all-archs.patch b/0001-PATCH-clang-Make-funwind-tables-the-default-on-all-a.patch similarity index 61% rename from 0003-PATCH-Make-funwind-tables-the-default-on-all-archs.patch rename to 0001-PATCH-clang-Make-funwind-tables-the-default-on-all-a.patch index ce920f93e16c7682656af55392cc03dbc1e55c2d..113f2a7b8dc6f87615da6b7312c431197a23eeae 100644 --- a/0003-PATCH-Make-funwind-tables-the-default-on-all-archs.patch +++ b/0001-PATCH-clang-Make-funwind-tables-the-default-on-all-a.patch @@ -1,21 +1,20 @@ -From d95d3fbff661c0390072ed0bb4544d5e2aae5c9a Mon Sep 17 00:00:00 2001 -From: serge-sans-paille -Date: Thu, 25 Feb 2021 14:09:29 +0100 +From 49f827b09db549de62dcaf8b90b3fcb3e08c0ee5 Mon Sep 17 00:00:00 2001 +From: Serge Guelton +Date: Mon, 6 Mar 2023 12:37:48 +0100 Subject: [PATCH] Make -funwind-tables the default on all archs --- - clang/lib/Driver/ToolChains/Gnu.cpp | 5 +++++ - 1 file changed, 5 insertions(+) + clang/lib/Driver/ToolChains/Gnu.cpp | 4 ++++ + 1 file changed, 4 insertions(+) diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp -index c8006f3d8412..6ed03adb7702 100644 +index 24fbdcffc07b..8fed46b49515 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp -@@ -2863,6 +2863,11 @@ Generic_GCC::getDefaultUnwindTableLevel(const ArgList &Args) const { - case llvm::Triple::ppc64le: +@@ -2904,6 +2904,10 @@ Generic_GCC::getDefaultUnwindTableLevel(const ArgList &Args) const { + case llvm::Triple::riscv64: case llvm::Triple::x86: case llvm::Triple::x86_64: -+ + // Enable -funwind-tables on all architectures supported by Fedora: + // rhbz#1655546 + case llvm::Triple::systemz: diff --git a/0010-PATCH-clang-Produce-DWARF4-by-default.patch b/0001-Produce-DWARF4-by-default.patch similarity index 78% rename from 0010-PATCH-clang-Produce-DWARF4-by-default.patch rename to 0001-Produce-DWARF4-by-default.patch index ea81f74c75560bf92dfe06101ddcb14e309cdb1c..9b5b46bb84e7a28568659e4aa5a6a583e70f8de0 100644 --- a/0010-PATCH-clang-Produce-DWARF4-by-default.patch +++ b/0001-Produce-DWARF4-by-default.patch @@ -1,36 +1,38 @@ -From 4ea62faaaac1aad0fe496cabe9674c809c91c49a Mon Sep 17 00:00:00 2001 +From adbe188f3b1e3a0dd5ec80d9409601ba7f5b0423 Mon Sep 17 00:00:00 2001 From: Konrad Kleine -Date: Mon, 13 Feb 2023 17:11:00 -0300 +Date: Thu, 24 Mar 2022 09:44:21 +0100 Subject: [PATCH] Produce DWARF4 by default Have a look at the following commit to see when the move from DWARF 4 to 5 first happened upstream: https://github.com/llvm/llvm-project/commit/d3b26dea16108c427b19b5480c9edc76edf8f5b4?diff=unified --- - clang/include/clang/Driver/ToolChain.h | 2 +- - clang/test/CodeGen/dwarf-version.c | 4 ++-- - clang/test/Driver/as-options.s | 4 ++-- - clang/test/Driver/cl-options.c | 2 +- - clang/test/Driver/clang-g-opts.c | 2 +- - clang/test/Driver/ve-toolchain.c | 2 +- - clang/test/Driver/ve-toolchain.cpp | 2 +- - 7 files changed, 9 insertions(+), 9 deletions(-) + clang/lib/Driver/ToolChain.cpp | 4 +--- + clang/test/CodeGen/dwarf-version.c | 4 ++-- + clang/test/Driver/as-options.s | 4 ++-- + clang/test/Driver/cl-options.c | 2 +- + clang/test/Driver/clang-g-opts.c | 2 +- + clang/test/Driver/ve-toolchain.c | 2 +- + clang/test/Driver/ve-toolchain.cpp | 2 +- + 7 files changed, 9 insertions(+), 11 deletions(-) -diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h -index f75f35dc9e65..a70ae2b17833 100644 ---- a/clang/include/clang/Driver/ToolChain.h -+++ b/clang/include/clang/Driver/ToolChain.h -@@ -547,7 +547,7 @@ public: +diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp +index 8dafc3d481c2..92bf26dc8ec6 100644 +--- a/clang/lib/Driver/ToolChain.cpp ++++ b/clang/lib/Driver/ToolChain.cpp +@@ -428,9 +428,7 @@ ToolChain::getDefaultUnwindTableLevel(const ArgList &Args) const { + } - // Return the DWARF version to emit, in the absence of arguments - // to the contrary. -- virtual unsigned GetDefaultDwarfVersion() const { return 5; } -+ virtual unsigned GetDefaultDwarfVersion() const { return 4; } + unsigned ToolChain::GetDefaultDwarfVersion() const { +- // TODO: Remove the RISC-V special case when R_RISCV_SET_ULEB128 linker +- // support becomes more widely available. +- return getTriple().isRISCV() ? 4 : 5; ++ return 4; + } - // Some toolchains may have different restrictions on the DWARF version and - // may need to adjust it. E.g. NVPTX may need to enforce DWARF2 even when host + Tool *ToolChain::getClang() const { diff --git a/clang/test/CodeGen/dwarf-version.c b/clang/test/CodeGen/dwarf-version.c -index 0a6fa4768026..96f01749d0d8 100644 +index d307eb3f101f..e7e93bf6688c 100644 --- a/clang/test/CodeGen/dwarf-version.c +++ b/clang/test/CodeGen/dwarf-version.c @@ -2,8 +2,8 @@ @@ -67,10 +69,10 @@ index 73d002c7ef7e..71d55f7fd537 100644 // RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -gdwarf-5 %s -### 2>&1 | \ // RUN: FileCheck --check-prefix=GDWARF5 %s diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c -index 1d588bdfc1b0..1ad57aedc3a4 100644 +index 6d929b19e7e2..373905c2e0fc 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c -@@ -575,7 +575,7 @@ +@@ -569,7 +569,7 @@ // RUN: %clang_cl /Z7 -gdwarf /c -### -- %s 2>&1 | FileCheck -check-prefix=Z7_gdwarf %s // Z7_gdwarf: "-gcodeview" // Z7_gdwarf: "-debug-info-kind=constructor" @@ -80,7 +82,7 @@ index 1d588bdfc1b0..1ad57aedc3a4 100644 // RUN: %clang_cl /ZH:MD5 /c -### -- %s 2>&1 | FileCheck -check-prefix=ZH_MD5 %s // ZH_MD5: "-gsrc-hash=md5" diff --git a/clang/test/Driver/clang-g-opts.c b/clang/test/Driver/clang-g-opts.c -index d982b1070cae..bb129e75769c 100644 +index 5ee0fe64fe48..985158746137 100644 --- a/clang/test/Driver/clang-g-opts.c +++ b/clang/test/Driver/clang-g-opts.c @@ -32,7 +32,7 @@ @@ -119,5 +121,5 @@ index 5a33d5eceb61..cedf895b36dc 100644 ///----------------------------------------------------------------------------- /// Checking include-path -- -2.39.1 +2.41.0 diff --git a/0001-Workaround-a-bug-in-ORC-on-ppc64le.patch b/0001-Workaround-a-bug-in-ORC-on-ppc64le.patch new file mode 100644 index 0000000000000000000000000000000000000000..af236a12e39abe15c87be6afac2a1db86e3210d9 --- /dev/null +++ b/0001-Workaround-a-bug-in-ORC-on-ppc64le.patch @@ -0,0 +1,30 @@ +From a2449cee8c995b56f1892502aab3dfad3d6f3ca1 Mon Sep 17 00:00:00 2001 +From: Tulio Magno Quites Machado Filho +Date: Fri, 8 Sep 2023 11:45:34 -0300 +Subject: [PATCH] Workaround a bug in ORC on ppc64le + +The Jit code appears to be returning the wrong printf symbol on ppc64le +after the transition of the default long double to IEEE 128-bit floating +point. +--- + clang/unittests/Interpreter/InterpreterTest.cpp | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/clang/unittests/Interpreter/InterpreterTest.cpp b/clang/unittests/Interpreter/InterpreterTest.cpp +index abb8e6377aab..7b6697ebc6ed 100644 +--- a/clang/unittests/Interpreter/InterpreterTest.cpp ++++ b/clang/unittests/Interpreter/InterpreterTest.cpp +@@ -243,7 +243,9 @@ TEST(IncrementalProcessing, FindMangledNameSymbol) { + EXPECT_FALSE(!Addr); + + // FIXME: Re-enable when we investigate the way we handle dllimports on Win. +-#ifndef _WIN32 ++ // FIXME: The printf symbol returned from the Jit may not be correct on ++ // ppc64le when the default long double is IEEE 128-bit fp. ++#if !defined _WIN32 && !(defined __PPC64__ && defined __LITTLE_ENDIAN__) + EXPECT_EQ((uintptr_t)&printf, Addr->getValue()); + #endif // _WIN32 + } +-- +2.41.0 + diff --git a/0001-backport-LoongArch-patches.patch b/0001-backport-LoongArch-patches.patch deleted file mode 100644 index ae53c0f092714cda698b40e8078824140dad7c0d..0000000000000000000000000000000000000000 --- a/0001-backport-LoongArch-patches.patch +++ /dev/null @@ -1,1564 +0,0 @@ -diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst -index 8d67ff904..d36046916 100644 ---- a/clang/docs/ReleaseNotes.rst -+++ b/clang/docs/ReleaseNotes.rst -@@ -1047,6 +1047,9 @@ LoongArch Support - - Support extended options: ``-msoft-float``, ``-msingle-float``, ``-mdouble-float`` and ``mfpu=``. - See `LoongArch toolchain conventions `_. - -+- Patchable function entry (``-fpatchable-function-entry``) is now supported -+ on LoongArch. -+ - RISC-V Support - ^^^^^^^^^^^^^^ - - ``sifive-7-rv32`` and ``sifive-7-rv64`` are no longer supported for ``-mcpu``. -diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td -index d449a2fe7..28f94eebc 100644 ---- a/clang/include/clang/Basic/Attr.td -+++ b/clang/include/clang/Basic/Attr.td -@@ -792,7 +792,8 @@ def XRayLogArgs : InheritableAttr { - def PatchableFunctionEntry - : InheritableAttr, - TargetSpecificAttr> { -+ ["aarch64", "aarch64_be", "loongarch32", "loongarch64", "riscv32", -+ "riscv64", "x86", "x86_64"]>> { - let Spellings = [GCC<"patchable_function_entry">]; - let Subjects = SubjectList<[Function, ObjCMethod]>; - let Args = [UnsignedArgument<"Count">, DefaultIntArgument<"Offset", 0>]; -diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td -index 6d7a3ffd2..8861a9fce 100644 ---- a/clang/include/clang/Basic/AttrDocs.td -+++ b/clang/include/clang/Basic/AttrDocs.td -@@ -5315,7 +5315,7 @@ takes precedence over the command line option ``-fpatchable-function-entry=N,M`` - ``M`` defaults to 0 if omitted. - - This attribute is only supported on --aarch64/aarch64-be/riscv32/riscv64/i386/x86-64 targets. -+aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64 targets. - }]; - } - -diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td -index f3d43b2e0..10bab1c46 100644 ---- a/clang/include/clang/Basic/DiagnosticDriverKinds.td -+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td -@@ -715,6 +715,9 @@ def warn_drv_sarif_format_unstable : Warning< - def err_drv_riscv_unsupported_with_linker_relaxation : Error< - "%0 is unsupported with RISC-V linker relaxation (-mrelax)">; - -+def warn_drv_loongarch_conflicting_implied_val : Warning< -+ "ignoring '%0' as it conflicts with that implied by '%1' (%2)">, -+ InGroup; - def err_drv_loongarch_invalid_mfpu_EQ : Error< - "invalid argument '%0' to -mfpu=; must be one of: 64, 32, none, 0 (alias for none)">; - } -diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td -index 652c15afc..fcbdcb5ec 100644 ---- a/clang/include/clang/Driver/Options.td -+++ b/clang/include/clang/Driver/Options.td -@@ -3583,12 +3583,14 @@ def mcmodel_EQ_medany : Flag<["-"], "mcmodel=medany">, Group, - def menable_experimental_extensions : Flag<["-"], "menable-experimental-extensions">, Group, - HelpText<"Enable use of experimental RISC-V extensions.">; - --def munaligned_access : Flag<["-"], "munaligned-access">, Group, -- HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">; --def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group, -- HelpText<"Force all memory accesses to be aligned (AArch32/AArch64 only)">; -+def munaligned_access : Flag<["-"], "munaligned-access">, Group, -+ HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64/LoongArch only)">; -+def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group, -+ HelpText<"Force all memory accesses to be aligned (AArch32/AArch64/LoongArch only)">; - def mstrict_align : Flag<["-"], "mstrict-align">, Alias, Flags<[CC1Option,HelpHidden]>, - HelpText<"Force all memory accesses to be aligned (same as mno-unaligned-access)">; -+def mno_strict_align : Flag<["-"], "mno-strict-align">, Alias, Flags<[CC1Option,HelpHidden]>, -+ HelpText<"Allow memory accesses to be unaligned (same as munaligned-access)">; - def mno_thumb : Flag<["-"], "mno-thumb">, Group; - def mrestrict_it: Flag<["-"], "mrestrict-it">, Group, - HelpText<"Disallow generation of complex IT blocks.">; -diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp -index 2079c89e3..96ef29620 100644 ---- a/clang/lib/Basic/Targets/LoongArch.cpp -+++ b/clang/lib/Basic/Targets/LoongArch.cpp -@@ -14,8 +14,8 @@ - #include "clang/Basic/Diagnostic.h" - #include "clang/Basic/MacroBuilder.h" - #include "clang/Basic/TargetBuiltins.h" --#include "llvm/Support/TargetParser.h" - #include "llvm/Support/raw_ostream.h" -+#include "llvm/TargetParser/LoongArchTargetParser.h" - - using namespace clang; - using namespace clang::targets; -@@ -31,34 +31,79 @@ ArrayRef LoongArchTargetInfo::getGCCRegNames() const { - "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9", - "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18", - "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", -- "$f28", "$f29", "$f30", "$f31"}; -+ "$f28", "$f29", "$f30", "$f31", -+ // Condition flag registers. -+ "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", "$fcc6", "$fcc7"}; - return llvm::ArrayRef(GCCRegNames); - } - - ArrayRef - LoongArchTargetInfo::getGCCRegAliases() const { - static const TargetInfo::GCCRegAlias GCCRegAliases[] = { -- {{"$zero"}, "$r0"}, {{"$ra"}, "$r1"}, {{"$tp"}, "$r2"}, -- {{"$sp"}, "$r3"}, {{"$a0"}, "$r4"}, {{"$a1"}, "$r5"}, -- {{"$a2"}, "$r6"}, {{"$a3"}, "$r7"}, {{"$a4"}, "$r8"}, -- {{"$a5"}, "$r9"}, {{"$a6"}, "$r10"}, {{"$a7"}, "$r11"}, -- {{"$t0"}, "$r12"}, {{"$t1"}, "$r13"}, {{"$t2"}, "$r14"}, -- {{"$t3"}, "$r15"}, {{"$t4"}, "$r16"}, {{"$t5"}, "$r17"}, -- {{"$t6"}, "$r18"}, {{"$t7"}, "$r19"}, {{"$t8"}, "$r20"}, -- {{"$fp", "$s9"}, "$r22"}, {{"$s0"}, "$r23"}, {{"$s1"}, "$r24"}, -- {{"$s2"}, "$r25"}, {{"$s3"}, "$r26"}, {{"$s4"}, "$r27"}, -- {{"$s5"}, "$r28"}, {{"$s6"}, "$r29"}, {{"$s7"}, "$r30"}, -- {{"$s8"}, "$r31"}, {{"$fa0"}, "$f0"}, {{"$fa1"}, "$f1"}, -- {{"$fa2"}, "$f2"}, {{"$fa3"}, "$f3"}, {{"$fa4"}, "$f4"}, -- {{"$fa5"}, "$f5"}, {{"$fa6"}, "$f6"}, {{"$fa7"}, "$f7"}, -- {{"$ft0"}, "$f8"}, {{"$ft1"}, "$f9"}, {{"$ft2"}, "$f10"}, -- {{"$ft3"}, "$f11"}, {{"$ft4"}, "$f12"}, {{"$ft5"}, "$f13"}, -- {{"$ft6"}, "$f14"}, {{"$ft7"}, "$f15"}, {{"$ft8"}, "$f16"}, -- {{"$ft9"}, "$f17"}, {{"$ft10"}, "$f18"}, {{"$ft11"}, "$f19"}, -- {{"$ft12"}, "$f20"}, {{"$ft13"}, "$f21"}, {{"$ft14"}, "$f22"}, -- {{"$ft15"}, "$f23"}, {{"$fs0"}, "$f24"}, {{"$fs1"}, "$f25"}, -- {{"$fs2"}, "$f26"}, {{"$fs3"}, "$f27"}, {{"$fs4"}, "$f28"}, -- {{"$fs5"}, "$f29"}, {{"$fs6"}, "$f30"}, {{"$fs7"}, "$f31"}, -+ {{"zero", "$zero", "r0"}, "$r0"}, -+ {{"ra", "$ra", "r1"}, "$r1"}, -+ {{"tp", "$tp", "r2"}, "$r2"}, -+ {{"sp", "$sp", "r3"}, "$r3"}, -+ {{"a0", "$a0", "r4"}, "$r4"}, -+ {{"a1", "$a1", "r5"}, "$r5"}, -+ {{"a2", "$a2", "r6"}, "$r6"}, -+ {{"a3", "$a3", "r7"}, "$r7"}, -+ {{"a4", "$a4", "r8"}, "$r8"}, -+ {{"a5", "$a5", "r9"}, "$r9"}, -+ {{"a6", "$a6", "r10"}, "$r10"}, -+ {{"a7", "$a7", "r11"}, "$r11"}, -+ {{"t0", "$t0", "r12"}, "$r12"}, -+ {{"t1", "$t1", "r13"}, "$r13"}, -+ {{"t2", "$t2", "r14"}, "$r14"}, -+ {{"t3", "$t3", "r15"}, "$r15"}, -+ {{"t4", "$t4", "r16"}, "$r16"}, -+ {{"t5", "$t5", "r17"}, "$r17"}, -+ {{"t6", "$t6", "r18"}, "$r18"}, -+ {{"t7", "$t7", "r19"}, "$r19"}, -+ {{"t8", "$t8", "r20"}, "$r20"}, -+ {{"r21"}, "$r21"}, -+ {{"s9", "$s9", "r22", "fp", "$fp"}, "$r22"}, -+ {{"s0", "$s0", "r23"}, "$r23"}, -+ {{"s1", "$s1", "r24"}, "$r24"}, -+ {{"s2", "$s2", "r25"}, "$r25"}, -+ {{"s3", "$s3", "r26"}, "$r26"}, -+ {{"s4", "$s4", "r27"}, "$r27"}, -+ {{"s5", "$s5", "r28"}, "$r28"}, -+ {{"s6", "$s6", "r29"}, "$r29"}, -+ {{"s7", "$s7", "r30"}, "$r30"}, -+ {{"s8", "$s8", "r31"}, "$r31"}, -+ {{"$fa0"}, "$f0"}, -+ {{"$fa1"}, "$f1"}, -+ {{"$fa2"}, "$f2"}, -+ {{"$fa3"}, "$f3"}, -+ {{"$fa4"}, "$f4"}, -+ {{"$fa5"}, "$f5"}, -+ {{"$fa6"}, "$f6"}, -+ {{"$fa7"}, "$f7"}, -+ {{"$ft0"}, "$f8"}, -+ {{"$ft1"}, "$f9"}, -+ {{"$ft2"}, "$f10"}, -+ {{"$ft3"}, "$f11"}, -+ {{"$ft4"}, "$f12"}, -+ {{"$ft5"}, "$f13"}, -+ {{"$ft6"}, "$f14"}, -+ {{"$ft7"}, "$f15"}, -+ {{"$ft8"}, "$f16"}, -+ {{"$ft9"}, "$f17"}, -+ {{"$ft10"}, "$f18"}, -+ {{"$ft11"}, "$f19"}, -+ {{"$ft12"}, "$f20"}, -+ {{"$ft13"}, "$f21"}, -+ {{"$ft14"}, "$f22"}, -+ {{"$ft15"}, "$f23"}, -+ {{"$fs0"}, "$f24"}, -+ {{"$fs1"}, "$f25"}, -+ {{"$fs2"}, "$f26"}, -+ {{"$fs3"}, "$f27"}, -+ {{"$fs4"}, "$f28"}, -+ {{"$fs5"}, "$f29"}, -+ {{"$fs6"}, "$f30"}, -+ {{"$fs7"}, "$f31"}, - }; - return llvm::ArrayRef(GCCRegAliases); - } -@@ -143,7 +188,15 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts, - else - Builder.defineMacro("__loongarch_frlen", "0"); - -- // TODO: define __loongarch_arch and __loongarch_tune. -+ // Define __loongarch_arch. -+ StringRef ArchName = getCPU(); -+ Builder.defineMacro("__loongarch_arch", Twine('"') + ArchName + Twine('"')); -+ -+ // Define __loongarch_tune. -+ StringRef TuneCPU = getTargetOpts().TuneCPU; -+ if (TuneCPU.empty()) -+ TuneCPU = ArchName; -+ Builder.defineMacro("__loongarch_tune", Twine('"') + TuneCPU + Twine('"')); - - StringRef ABI = getABI(); - if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s") -@@ -215,3 +268,12 @@ bool LoongArchTargetInfo::handleTargetFeatures( - } - return true; - } -+ -+bool LoongArchTargetInfo::isValidCPUName(StringRef Name) const { -+ return llvm::LoongArch::isValidCPUName(Name); -+} -+ -+void LoongArchTargetInfo::fillValidCPUList( -+ SmallVectorImpl &Values) const { -+ llvm::LoongArch::fillValidCPUList(Values); -+} -diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h -index 646c8d071..46ce56b43 100644 ---- a/clang/lib/Basic/Targets/LoongArch.h -+++ b/clang/lib/Basic/Targets/LoongArch.h -@@ -24,6 +24,7 @@ namespace targets { - class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { - protected: - std::string ABI; -+ std::string CPU; - bool HasFeatureD; - bool HasFeatureF; - -@@ -40,6 +41,15 @@ public: - WIntType = UnsignedInt; - } - -+ bool setCPU(const std::string &Name) override { -+ if (!isValidCPUName(Name)) -+ return false; -+ CPU = Name; -+ return true; -+ } -+ -+ StringRef getCPU() const { return CPU; } -+ - StringRef getABI() const override { return ABI; } - - void getTargetDefines(const LangOptions &Opts, -@@ -80,6 +90,9 @@ public: - const std::vector &FeaturesVec) const override; - - bool hasFeature(StringRef Feature) const override; -+ -+ bool isValidCPUName(StringRef Name) const override; -+ void fillValidCPUList(SmallVectorImpl &Values) const override; - }; - - class LLVM_LIBRARY_VISIBILITY LoongArch32TargetInfo -diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp -index 9e2d7a85d..442138715 100644 ---- a/clang/lib/CodeGen/TargetInfo.cpp -+++ b/clang/lib/CodeGen/TargetInfo.cpp -@@ -548,12 +548,13 @@ TargetCodeGenInfo::getLLVMSyncScopeID(const LangOptions &LangOpts, - return Ctx.getOrInsertSyncScopeID(""); /* default sync scope */ - } - --static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays); -+static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, -+ bool AsIfNoUniqueAddr = false); - - /// isEmptyField - Return true iff a the field is "empty", that is it - /// is an unnamed bit-field or an (array of) empty record(s). - static bool isEmptyField(ASTContext &Context, const FieldDecl *FD, -- bool AllowArrays) { -+ bool AllowArrays, bool AsIfNoUniqueAddr = false) { - if (FD->isUnnamedBitfield()) - return true; - -@@ -587,16 +588,19 @@ static bool isEmptyField(ASTContext &Context, const FieldDecl *FD, - // not arrays of records, so we must also check whether we stripped off an - // array type above. - if (isa(RT->getDecl()) && -- (WasArray || !FD->hasAttr())) -+ (WasArray || (!AsIfNoUniqueAddr && !FD->hasAttr()))) - return false; - -- return isEmptyRecord(Context, FT, AllowArrays); -+ return isEmptyRecord(Context, FT, AllowArrays, AsIfNoUniqueAddr); - } - - /// isEmptyRecord - Return true iff a structure contains only empty - /// fields. Note that a structure with a flexible array member is not --/// considered empty. --static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays) { -+/// considered empty. If AsIfNoUniqueAddr is true, then C++ record fields are -+/// considered empty if the [[no_unique_address]] attribute would have made -+/// them empty. -+static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, -+ bool AsIfNoUniqueAddr) { - const RecordType *RT = T->getAs(); - if (!RT) - return false; -@@ -607,11 +611,11 @@ static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays) { - // If this is a C++ record, check the bases first. - if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) - for (const auto &I : CXXRD->bases()) -- if (!isEmptyRecord(Context, I.getType(), true)) -+ if (!isEmptyRecord(Context, I.getType(), true, AsIfNoUniqueAddr)) - return false; - - for (const auto *I : RD->fields()) -- if (!isEmptyField(Context, I, AllowArrays)) -+ if (!isEmptyField(Context, I, AllowArrays, AsIfNoUniqueAddr)) - return false; - return true; - } -@@ -11883,6 +11887,13 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper( - if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) { - uint64_t ArraySize = ATy->getSize().getZExtValue(); - QualType EltTy = ATy->getElementType(); -+ // Non-zero-length arrays of empty records make the struct ineligible to be -+ // passed via FARs in C++. -+ if (const auto *RTy = EltTy->getAs()) { -+ if (ArraySize != 0 && isa(RTy->getDecl()) && -+ isEmptyRecord(getContext(), EltTy, true, true)) -+ return false; -+ } - CharUnits EltSize = getContext().getTypeSizeInChars(EltTy); - for (uint64_t i = 0; i < ArraySize; ++i) { - if (!detectFARsEligibleStructHelper(EltTy, CurOff, Field1Ty, Field1Off, -@@ -11898,7 +11909,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper( - // copy constructor are not eligible for the FP calling convention. - if (getRecordArgABI(Ty, CGT.getCXXABI())) - return false; -- if (isEmptyRecord(getContext(), Ty, true)) -+ if (isEmptyRecord(getContext(), Ty, true, true)) - return true; - const RecordDecl *RD = RTy->getDecl(); - // Unions aren't eligible unless they're empty (which is caught above). -@@ -11957,6 +11968,8 @@ bool LoongArchABIInfo::detectFARsEligibleStruct( - if (!detectFARsEligibleStructHelper(Ty, CharUnits::Zero(), Field1Ty, - Field1Off, Field2Ty, Field2Off)) - return false; -+ if (!Field1Ty) -+ return false; - // Not really a candidate if we have a single int but no float. - if (Field1Ty && !Field2Ty && !Field1Ty->isFloatingPointTy()) - return false; -diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp -index 576677a5f..f5d4018a4 100644 ---- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp -+++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp -@@ -7,11 +7,13 @@ - //===----------------------------------------------------------------------===// - - #include "LoongArch.h" -+#include "ToolChains/CommonArgs.h" - #include "clang/Basic/DiagnosticDriver.h" - #include "clang/Driver/Driver.h" - #include "clang/Driver/DriverDiagnostic.h" - #include "clang/Driver/Options.h" --#include "llvm/Support/LoongArchTargetParser.h" -+#include "llvm/TargetParser/Host.h" -+#include "llvm/TargetParser/LoongArchTargetParser.h" - - using namespace clang::driver; - using namespace clang::driver::tools; -@@ -25,32 +27,75 @@ StringRef loongarch::getLoongArchABI(const Driver &D, const ArgList &Args, - "Unexpected triple"); - bool IsLA32 = Triple.getArch() == llvm::Triple::loongarch32; - -+ // Record -mabi value for later use. -+ const Arg *MABIArg = Args.getLastArg(options::OPT_mabi_EQ); -+ StringRef MABIValue; -+ if (MABIArg) { -+ MABIValue = MABIArg->getValue(); -+ } -+ -+ // Parse -mfpu value for later use. -+ const Arg *MFPUArg = Args.getLastArg(options::OPT_mfpu_EQ); -+ int FPU = -1; -+ if (MFPUArg) { -+ StringRef V = MFPUArg->getValue(); -+ if (V == "64") -+ FPU = 64; -+ else if (V == "32") -+ FPU = 32; -+ else if (V == "0" || V == "none") -+ FPU = 0; -+ else -+ D.Diag(diag::err_drv_loongarch_invalid_mfpu_EQ) << V; -+ } -+ - // Check -m*-float firstly since they have highest priority. - if (const Arg *A = Args.getLastArg(options::OPT_mdouble_float, - options::OPT_msingle_float, - options::OPT_msoft_float)) { -- if (A->getOption().matches(options::OPT_mdouble_float)) -- return IsLA32 ? "ilp32d" : "lp64d"; -- if (A->getOption().matches(options::OPT_msingle_float)) -- return IsLA32 ? "ilp32f" : "lp64f"; -- if (A->getOption().matches(options::OPT_msoft_float)) -- return IsLA32 ? "ilp32s" : "lp64s"; -+ StringRef ImpliedABI; -+ int ImpliedFPU = -1; -+ if (A->getOption().matches(options::OPT_mdouble_float)) { -+ ImpliedABI = IsLA32 ? "ilp32d" : "lp64d"; -+ ImpliedFPU = 64; -+ } -+ if (A->getOption().matches(options::OPT_msingle_float)) { -+ ImpliedABI = IsLA32 ? "ilp32f" : "lp64f"; -+ ImpliedFPU = 32; -+ } -+ if (A->getOption().matches(options::OPT_msoft_float)) { -+ ImpliedABI = IsLA32 ? "ilp32s" : "lp64s"; -+ ImpliedFPU = 0; -+ } -+ -+ // Check `-mabi=` and `-mfpu=` settings and report if they conflict with -+ // the higher-priority settings implied by -m*-float. -+ // -+ // ImpliedABI and ImpliedFPU are guaranteed to have valid values because -+ // one of the match arms must match if execution can arrive here at all. -+ if (!MABIValue.empty() && ImpliedABI != MABIValue) -+ D.Diag(diag::warn_drv_loongarch_conflicting_implied_val) -+ << MABIArg->getAsString(Args) << A->getAsString(Args) << ImpliedABI; -+ -+ if (FPU != -1 && ImpliedFPU != FPU) -+ D.Diag(diag::warn_drv_loongarch_conflicting_implied_val) -+ << MFPUArg->getAsString(Args) << A->getAsString(Args) << ImpliedFPU; -+ -+ return ImpliedABI; - } - - // If `-mabi=` is specified, use it. -- if (const Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) -- return A->getValue(); -+ if (!MABIValue.empty()) -+ return MABIValue; - - // Select abi based on -mfpu=xx. -- if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) { -- StringRef FPU = A->getValue(); -- if (FPU == "64") -- return IsLA32 ? "ilp32d" : "lp64d"; -- if (FPU == "32") -- return IsLA32 ? "ilp32f" : "lp64f"; -- if (FPU == "0" || FPU == "none") -- return IsLA32 ? "ilp32s" : "lp64s"; -- D.Diag(diag::err_drv_loongarch_invalid_mfpu_EQ) << FPU; -+ switch (FPU) { -+ case 64: -+ return IsLA32 ? "ilp32d" : "lp64d"; -+ case 32: -+ return IsLA32 ? "ilp32f" : "lp64f"; -+ case 0: -+ return IsLA32 ? "ilp32s" : "lp64s"; - } - - // Choose a default based on the triple. -@@ -61,25 +106,11 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, - const llvm::Triple &Triple, - const ArgList &Args, - std::vector &Features) { -- StringRef ArchName; -- llvm::LoongArch::ArchKind ArchKind = llvm::LoongArch::ArchKind::AK_INVALID; -- if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { -- ArchKind = llvm::LoongArch::parseArch(A->getValue()); -- if (ArchKind == llvm::LoongArch::ArchKind::AK_INVALID) { -- D.Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args); -- return; -- } -+ std::string ArchName; -+ if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) - ArchName = A->getValue(); -- } -- -- // TODO: handle -march=native and -mtune=xx. -- -- // Select a default arch name. -- if (ArchName.empty() && Triple.getArch() == llvm::Triple::loongarch64) -- ArchName = "loongarch64"; -- -- if (!ArchName.empty()) -- llvm::LoongArch::getArchFeatures(ArchName, Features); -+ ArchName = postProcessTargetCPUString(ArchName, Triple); -+ llvm::LoongArch::getArchFeatures(ArchName, Features); - - // Select floating-point features determined by -mdouble-float, - // -msingle-float, -msoft-float and -mfpu. -@@ -112,4 +143,31 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, - D.Diag(diag::err_drv_loongarch_invalid_mfpu_EQ) << FPU; - } - } -+ -+ // Select the `ual` feature determined by -m[no-]unaligned-access -+ // or the alias -m[no-]strict-align. -+ AddTargetFeature(Args, Features, options::OPT_munaligned_access, -+ options::OPT_mno_unaligned_access, "ual"); -+} -+ -+std::string loongarch::postProcessTargetCPUString(const std::string &CPU, -+ const llvm::Triple &Triple) { -+ std::string CPUString = CPU; -+ if (CPUString == "native") { -+ CPUString = llvm::sys::getHostCPUName(); -+ if (CPUString == "generic") -+ CPUString = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64()); -+ } -+ if (CPUString.empty()) -+ CPUString = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64()); -+ return CPUString; -+} -+ -+std::string loongarch::getLoongArchTargetCPU(const llvm::opt::ArgList &Args, -+ const llvm::Triple &Triple) { -+ std::string CPU; -+ // If we have -march, use that. -+ if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) -+ CPU = A->getValue(); -+ return postProcessTargetCPUString(CPU, Triple); - } -diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.h b/clang/lib/Driver/ToolChains/Arch/LoongArch.h -index 0084474e7..d8280cd83 100644 ---- a/clang/lib/Driver/ToolChains/Arch/LoongArch.h -+++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.h -@@ -23,6 +23,12 @@ void getLoongArchTargetFeatures(const Driver &D, const llvm::Triple &Triple, - - StringRef getLoongArchABI(const Driver &D, const llvm::opt::ArgList &Args, - const llvm::Triple &Triple); -+ -+std::string postProcessTargetCPUString(const std::string &CPU, -+ const llvm::Triple &Triple); -+ -+std::string getLoongArchTargetCPU(const llvm::opt::ArgList &Args, -+ const llvm::Triple &Triple); - } // end namespace loongarch - } // end namespace tools - } // end namespace driver -diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp -index 77554aa2c..e5c3b1087 100644 ---- a/clang/lib/Driver/ToolChains/Clang.cpp -+++ b/clang/lib/Driver/ToolChains/Clang.cpp -@@ -54,6 +54,7 @@ - #include "llvm/Support/Path.h" - #include "llvm/Support/Process.h" - #include "llvm/Support/YAMLParser.h" -+#include "llvm/TargetParser/LoongArchTargetParser.h" - #include - - using namespace clang::driver; -@@ -1833,10 +1834,20 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, - - void Clang::AddLoongArchTargetArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { -+ const llvm::Triple &Triple = getToolChain().getTriple(); -+ - CmdArgs.push_back("-target-abi"); -- CmdArgs.push_back(loongarch::getLoongArchABI(getToolChain().getDriver(), Args, -- getToolChain().getTriple()) -- .data()); -+ CmdArgs.push_back( -+ loongarch::getLoongArchABI(getToolChain().getDriver(), Args, Triple) -+ .data()); -+ -+ // Handle -mtune. -+ if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) { -+ std::string TuneCPU = A->getValue(); -+ TuneCPU = loongarch::postProcessTargetCPUString(TuneCPU, Triple); -+ CmdArgs.push_back("-tune-cpu"); -+ CmdArgs.push_back(Args.MakeArgString(TuneCPU)); -+ } - } - - void Clang::AddMIPSTargetArgs(const ArgList &Args, -@@ -6235,7 +6246,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, - if (Arg *A = Args.getLastArg(options::OPT_fpatchable_function_entry_EQ)) { - StringRef S0 = A->getValue(), S = S0; - unsigned Size, Offset = 0; -- if (!Triple.isAArch64() && !Triple.isRISCV() && !Triple.isX86()) -+ if (!Triple.isAArch64() && !Triple.isLoongArch() && !Triple.isRISCV() && -+ !Triple.isX86()) - D.Diag(diag::err_drv_unsupported_opt_for_target) - << A->getAsString(Args) << TripleStr; - else if (S.consumeInteger(10, Size) || -@@ -7863,6 +7875,14 @@ void ClangAs::AddX86TargetArgs(const ArgList &Args, - } - } - -+void ClangAs::AddLoongArchTargetArgs(const ArgList &Args, -+ ArgStringList &CmdArgs) const { -+ CmdArgs.push_back("-target-abi"); -+ CmdArgs.push_back(loongarch::getLoongArchABI(getToolChain().getDriver(), Args, -+ getToolChain().getTriple()) -+ .data()); -+} -+ - void ClangAs::AddRISCVTargetArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { - const llvm::Triple &Triple = getToolChain().getTriple(); -@@ -8054,6 +8074,11 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, - } - break; - -+ case llvm::Triple::loongarch32: -+ case llvm::Triple::loongarch64: -+ AddLoongArchTargetArgs(Args, CmdArgs); -+ break; -+ - case llvm::Triple::riscv32: - case llvm::Triple::riscv64: - AddRISCVTargetArgs(Args, CmdArgs); -diff --git a/clang/lib/Driver/ToolChains/Clang.h b/clang/lib/Driver/ToolChains/Clang.h -index a7625dba6..3c373bdee 100644 ---- a/clang/lib/Driver/ToolChains/Clang.h -+++ b/clang/lib/Driver/ToolChains/Clang.h -@@ -125,6 +125,8 @@ class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool { - public: - ClangAs(const ToolChain &TC) - : Tool("clang::as", "clang integrated assembler", TC) {} -+ void AddLoongArchTargetArgs(const llvm::opt::ArgList &Args, -+ llvm::opt::ArgStringList &CmdArgs) const; - void AddMIPSTargetArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const; - void AddX86TargetArgs(const llvm::opt::ArgList &Args, -diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp -index 34640b3c4..b462e2fe1 100644 ---- a/clang/lib/Driver/ToolChains/CommonArgs.cpp -+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp -@@ -455,6 +455,10 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args, - case llvm::Triple::wasm32: - case llvm::Triple::wasm64: - return std::string(getWebAssemblyTargetCPU(Args)); -+ -+ case llvm::Triple::loongarch32: -+ case llvm::Triple::loongarch64: -+ return loongarch::getLoongArchTargetCPU(Args, T); - } - } - -diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp -index 4f2340316..001ead153 100644 ---- a/clang/lib/Driver/ToolChains/Gnu.cpp -+++ b/clang/lib/Driver/ToolChains/Gnu.cpp -@@ -9,6 +9,7 @@ - #include "Gnu.h" - #include "Arch/ARM.h" - #include "Arch/CSKY.h" -+#include "Arch/LoongArch.h" - #include "Arch/Mips.h" - #include "Arch/PPC.h" - #include "Arch/RISCV.h" -@@ -855,6 +856,13 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, - - break; - } -+ // TODO: handle loongarch32. -+ case llvm::Triple::loongarch64: { -+ StringRef ABIName = -+ loongarch::getLoongArchABI(D, Args, getToolChain().getTriple()); -+ CmdArgs.push_back(Args.MakeArgString("-mabi=" + ABIName)); -+ break; -+ } - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::mips64: -@@ -2261,7 +2269,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( - - static const char *const LoongArch64LibDirs[] = {"/lib64", "/lib"}; - static const char *const LoongArch64Triples[] = { -- "loongarch64-linux-gnu", "loongarch64-unknown-linux-gnu"}; -+ "loongarch64-linux-gnu", "loongarch64-unknown-linux-gnu", -+ "loongarch64-anolis-linux"}; - - static const char *const M68kLibDirs[] = {"/lib"}; - static const char *const M68kTriples[] = { -diff --git a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c -new file mode 100644 -index 000000000..fb90bf556 ---- /dev/null -+++ b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c -@@ -0,0 +1,89 @@ -+// RUN: %clang_cc1 -triple loongarch64 -target-feature +f -target-feature +d -target-abi lp64d -emit-llvm %s -o - | \ -+// RUN: FileCheck --check-prefix=CHECK-C %s -+// RUN: %clang_cc1 -triple loongarch64 -target-feature +f -target-feature +d -target-abi lp64d -emit-llvm %s -o - -x c++ | \ -+// RUN: FileCheck --check-prefix=CHECK-CXX %s -+ -+// Fields containing empty structs or unions are ignored when flattening -+// structs to examine whether the structs can be passed via FARs, even in C++. -+// But there is an exception that non-zero-length array of empty structures are -+// not ignored in C++. These rules are not documented in psABI -+// but they match GCC behaviours. -+ -+#include -+ -+struct empty { struct { struct { } e; }; }; -+struct s1 { struct empty e; float f; }; -+ -+// CHECK-C: define{{.*}} float @test_s1(float {{.*}}) -+// CHECK-CXX: define{{.*}} float @_Z7test_s12s1(float {{.*}}) -+struct s1 test_s1(struct s1 a) { -+ return a; -+} -+ -+struct s2 { struct empty e; int32_t i; float f; }; -+ -+// CHECK-C: define{{.*}} { i32, float } @test_s2(i32 {{.*}}, float {{.*}}) -+// CHECK-CXX: define{{.*}} { i32, float } @_Z7test_s22s2(i32 {{.*}}, float {{.*}}) -+struct s2 test_s2(struct s2 a) { -+ return a; -+} -+ -+struct s3 { struct empty e; float f; float g; }; -+ -+// CHECK-C: define{{.*}} { float, float } @test_s3(float {{.*}}, float {{.*}}) -+// CHECK-CXX: define{{.*}} { float, float } @_Z7test_s32s3(float {{.*}}, float {{.*}}) -+struct s3 test_s3(struct s3 a) { -+ return a; -+} -+ -+struct s4 { struct empty e; float __complex__ c; }; -+ -+// CHECK-C: define{{.*}} { float, float } @test_s4(float {{.*}}, float {{.*}}) -+// CHECK-CXX: define{{.*}} { float, float } @_Z7test_s42s4(float {{.*}}, float {{.*}}) -+struct s4 test_s4(struct s4 a) { -+ return a; -+} -+ -+// An array of empty fields isn't ignored in C++ (this isn't explicit in the -+// psABI, but matches observed g++ behaviour). -+ -+struct s5 { struct empty e[1]; float f; }; -+ -+// CHECK-C: define{{.*}} float @test_s5(float {{.*}}) -+// CHECK-CXX: define{{.*}} i64 @_Z7test_s52s5(i64 {{.*}}) -+struct s5 test_s5(struct s5 a) { -+ return a; -+} -+ -+struct empty_arr { struct { struct { } e[1]; }; }; -+struct s6 { struct empty_arr e; float f; }; -+ -+// CHECK-C: define{{.*}} float @test_s6(float {{.*}}) -+// CHECK-CXX: define{{.*}} i64 @_Z7test_s62s6(i64 {{.*}}) -+struct s6 test_s6(struct s6 a) { -+ return a; -+} -+ -+struct s7 { struct empty e[0]; float f; }; -+ -+// CHECK-C: define{{.*}} float @test_s7(float {{.*}}) -+// CHECK-CXX: define{{.*}} float @_Z7test_s72s7(float {{.*}}) -+struct s7 test_s7(struct s7 a) { -+ return a; -+} -+ -+struct empty_arr0 { struct { struct { } e[0]; }; }; -+struct s8 { struct empty_arr0 e; float f; }; -+ -+// CHECK-C: define{{.*}} float @test_s8(float {{.*}}) -+// CHECK-CXX: define{{.*}} float @_Z7test_s82s8(float {{.*}}) -+struct s8 test_s8(struct s8 a) { -+ return a; -+} -+ -+// CHECK-C: define{{.*}} void @test_s9() -+// CHECK-CXX: define{{.*}} i64 @_Z7test_s92s9(i64 {{.*}}) -+struct s9 { struct empty e; }; -+struct s9 test_s9(struct s9 a) { -+ return a; -+} -diff --git a/clang/test/CodeGen/LoongArch/inline-asm-gcc-regs-error.c b/clang/test/CodeGen/LoongArch/inline-asm-gcc-regs-error.c -index 39450c465..c5ecf0c92 100644 ---- a/clang/test/CodeGen/LoongArch/inline-asm-gcc-regs-error.c -+++ b/clang/test/CodeGen/LoongArch/inline-asm-gcc-regs-error.c -@@ -11,12 +11,10 @@ void test(void) { - - /// Names not prefixed with '$' are invalid. - --// CHECK: :[[#@LINE+1]]:24: error: unknown register name 'r4' in asm -- register int a3 asm ("r4"); --// CHECK: :[[#@LINE+1]]:24: error: unknown register name 'a0' in asm -- register int a4 asm ("a0"); - // CHECK: :[[#@LINE+1]]:26: error: unknown register name 'f0' in asm - register float a5 asm ("f0"); - // CHECK: :[[#@LINE+1]]:26: error: unknown register name 'fa0' in asm - register float a6 asm ("fa0"); -+// CHECK: :[[#@LINE+1]]:15: error: unknown register name 'fcc0' in asm -+ asm ("" ::: "fcc0"); - } -diff --git a/clang/test/CodeGen/LoongArch/inline-asm-gcc-regs.c b/clang/test/CodeGen/LoongArch/inline-asm-gcc-regs.c -index 067645366..e1015f6fc 100644 ---- a/clang/test/CodeGen/LoongArch/inline-asm-gcc-regs.c -+++ b/clang/test/CodeGen/LoongArch/inline-asm-gcc-regs.c -@@ -7,56 +7,72 @@ - // CHECK: call void asm sideeffect "", "{$r0}"(i32 undef) - void test_r0() { - register int a asm ("$r0"); -+ register int b asm ("r0"); - asm ("" :: "r" (a)); -+ asm ("" :: "r" (b)); - } - - // CHECK-LABEL: @test_r12 - // CHECK: call void asm sideeffect "", "{$r12}"(i32 undef) - void test_r12() { - register int a asm ("$r12"); -+ register int b asm ("r12"); - asm ("" :: "r" (a)); -+ asm ("" :: "r" (b)); - } - - // CHECK-LABEL: @test_r31 - // CHECK: call void asm sideeffect "", "{$r31}"(i32 undef) - void test_r31() { - register int a asm ("$r31"); -+ register int b asm ("r31"); - asm ("" :: "r" (a)); -+ asm ("" :: "r" (b)); - } - - // CHECK-LABEL: @test_zero - // CHECK: call void asm sideeffect "", "{$r0}"(i32 undef) - void test_zero() { - register int a asm ("$zero"); -+ register int b asm ("zero"); - asm ("" :: "r" (a)); -+ asm ("" :: "r" (b)); - } - - // CHECK-LABEL: @test_a0 - // CHECK: call void asm sideeffect "", "{$r4}"(i32 undef) - void test_a0() { - register int a asm ("$a0"); -+ register int b asm ("a0"); - asm ("" :: "r" (a)); -+ asm ("" :: "r" (b)); - } - - // CHECK-LABEL: @test_t1 - // CHECK: call void asm sideeffect "", "{$r13}"(i32 undef) - void test_t1() { - register int a asm ("$t1"); -+ register int b asm ("t1"); - asm ("" :: "r" (a)); -+ asm ("" :: "r" (b)); - } - - // CHECK-LABEL: @test_fp - // CHECK: call void asm sideeffect "", "{$r22}"(i32 undef) - void test_fp() { - register int a asm ("$fp"); -+ register int b asm ("fp"); - asm ("" :: "r" (a)); -+ asm ("" :: "r" (b)); - } - - // CHECK-LABEL: @test_s2 - // CHECK: call void asm sideeffect "", "{$r25}"(i32 undef) - void test_s2() { - register int a asm ("$s2"); -+ register int b asm ("s2"); - asm ("" :: "r" (a)); -+ asm ("" :: "r" (b)); - } - - // CHECK-LABEL: @test_f0 -@@ -100,3 +116,11 @@ void test_fs2() { - register float a asm ("$fs2"); - asm ("" :: "f" (a)); - } -+ -+// CHECK-LABEL: @test_fcc -+// CHECK: call void asm sideeffect "", "~{$fcc0}"() -+// CHECK: call void asm sideeffect "", "~{$fcc7}"() -+void test_fcc() { -+ asm ("" ::: "$fcc0"); -+ asm ("" ::: "$fcc7"); -+} -diff --git a/clang/test/Driver/fpatchable-function-entry.c b/clang/test/Driver/fpatchable-function-entry.c -index da7370a4d..4d0d60958 100644 ---- a/clang/test/Driver/fpatchable-function-entry.c -+++ b/clang/test/Driver/fpatchable-function-entry.c -@@ -2,6 +2,8 @@ - // RUN: %clang -target x86_64 %s -fpatchable-function-entry=1 -c -### 2>&1 | FileCheck %s - // RUN: %clang -target aarch64 %s -fpatchable-function-entry=1 -c -### 2>&1 | FileCheck %s - // RUN: %clang -target aarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s -+// RUN: %clang -target loongarch32 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s -+// RUN: %clang -target loongarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s - // RUN: %clang -target riscv32 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s - // RUN: %clang -target riscv64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s - // CHECK: "-fpatchable-function-entry=1" -diff --git a/clang/test/Driver/loongarch-as.s b/clang/test/Driver/loongarch-as.s -new file mode 100644 -index 000000000..6f6d87f6a ---- /dev/null -+++ b/clang/test/Driver/loongarch-as.s -@@ -0,0 +1,15 @@ -+/// This file checks options are correctly passed to as for LoongArch targets. -+ -+/// Check `-mabi`. -+// RUN: %clang --target=loongarch64 -### -fno-integrated-as -c %s 2>&1 | \ -+// RUN: FileCheck -DABI=lp64d --check-prefix=ABI %s -+// RUN: %clang --target=loongarch64 -mabi=lp64d -### -fno-integrated-as -c %s 2>&1 | \ -+// RUN: FileCheck -DABI=lp64d --check-prefix=ABI %s -+// RUN: %clang --target=loongarch64 -mabi=lp64f -### -fno-integrated-as -c %s 2>&1 | \ -+// RUN: FileCheck -DABI=lp64f --check-prefix=ABI %s -+// RUN: %clang --target=loongarch64 -mabi=lp64s -### -fno-integrated-as -c %s 2>&1 | \ -+// RUN: FileCheck -DABI=lp64s --check-prefix=ABI %s -+ -+// ALL: as -+ -+// ABI: "-mabi=[[ABI]]" -diff --git a/clang/test/Driver/loongarch-default-features.c b/clang/test/Driver/loongarch-default-features.c -index 027d8cdb7..3cdf3ba3d 100644 ---- a/clang/test/Driver/loongarch-default-features.c -+++ b/clang/test/Driver/loongarch-default-features.c -@@ -2,7 +2,7 @@ - // RUN: %clang --target=loongarch64 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA64 - - // LA32: "target-features"="+32bit" --// LA64: "target-features"="+64bit,+d,+f" -+// LA64: "target-features"="+64bit,+d,+f,+ual" - - int foo(void) { - return 3; -diff --git a/clang/test/Driver/loongarch-ias.s b/clang/test/Driver/loongarch-ias.s -new file mode 100644 -index 000000000..6fec9e6e1 ---- /dev/null -+++ b/clang/test/Driver/loongarch-ias.s -@@ -0,0 +1,23 @@ -+/// This file checks options are correctly passed to cc1as for LoongArch targets. -+ -+/// Check `-target-abi`. -+// RUN: %clang --target=loongarch32 -### -fintegrated-as -c %s 2>&1 | \ -+// RUN: FileCheck -DABI=ilp32d --check-prefix=ABI %s -+// RUN: %clang --target=loongarch32 -mabi=ilp32d -### -fintegrated-as -c %s 2>&1 | \ -+// RUN: FileCheck -DABI=ilp32d --check-prefix=ABI %s -+// RUN: %clang --target=loongarch32 -mabi=ilp32f -### -fintegrated-as -c %s 2>&1 | \ -+// RUN: FileCheck -DABI=ilp32f --check-prefix=ABI %s -+// RUN: %clang --target=loongarch32 -mabi=ilp32s -### -fintegrated-as -c %s 2>&1 | \ -+// RUN: FileCheck -DABI=ilp32s --check-prefix=ABI %s -+// RUN: %clang --target=loongarch64 -### -fintegrated-as -c %s 2>&1 | \ -+// RUN: FileCheck -DABI=lp64d --check-prefix=ABI %s -+// RUN: %clang --target=loongarch64 -mabi=lp64d -### -fintegrated-as -c %s 2>&1 | \ -+// RUN: FileCheck -DABI=lp64d --check-prefix=ABI %s -+// RUN: %clang --target=loongarch64 -mabi=lp64f -### -fintegrated-as -c %s 2>&1 | \ -+// RUN: FileCheck -DABI=lp64f --check-prefix=ABI %s -+// RUN: %clang --target=loongarch64 -mabi=lp64s -### -fintegrated-as -c %s 2>&1 | \ -+// RUN: FileCheck -DABI=lp64s --check-prefix=ABI %s -+ -+// ALL: -cc1as -+ -+// ABI: "-target-abi" "[[ABI]]" -diff --git a/clang/test/Driver/loongarch-march-error.c b/clang/test/Driver/loongarch-march-error.c -index f447de655..6bfaa18b0 100644 ---- a/clang/test/Driver/loongarch-march-error.c -+++ b/clang/test/Driver/loongarch-march-error.c -@@ -1,7 +1,7 @@ - // RUN: not %clang --target=loongarch64 -march=loongarch -fsyntax-only %s 2>&1 | \ --// RUN: FileCheck --check-prefix=LOONGARCH %s --// LOONGARCH: error: invalid arch name '-march=loongarch' -- -+// RUN: FileCheck -DCPU=loongarch %s - // RUN: not %clang --target=loongarch64 -march=LA464 -fsyntax-only %s 2>&1 | \ --// RUN: FileCheck --check-prefix=LA464-UPPER %s --// LA464-UPPER: error: invalid arch name '-march=LA464' -+// RUN: FileCheck -DCPU=LA464 %s -+ -+// CHECK: error: unknown target CPU '[[CPU]]' -+// CHECK-NEXT: note: valid target CPU values are: {{.*}} -diff --git a/clang/test/Driver/loongarch-march.c b/clang/test/Driver/loongarch-march.c -index 6416f4274..9214130cd 100644 ---- a/clang/test/Driver/loongarch-march.c -+++ b/clang/test/Driver/loongarch-march.c -@@ -7,18 +7,20 @@ - // RUN: %clang --target=loongarch64 -march=la464 -S -emit-llvm %s -o - | \ - // RUN: FileCheck %s --check-prefix=IR-LA464 - -+// CC1-LOONGARCH64: "-target-cpu" "loongarch64" - // CC1-LOONGARCH64-NOT: "-target-feature" --// CC1-LOONGARCH64: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" -+// CC1-LOONGARCH64: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+ual" - // CC1-LOONGARCH64-NOT: "-target-feature" - // CC1-LOONGARCH64: "-target-abi" "lp64d" - -+// CC1-LA464: "-target-cpu" "la464" - // CC1-LA464-NOT: "-target-feature" --// CC1-LA464: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" -+// CC1-LA464: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" "-target-feature" "+ual" - // CC1-LA464-NOT: "-target-feature" - // CC1-LA464: "-target-abi" "lp64d" - --// IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-features"="+64bit,+d,+f" --// IR-LA464: attributes #[[#]] ={{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx" -+// IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+f,+ual" -+// IR-LA464: attributes #[[#]] ={{.*}}"target-cpu"="la464" {{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+ual" - - int foo(void) { - return 3; -diff --git a/clang/test/Driver/loongarch-mdouble-float.c b/clang/test/Driver/loongarch-mdouble-float.c -index 63bc1c911..caa9ab42c 100644 ---- a/clang/test/Driver/loongarch-mdouble-float.c -+++ b/clang/test/Driver/loongarch-mdouble-float.c -@@ -1,19 +1,23 @@ - // RUN: %clang --target=loongarch64 -mdouble-float -fsyntax-only %s -### 2>&1 | \ - // RUN: FileCheck %s --check-prefix=CC1 -+// RUN: %clang --target=loongarch64 -mdouble-float -mfpu=64 -mabi=lp64d -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefixes=CC1,NOWARN - // RUN: %clang --target=loongarch64 -mdouble-float -mfpu=0 -mabi=lp64s -fsyntax-only %s -### 2>&1 | \ --// RUN: FileCheck %s --check-prefixes=CC1,WARN -+// RUN: FileCheck %s --check-prefixes=CC1,WARN,WARN-FPU0 -+// RUN: %clang --target=loongarch64 -mdouble-float -mfpu=none -mabi=lp64s -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefixes=CC1,WARN,WARN-FPUNONE - // RUN: %clang --target=loongarch64 -mdouble-float -S -emit-llvm %s -o - | \ - // RUN: FileCheck %s --check-prefix=IR - --// WARN: warning: argument unused during compilation: '-mfpu=0' --// WARN: warning: argument unused during compilation: '-mabi=lp64s' -+// NOWARN-NOT: warning: -+// WARN: warning: ignoring '-mabi=lp64s' as it conflicts with that implied by '-mdouble-float' (lp64d) -+// WARN-FPU0: warning: ignoring '-mfpu=0' as it conflicts with that implied by '-mdouble-float' (64) -+// WARN-FPUNONE: warning: ignoring '-mfpu=none' as it conflicts with that implied by '-mdouble-float' (64) - --// CC1-NOT: "-target-feature" --// CC1: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" --// CC1-NOT: "-target-feature" -+// CC1: "-target-feature" "+f"{{.*}} "-target-feature" "+d" - // CC1: "-target-abi" "lp64d" - --// IR: attributes #[[#]] ={{.*}}"target-features"="+64bit,+d,+f" -+// IR: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}+d,{{(.*,)?}}+f{{(,.*)?}}" - - int foo(void) { - return 3; -diff --git a/clang/test/Driver/loongarch-mfpu.c b/clang/test/Driver/loongarch-mfpu.c -index 7fc7d45a7..753057d70 100644 ---- a/clang/test/Driver/loongarch-mfpu.c -+++ b/clang/test/Driver/loongarch-mfpu.c -@@ -16,24 +16,18 @@ - // RUN: %clang --target=loongarch64 -mfpu=none -S -emit-llvm %s -o - | \ - // RUN: FileCheck %s --check-prefix=IR-FPU0 - --// CC1-FPU64-NOT: "-target-feature" --// CC1-FPU64: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" --// CC1-FPU64-NOT: "-target-feature" -+// CC1-FPU64: "-target-feature" "+f"{{.*}} "-target-feature" "+d" - // CC1-FPU64: "-target-abi" "lp64d" - --// CC1-FPU32-NOT: "-target-feature" --// CC1-FPU32: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "-d" --// CC1-FPU32-NOT: "-target-feature" -+// CC1-FPU32: "-target-feature" "+f"{{.*}} "-target-feature" "-d" - // CC1-FPU32: "-target-abi" "lp64f" - --// CC1-FPU0-NOT: "-target-feature" --// CC1-FPU0: "-target-feature" "+64bit" "-target-feature" "-f" "-target-feature" "-d" --// CC1-FPU0-NOT: "-target-feature" -+// CC1-FPU0: "-target-feature" "-f"{{.*}} "-target-feature" "-d" - // CC1-FPU0: "-target-abi" "lp64s" - --// IR-FPU64: attributes #[[#]] ={{.*}}"target-features"="+64bit,+d,+f" --// IR-FPU32: attributes #[[#]] ={{.*}}"target-features"="+64bit,+f,-d" --// IR-FPU0: attributes #[[#]] ={{.*}}"target-features"="+64bit,-d,-f" -+// IR-FPU64: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}+d,{{(.*,)?}}+f{{(,.*)?}}" -+// IR-FPU32: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}+f,{{(.*,)?}}-d{{(,.*)?}}" -+// IR-FPU0: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}-d,{{(.*,)?}}-f{{(,.*)?}}" - - int foo(void) { - return 3; -diff --git a/clang/test/Driver/loongarch-msingle-float.c b/clang/test/Driver/loongarch-msingle-float.c -index 5deff8655..bd9b3e8a8 100644 ---- a/clang/test/Driver/loongarch-msingle-float.c -+++ b/clang/test/Driver/loongarch-msingle-float.c -@@ -1,19 +1,20 @@ - // RUN: %clang --target=loongarch64 -msingle-float -fsyntax-only %s -### 2>&1 | \ - // RUN: FileCheck %s --check-prefix=CC1 --// RUN: %clang --target=loongarch64 -msingle-float -mfpu=0 -mabi=lp64s -fsyntax-only %s -### 2>&1 | \ -+// RUN: %clang --target=loongarch64 -msingle-float -mfpu=32 -mabi=lp64f -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefixes=CC1,NOWARN -+// RUN: %clang --target=loongarch64 -msingle-float -mfpu=64 -mabi=lp64s -fsyntax-only %s -### 2>&1 | \ - // RUN: FileCheck %s --check-prefixes=CC1,WARN - // RUN: %clang --target=loongarch64 -msingle-float -S -emit-llvm %s -o - | \ - // RUN: FileCheck %s --check-prefix=IR - --// WARN: warning: argument unused during compilation: '-mfpu=0' --// WARN: warning: argument unused during compilation: '-mabi=lp64s' -+// NOWARN-NOT: warning: -+// WARN: warning: ignoring '-mabi=lp64s' as it conflicts with that implied by '-msingle-float' (lp64f) -+// WARN: warning: ignoring '-mfpu=64' as it conflicts with that implied by '-msingle-float' (32) - --// CC1-NOT: "-target-feature" --// CC1: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "-d" --// CC1-NOT: "-target-feature" -+// CC1: "-target-feature" "+f"{{.*}} "-target-feature" "-d" - // CC1: "-target-abi" "lp64f" - --// IR: attributes #[[#]] ={{.*}}"target-features"="+64bit,+f,-d" -+// IR: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}+f,{{(.*,)?}}-d" - - int foo(void) { - return 3; -diff --git a/clang/test/Driver/loongarch-msoft-float.c b/clang/test/Driver/loongarch-msoft-float.c -index fd200377a..0e5121ac8 100644 ---- a/clang/test/Driver/loongarch-msoft-float.c -+++ b/clang/test/Driver/loongarch-msoft-float.c -@@ -1,19 +1,20 @@ - // RUN: %clang --target=loongarch64 -msoft-float -fsyntax-only %s -### 2>&1 | \ - // RUN: FileCheck %s --check-prefix=CC1 -+// RUN: %clang --target=loongarch64 -msoft-float -mfpu=0 -mabi=lp64s -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefixes=CC1,NOWARN - // RUN: %clang --target=loongarch64 -msoft-float -mfpu=64 -mabi=lp64d -fsyntax-only %s -### 2>&1 | \ - // RUN: FileCheck %s --check-prefixes=CC1,WARN - // RUN: %clang --target=loongarch64 -msoft-float -S -emit-llvm %s -o - | \ - // RUN: FileCheck %s --check-prefix=IR - --// WARN: warning: argument unused during compilation: '-mfpu=64' --// WARN: warning: argument unused during compilation: '-mabi=lp64d' -+// NOWARN-NOT: warning: -+// WARN: warning: ignoring '-mabi=lp64d' as it conflicts with that implied by '-msoft-float' (lp64s) -+// WARN: warning: ignoring '-mfpu=64' as it conflicts with that implied by '-msoft-float' (0) - --// CC1-NOT: "-target-feature" --// CC1: "-target-feature" "+64bit" "-target-feature" "-f" "-target-feature" "-d" --// CC1-NOT: "-target-feature" -+// CC1: "-target-feature" "-f"{{.*}} "-target-feature" "-d" - // CC1: "-target-abi" "lp64s" - --// IR: attributes #[[#]] ={{.*}}"target-features"="+64bit,-d,-f" -+// IR: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}-d,{{(.*,)?}}-f{{(,.*)?}}" - - int foo(void) { - return 3; -diff --git a/clang/test/Driver/loongarch-mtune.c b/clang/test/Driver/loongarch-mtune.c -new file mode 100644 -index 000000000..6f3f39e9b ---- /dev/null -+++ b/clang/test/Driver/loongarch-mtune.c -@@ -0,0 +1,34 @@ -+// RUN: %clang --target=loongarch64 -mtune=loongarch64 -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=loongarch64 -+// RUN: %clang --target=loongarch64 -mtune=loongarch64 -S -emit-llvm %s -o - | \ -+// RUN: FileCheck %s --check-prefix=IRATTR -DCPU=loongarch64 -+ -+// RUN: %clang --target=loongarch64 -mtune=la464 -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=la464 -+// RUN: %clang --target=loongarch64 -mtune=la464 -S -emit-llvm %s -o - | \ -+// RUN: FileCheck %s --check-prefix=IRATTR -DCPU=la464 -+ -+// RUN: %clang --target=loongarch64 -mtune=invalidcpu -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=invalidcpu -+// RUN: not %clang --target=loongarch64 -mtune=invalidcpu -S -emit-llvm %s -o /dev/null 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=ERROR -DCPU=invalidcpu -+ -+// RUN: %clang --target=loongarch64 -mtune=generic -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=generic -+// RUN: not %clang --target=loongarch64 -mtune=generic -S -emit-llvm %s -o /dev/null 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=ERROR -DCPU=generic -+ -+// RUN: %clang --target=loongarch64 -mtune=generic-la64 -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=generic-la64 -+// RUN: not %clang --target=loongarch64 -mtune=generic-la64 -S -emit-llvm %s -o /dev/null 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=ERROR -DCPU=generic-la64 -+ -+// CC1ARG: "-tune-cpu" "[[CPU]]" -+// IRATTR: "tune-cpu"="[[CPU]]" -+ -+// ERROR: error: unknown target CPU '[[CPU]]' -+// ERROR-NEXT: note: valid target CPU values are: {{.*}} -+ -+int foo(void) { -+ return 3; -+} -diff --git a/clang/test/Driver/loongarch-munaligned-access.c b/clang/test/Driver/loongarch-munaligned-access.c -new file mode 100644 -index 000000000..44edb2eb1 ---- /dev/null -+++ b/clang/test/Driver/loongarch-munaligned-access.c -@@ -0,0 +1,61 @@ -+/// Test -m[no-]unaligned-access and -m[no-]strict-align options. -+ -+// RUN: %clang --target=loongarch64 -munaligned-access -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1-UNALIGNED -+// RUN: %clang --target=loongarch64 -mno-unaligned-access -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1-NO-UNALIGNED -+// RUN: %clang --target=loongarch64 -mstrict-align -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1-NO-UNALIGNED -+// RUN: %clang --target=loongarch64 -mno-strict-align -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1-UNALIGNED -+// RUN: %clang --target=loongarch64 -munaligned-access -mno-unaligned-access -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1-NO-UNALIGNED -+// RUN: %clang --target=loongarch64 -mno-unaligned-access -munaligned-access -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1-UNALIGNED -+// RUN: %clang --target=loongarch64 -mstrict-align -mno-strict-align -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1-UNALIGNED -+// RUN: %clang --target=loongarch64 -mno-strict-align -mstrict-align -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1-NO-UNALIGNED -+// RUN: %clang --target=loongarch64 -munaligned-access -mstrict-align -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1-NO-UNALIGNED -+// RUN: %clang --target=loongarch64 -mstrict-align -munaligned-access -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1-UNALIGNED -+// RUN: %clang --target=loongarch64 -mno-unaligned-access -mno-strict-align -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1-UNALIGNED -+// RUN: %clang --target=loongarch64 -mno-strict-align -mno-unaligned-access -fsyntax-only %s -### 2>&1 | \ -+// RUN: FileCheck %s --check-prefix=CC1-NO-UNALIGNED -+ -+// RUN: %clang --target=loongarch64 -munaligned-access -S -emit-llvm %s -o - | \ -+// RUN: FileCheck %s --check-prefix=IR-UNALIGNED -+// RUN: %clang --target=loongarch64 -mno-unaligned-access -S -emit-llvm %s -o - | \ -+// RUN: FileCheck %s --check-prefix=IR-NO-UNALIGNED -+// RUN: %clang --target=loongarch64 -mstrict-align -S -emit-llvm %s -o - | \ -+// RUN: FileCheck %s --check-prefix=IR-NO-UNALIGNED -+// RUN: %clang --target=loongarch64 -mno-strict-align -S -emit-llvm %s -o - | \ -+// RUN: FileCheck %s --check-prefix=IR-UNALIGNED -+// RUN: %clang --target=loongarch64 -munaligned-access -mno-unaligned-access -S -emit-llvm %s -o - | \ -+// RUN: FileCheck %s --check-prefix=IR-NO-UNALIGNED -+// RUN: %clang --target=loongarch64 -mno-unaligned-access -munaligned-access -S -emit-llvm %s -o - | \ -+// RUN: FileCheck %s --check-prefix=IR-UNALIGNED -+// RUN: %clang --target=loongarch64 -mstrict-align -mno-strict-align -S -emit-llvm %s -o - | \ -+// RUN: FileCheck %s --check-prefix=IR-UNALIGNED -+// RUN: %clang --target=loongarch64 -mno-strict-align -mstrict-align -S -emit-llvm %s -o - | \ -+// RUN: FileCheck %s --check-prefix=IR-NO-UNALIGNED -+// RUN: %clang --target=loongarch64 -munaligned-access -mstrict-align -S -emit-llvm %s -o - | \ -+// RUN: FileCheck %s --check-prefix=IR-NO-UNALIGNED -+// RUN: %clang --target=loongarch64 -mstrict-align -munaligned-access -S -emit-llvm %s -o - | \ -+// RUN: FileCheck %s --check-prefix=IR-UNALIGNED -+// RUN: %clang --target=loongarch64 -mno-unaligned-access -mno-strict-align -S -emit-llvm %s -o - | \ -+// RUN: FileCheck %s --check-prefix=IR-UNALIGNED -+// RUN: %clang --target=loongarch64 -mno-strict-align -mno-unaligned-access -S -emit-llvm %s -o - | \ -+// RUN: FileCheck %s --check-prefix=IR-NO-UNALIGNED -+ -+// CC1-UNALIGNED: "-target-feature" "+ual" -+// CC1-NO-UNALIGNED: "-target-feature" "-ual" -+ -+// IR-UNALIGNED: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}+ual{{(,.*)?}}" -+// IR-NO-UNALIGNED: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}-ual{{(,.*)?}}" -+ -+int foo(void) { -+ return 3; -+} -diff --git a/clang/test/Driver/munaligned-access-unused.c b/clang/test/Driver/munaligned-access-unused.c -new file mode 100644 -index 000000000..c8cbe4e0d ---- /dev/null -+++ b/clang/test/Driver/munaligned-access-unused.c -@@ -0,0 +1,8 @@ -+/// Check -m[no-]unaligned-access and -m[no-]strict-align are warned unused on a target that does not support them. -+ -+// RUN: %clang --target=x86_64 -munaligned-access -fsyntax-only %s -### 2>&1 | FileCheck %s -DOPTION=unaligned-access -+// RUN: %clang --target=x86_64 -mno-unaligned-access -fsyntax-only %s -### 2>&1 | FileCheck %s -DOPTION=no-unaligned-access -+// RUN: %clang --target=x86_64 -mstrict-align -fsyntax-only %s -### 2>&1 | FileCheck %s -DOPTION=strict-align -+// RUN: %clang --target=x86_64 -mno-strict-align -fsyntax-only %s -### 2>&1 | FileCheck %s -DOPTION=no-strict-align -+ -+// CHECK: warning: argument unused during compilation: '-m[[OPTION]]' [-Wunused-command-line-argument] -diff --git a/clang/test/Preprocessor/init-loongarch.c b/clang/test/Preprocessor/init-loongarch.c -index 686c96813..4ef42a921 100644 ---- a/clang/test/Preprocessor/init-loongarch.c -+++ b/clang/test/Preprocessor/init-loongarch.c -@@ -3,16 +3,16 @@ - // RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple loongarch32-unknown-linux /dev/null \ - // RUN: | FileCheck --match-full-lines --check-prefixes=LA32,LA32-LINUX %s - // RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple loongarch32 \ --// RUN: -fforce-enable-int128 /dev/null | FileCheck --match-full-lines \ --// RUN: --check-prefixes=LA32,LA32-INT128 %s -+// RUN: -fforce-enable-int128 /dev/null | FileCheck --match-full-lines \ -+// RUN: --check-prefixes=LA32,LA32-INT128 %s - - // RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple loongarch64 /dev/null \ - // RUN: | FileCheck --match-full-lines --check-prefix=LA64 %s - // RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple loongarch64-unknown-linux /dev/null \ - // RUN: | FileCheck --match-full-lines --check-prefixes=LA64,LA64-LINUX %s - // RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple loongarch64 \ --// RUN: -fforce-enable-int128 /dev/null | FileCheck --match-full-lines \ --// RUN: --check-prefixes=LA64,LA64-INT128 %s -+// RUN: -fforce-enable-int128 /dev/null | FileCheck --match-full-lines \ -+// RUN: --check-prefixes=LA64,LA64-INT128 %s - - //// Note that common macros are tested in init.c, such as __VERSION__. So they're not listed here. - -@@ -650,141 +650,160 @@ - // LA64-LINUX: #define unix 1 - - --/// Check various macros prefixed with "__loongarch_" in different cases. --/// "__loongarch__"" is not listed here as it has been checked above. -+/// Check __loongarch_{double,single,hard,soft}_float, __loongarch_{gr,fr}len, __loongarch_lp64. - - // RUN: %clang --target=loongarch32 -mfpu=64 -mabi=ilp32d -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU64-ILP32D %s -+// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU64-ILP32D %s - // RUN: %clang --target=loongarch32 -mdouble-float -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU64-ILP32D %s --// LA32-FPU64-ILP32D: __loongarch_double_float 1 --// LA32-FPU64-ILP32D-NEXT: __loongarch_frlen 64 --// LA32-FPU64-ILP32D-NEXT: __loongarch_grlen 32 --// LA32-FPU64-ILP32D-NEXT: __loongarch_hard_float 1 --// LA32-FPU64-ILP32D-NOT: __loongarch_lp64 --// LA32-FPU64-ILP32D-NOT: __loongarch_single_float --// LA32-FPU64-ILP32D-NOT: __loongarch_soft_float -+// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU64-ILP32D %s -+// LA32-FPU64-ILP32D: #define __loongarch_double_float 1 -+// LA32-FPU64-ILP32D: #define __loongarch_frlen 64 -+// LA32-FPU64-ILP32D: #define __loongarch_grlen 32 -+// LA32-FPU64-ILP32D: #define __loongarch_hard_float 1 -+// LA32-FPU64-ILP32D-NOT: #define __loongarch_lp64 -+// LA32-FPU64-ILP32D-NOT: #define __loongarch_single_float -+// LA32-FPU64-ILP32D-NOT: #define __loongarch_soft_float - - // RUN: %clang --target=loongarch32 -mfpu=64 -mabi=ilp32f -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU64-ILP32F %s --// LA32-FPU64-ILP32F-NOT: __loongarch_double_float --// LA32-FPU64-ILP32F: __loongarch_frlen 64 --// LA32-FPU64-ILP32F-NEXT: __loongarch_grlen 32 --// LA32-FPU64-ILP32F-NEXT: __loongarch_hard_float 1 --// LA32-FPU64-ILP32F-NOT: __loongarch_lp64 --// LA32-FPU64-ILP32F-NEXT: __loongarch_single_float 1 --// LA32-FPU64-ILP32F-NOT: __loongarch_soft_float -+// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU64-ILP32F %s -+// LA32-FPU64-ILP32F-NOT: #define __loongarch_double_float -+// LA32-FPU64-ILP32F: #define __loongarch_frlen 64 -+// LA32-FPU64-ILP32F: #define __loongarch_grlen 32 -+// LA32-FPU64-ILP32F: #define __loongarch_hard_float 1 -+// LA32-FPU64-ILP32F-NOT: #define __loongarch_lp64 -+// LA32-FPU64-ILP32F: #define __loongarch_single_float 1 -+// LA32-FPU64-ILP32F-NOT: #define __loongarch_soft_float - - // RUN: %clang --target=loongarch32 -mfpu=64 -mabi=ilp32s -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU64-ILP32S %s --// LA32-FPU64-ILP32S-NOT: __loongarch_double_float --// LA32-FPU64-ILP32S: __loongarch_frlen 64 --// LA32-FPU64-ILP32S-NEXT: __loongarch_grlen 32 --// LA32-FPU64-ILP32S-NOT: __loongarch_hard_float --// LA32-FPU64-ILP32S-NOT: __loongarch_lp64 --// LA32-FPU64-ILP32S-NOT: __loongarch_single_float --// LA32-FPU64-ILP32S-NEXT: __loongarch_soft_float 1 -+// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU64-ILP32S %s -+// LA32-FPU64-ILP32S-NOT: #define __loongarch_double_float -+// LA32-FPU64-ILP32S: #define __loongarch_frlen 64 -+// LA32-FPU64-ILP32S: #define __loongarch_grlen 32 -+// LA32-FPU64-ILP32S-NOT: #define __loongarch_hard_float -+// LA32-FPU64-ILP32S-NOT: #define __loongarch_lp64 -+// LA32-FPU64-ILP32S-NOT: #define __loongarch_single_float -+// LA32-FPU64-ILP32S: #define __loongarch_soft_float 1 - - // RUN: %clang --target=loongarch32 -mfpu=32 -mabi=ilp32f -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU32-ILP32F %s -+// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU32-ILP32F %s - // RUN: %clang --target=loongarch32 -msingle-float -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU32-ILP32F %s --// LA32-FPU32-ILP32F-NOT: __loongarch_double_float --// LA32-FPU32-ILP32F: __loongarch_frlen 32 --// LA32-FPU32-ILP32F-NEXT: __loongarch_grlen 32 --// LA32-FPU32-ILP32F-NEXT: __loongarch_hard_float 1 --// LA32-FPU32-ILP32F-NOT: __loongarch_lp64 --// LA32-FPU32-ILP32F-NEXT: __loongarch_single_float 1 --// LA32-FPU32-ILP32F-NOT: __loongarch_soft_float -+// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU32-ILP32F %s -+// LA32-FPU32-ILP32F-NOT: #define __loongarch_double_float -+// LA32-FPU32-ILP32F: #define __loongarch_frlen 32 -+// LA32-FPU32-ILP32F: #define __loongarch_grlen 32 -+// LA32-FPU32-ILP32F: #define __loongarch_hard_float 1 -+// LA32-FPU32-ILP32F-NOT: #define __loongarch_lp64 -+// LA32-FPU32-ILP32F: #define __loongarch_single_float 1 -+// LA32-FPU32-ILP32F-NOT: #define __loongarch_soft_float - - // RUN: %clang --target=loongarch32 -mfpu=32 -mabi=ilp32s -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU32-ILP32S %s --// LA32-FPU32-ILP32S-NOT: __loongarch_double_float --// LA32-FPU32-ILP32S: __loongarch_frlen 32 --// LA32-FPU32-ILP32S-NEXT: __loongarch_grlen 32 --// LA32-FPU32-ILP32S-NOT: __loongarch_hard_float --// LA32-FPU32-ILP32S-NOT: __loongarch_lp64 --// LA32-FPU32-ILP32S-NOT: __loongarch_single_float --// LA32-FPU32-ILP32S-NEXT: __loongarch_soft_float 1 -+// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU32-ILP32S %s -+// LA32-FPU32-ILP32S-NOT: #define __loongarch_double_float -+// LA32-FPU32-ILP32S: #define __loongarch_frlen 32 -+// LA32-FPU32-ILP32S: #define __loongarch_grlen 32 -+// LA32-FPU32-ILP32S-NOT: #define __loongarch_hard_float -+// LA32-FPU32-ILP32S-NOT: #define __loongarch_lp64 -+// LA32-FPU32-ILP32S-NOT: #define __loongarch_single_float -+// LA32-FPU32-ILP32S: #define __loongarch_soft_float 1 - - // RUN: %clang --target=loongarch32 -mfpu=0 -mabi=ilp32s -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU0-ILP32S %s -+// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU0-ILP32S %s - // RUN: %clang --target=loongarch32 -mfpu=none -mabi=ilp32s -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU0-ILP32S %s -+// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU0-ILP32S %s - // RUN: %clang --target=loongarch32 -msoft-float -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU0-ILP32S %s --// LA32-FPU0-ILP32S-NOT: __loongarch_double_float --// LA32-FPU0-ILP32S: __loongarch_frlen 0 --// LA32-FPU0-ILP32S-NEXT: __loongarch_grlen 32 --// LA32-FPU0-ILP32S-NOT: __loongarch_hard_float --// LA32-FPU0-ILP32S-NOT: __loongarch_lp64 --// LA32-FPU0-ILP32S-NOT: __loongarch_single_float --// LA32-FPU0-ILP32S-NEXT: __loongarch_soft_float 1 -+// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU0-ILP32S %s -+// LA32-FPU0-ILP32S-NOT: #define __loongarch_double_float -+// LA32-FPU0-ILP32S: #define __loongarch_frlen 0 -+// LA32-FPU0-ILP32S: #define __loongarch_grlen 32 -+// LA32-FPU0-ILP32S-NOT: #define __loongarch_hard_float -+// LA32-FPU0-ILP32S-NOT: #define __loongarch_lp64 -+// LA32-FPU0-ILP32S-NOT: #define __loongarch_single_float -+// LA32-FPU0-ILP32S: #define __loongarch_soft_float 1 - - // RUN: %clang --target=loongarch64 -mfpu=64 -mabi=lp64d -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU64-LP64D %s -+// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU64-LP64D %s - // RUN: %clang --target=loongarch64 -mdouble-float -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU64-LP64D %s --// LA64-FPU64-LP64D: __loongarch_double_float 1 --// LA64-FPU64-LP64D-NEXT: __loongarch_frlen 64 --// LA64-FPU64-LP64D-NEXT: __loongarch_grlen 64 --// LA64-FPU64-LP64D-NEXT: __loongarch_hard_float 1 --// LA64-FPU64-LP64D-NEXT: __loongarch_lp64 1 --// LA64-FPU64-LP64D-NOT: __loongarch_single_float --// LA64-FPU64-LP64D-NOT: __loongarch_soft_float -+// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU64-LP64D %s -+// LA64-FPU64-LP64D: #define __loongarch_double_float 1 -+// LA64-FPU64-LP64D: #define __loongarch_frlen 64 -+// LA64-FPU64-LP64D: #define __loongarch_grlen 64 -+// LA64-FPU64-LP64D: #define __loongarch_hard_float 1 -+// LA64-FPU64-LP64D: #define __loongarch_lp64 1 -+// LA64-FPU64-LP64D-NOT: #define __loongarch_single_float -+// LA64-FPU64-LP64D-NOT: #define __loongarch_soft_float - - // RUN: %clang --target=loongarch64 -mfpu=64 -mabi=lp64f -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU64-LP64F %s --// LA64-FPU64-LP64F-NOT: __loongarch_double_float --// LA64-FPU64-LP64F: __loongarch_frlen 64 --// LA64-FPU64-LP64F-NEXT: __loongarch_grlen 64 --// LA64-FPU64-LP64F-NEXT: __loongarch_hard_float 1 --// LA64-FPU64-LP64F-NEXT: __loongarch_lp64 1 --// LA64-FPU64-LP64F-NEXT: __loongarch_single_float 1 --// LA64-FPU64-LP64F-NOT: __loongarch_soft_float -+// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU64-LP64F %s -+// LA64-FPU64-LP64F-NOT: #define __loongarch_double_float -+// LA64-FPU64-LP64F: #define __loongarch_frlen 64 -+// LA64-FPU64-LP64F: #define __loongarch_grlen 64 -+// LA64-FPU64-LP64F: #define __loongarch_hard_float 1 -+// LA64-FPU64-LP64F: #define __loongarch_lp64 1 -+// LA64-FPU64-LP64F: #define __loongarch_single_float 1 -+// LA64-FPU64-LP64F-NOT: #define __loongarch_soft_float - - // RUN: %clang --target=loongarch64 -mfpu=64 -mabi=lp64s -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU64-LP64S %s --// LA64-FPU64-LP64S-NOT: __loongarch_double_float --// LA64-FPU64-LP64S: __loongarch_frlen 64 --// LA64-FPU64-LP64S-NEXT: __loongarch_grlen 64 --// LA64-FPU64-LP64S-NOT: __loongarch_hard_float --// LA64-FPU64-LP64S-NEXT: __loongarch_lp64 1 --// LA64-FPU64-LP64S-NOT: __loongarch_single_float --// LA64-FPU64-LP64S-NEXT: __loongarch_soft_float 1 -+// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU64-LP64S %s -+// LA64-FPU64-LP64S-NOT: #define __loongarch_double_float -+// LA64-FPU64-LP64S: #define __loongarch_frlen 64 -+// LA64-FPU64-LP64S: #define __loongarch_grlen 64 -+// LA64-FPU64-LP64S-NOT: #define __loongarch_hard_float -+// LA64-FPU64-LP64S: #define __loongarch_lp64 1 -+// LA64-FPU64-LP64S-NOT: #define __loongarch_single_float -+// LA64-FPU64-LP64S: #define __loongarch_soft_float 1 - - // RUN: %clang --target=loongarch64 -mfpu=32 -mabi=lp64f -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU32-LP64F %s -+// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU32-LP64F %s - // RUN: %clang --target=loongarch64 -msingle-float -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU32-LP64F %s --// LA64-FPU32-LP64F-NOT: __loongarch_double_float --// LA64-FPU32-LP64F: __loongarch_frlen 32 --// LA64-FPU32-LP64F-NEXT: __loongarch_grlen 64 --// LA64-FPU32-LP64F-NEXT: __loongarch_hard_float 1 --// LA64-FPU32-LP64F-NEXT: __loongarch_lp64 1 --// LA64-FPU32-LP64F-NEXT: __loongarch_single_float 1 --// LA64-FPU32-LP64F-NOT: __loongarch_soft_float -+// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU32-LP64F %s -+// LA64-FPU32-LP64F-NOT: #define __loongarch_double_float -+// LA64-FPU32-LP64F: #define __loongarch_frlen 32 -+// LA64-FPU32-LP64F: #define __loongarch_grlen 64 -+// LA64-FPU32-LP64F: #define __loongarch_hard_float 1 -+// LA64-FPU32-LP64F: #define __loongarch_lp64 1 -+// LA64-FPU32-LP64F: #define __loongarch_single_float 1 -+// LA64-FPU32-LP64F-NOT: #define __loongarch_soft_float - - // RUN: %clang --target=loongarch64 -mfpu=32 -mabi=lp64s -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU32-LP64S %s --// LA64-FPU32-LP64S-NOT: __loongarch_double_float --// LA64-FPU32-LP64S: __loongarch_frlen 32 --// LA64-FPU32-LP64S-NEXT: __loongarch_grlen 64 --// LA64-FPU32-LP64S-NOT: __loongarch_hard_float --// LA64-FPU32-LP64S-NEXT: __loongarch_lp64 1 --// LA64-FPU32-LP64S-NOT: __loongarch_single_float --// LA64-FPU32-LP64S-NEXT: __loongarch_soft_float 1 -+// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU32-LP64S %s -+// LA64-FPU32-LP64S-NOT: #define __loongarch_double_float -+// LA64-FPU32-LP64S: #define __loongarch_frlen 32 -+// LA64-FPU32-LP64S: #define __loongarch_grlen 64 -+// LA64-FPU32-LP64S-NOT: #define __loongarch_hard_float -+// LA64-FPU32-LP64S: #define __loongarch_lp64 1 -+// LA64-FPU32-LP64S-NOT: #define __loongarch_single_float -+// LA64-FPU32-LP64S: #define __loongarch_soft_float 1 - - // RUN: %clang --target=loongarch64 -mfpu=0 -mabi=lp64s -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU0-LP64S %s -+// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU0-LP64S %s - // RUN: %clang --target=loongarch64 -mfpu=none -mabi=lp64s -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU0-LP64S %s -+// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU0-LP64S %s - // RUN: %clang --target=loongarch64 -msoft-float -x c -E -dM %s -o - \ --// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU0-LP64S %s --// LA64-FPU0-LP64S-NOT: __loongarch_double_float --// LA64-FPU0-LP64S: __loongarch_frlen 0 --// LA64-FPU0-LP64S-NEXT: __loongarch_grlen 64 --// LA64-FPU0-LP64S-NOT: __loongarch_hard_float --// LA64-FPU0-LP64S-NEXT: __loongarch_lp64 1 --// LA64-FPU0-LP64S-NOT: __loongarch_single_float --// LA64-FPU0-LP64S-NEXT: __loongarch_soft_float 1 -+// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU0-LP64S %s -+// LA64-FPU0-LP64S-NOT: #define __loongarch_double_float -+// LA64-FPU0-LP64S: #define __loongarch_frlen 0 -+// LA64-FPU0-LP64S: #define __loongarch_grlen 64 -+// LA64-FPU0-LP64S-NOT: #define __loongarch_hard_float -+// LA64-FPU0-LP64S: #define __loongarch_lp64 1 -+// LA64-FPU0-LP64S-NOT: #define __loongarch_single_float -+// LA64-FPU0-LP64S: #define __loongarch_soft_float 1 -+ -+/// Check __loongarch_arch and __loongarch_tune. -+ -+// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - | \ -+// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=loongarch64 %s -+// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 | \ -+// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=loongarch64 %s -+// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la464 | \ -+// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la464 -DTUNE=la464 %s -+// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -mtune=loongarch64 | \ -+// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=loongarch64 %s -+// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -mtune=la464 | \ -+// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=la464 %s -+// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -mtune=la464 | \ -+// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=la464 %s -+// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la464 -mtune=loongarch64 | \ -+// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la464 -DTUNE=loongarch64 %s -+ -+// ARCH-TUNE: #define __loongarch_arch "[[ARCH]]" -+// ARCH-TUNE: #define __loongarch_tune "[[TUNE]]" -diff --git a/clang/test/Sema/patchable-function-entry-attr.cpp b/clang/test/Sema/patchable-function-entry-attr.cpp -index 3dd050498..9134c851d 100644 ---- a/clang/test/Sema/patchable-function-entry-attr.cpp -+++ b/clang/test/Sema/patchable-function-entry-attr.cpp -@@ -2,6 +2,8 @@ - // RUN: %clang_cc1 -triple aarch64_be -fsyntax-only -verify=silence %s - // RUN: %clang_cc1 -triple i386 -fsyntax-only -verify=silence %s - // RUN: %clang_cc1 -triple x86_64 -fsyntax-only -verify=silence %s -+// RUN: %clang_cc1 -triple loongarch32 -fsyntax-only -verify=silence %s -+// RUN: %clang_cc1 -triple loongarch64 -fsyntax-only -verify=silence %s - // RUN: %clang_cc1 -triple riscv32 -fsyntax-only -verify=silence %s - // RUN: %clang_cc1 -triple riscv64 -fsyntax-only -verify=silence %s - // RUN: %clang_cc1 -triple ppc64le -fsyntax-only -verify %s diff --git a/0001-clang-tools-extra-Make-test-dependency-on-LLVMHello-.patch b/0001-clang-tools-extra-Make-test-dependency-on-LLVMHello-.patch index a0b8cb03cc0406e63f164b0b3afb4d335359ea12..36392f9ea256386009f3fb160eec5d24f99e1fa3 100644 --- a/0001-clang-tools-extra-Make-test-dependency-on-LLVMHello-.patch +++ b/0001-clang-tools-extra-Make-test-dependency-on-LLVMHello-.patch @@ -55,19 +55,19 @@ index c66a94f458cf..b4e7a5d691e5 100644 // CHECK-LIST: Enabled checks: // CHECK-LIST-NEXT: mytest1 diff --git a/clang-tools-extra/test/lit.cfg.py b/clang-tools-extra/test/lit.cfg.py -index 9b99bfd93440..3fca9f25fb48 100644 +index 9f64fd3d2ffa..1b258a00ddf9 100644 --- a/clang-tools-extra/test/lit.cfg.py +++ b/clang-tools-extra/test/lit.cfg.py -@@ -59,6 +59,9 @@ config.substitutions.append( - # Plugins (loadable modules) +@@ -75,6 +75,9 @@ config.substitutions.append(("%clang_tidy_headers", clang_tidy_headers)) if config.has_plugins and config.llvm_plugin_ext: - config.available_features.add('plugins') -+ + config.available_features.add("plugins") + +if config.has_llvm_hello: + config.available_features.add("llvm-hello") - ++ # It is not realistically possible to account for all options that could # possibly be present in system and user configuration files, so disable + # default configs for the test runs. diff --git a/clang-tools-extra/test/lit.site.cfg.py.in b/clang-tools-extra/test/lit.site.cfg.py.in index 4eb830a1baf1..6e5559348454 100644 --- a/clang-tools-extra/test/lit.site.cfg.py.in @@ -81,5 +81,5 @@ index 4eb830a1baf1..6e5559348454 100644 # used when we can't determine the tool dir at configuration time. config.llvm_tools_dir = lit_config.substitute("@LLVM_TOOLS_DIR@") -- -2.27.0 +2.40.1 diff --git a/0002-LoongArch-fix-symbol-lookup-error.patch b/0002-LoongArch-fix-symbol-lookup-error.patch deleted file mode 100644 index d04f88c1a9e06d1b00093b734aa42802ac6d4721..0000000000000000000000000000000000000000 --- a/0002-LoongArch-fix-symbol-lookup-error.patch +++ /dev/null @@ -1,834 +0,0 @@ -diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp -index 96ef29620..b34ce4f4c 100644 ---- a/clang/lib/Basic/Targets/LoongArch.cpp -+++ b/clang/lib/Basic/Targets/LoongArch.cpp -@@ -14,8 +14,8 @@ - #include "clang/Basic/Diagnostic.h" - #include "clang/Basic/MacroBuilder.h" - #include "clang/Basic/TargetBuiltins.h" -+#include "llvm/Support/TargetParser.h" - #include "llvm/Support/raw_ostream.h" --#include "llvm/TargetParser/LoongArchTargetParser.h" - - using namespace clang; - using namespace clang::targets; -@@ -188,15 +188,7 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts, - else - Builder.defineMacro("__loongarch_frlen", "0"); - -- // Define __loongarch_arch. -- StringRef ArchName = getCPU(); -- Builder.defineMacro("__loongarch_arch", Twine('"') + ArchName + Twine('"')); -- -- // Define __loongarch_tune. -- StringRef TuneCPU = getTargetOpts().TuneCPU; -- if (TuneCPU.empty()) -- TuneCPU = ArchName; -- Builder.defineMacro("__loongarch_tune", Twine('"') + TuneCPU + Twine('"')); -+ // TODO: define __loongarch_arch and __loongarch_tune. - - StringRef ABI = getABI(); - if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s") -@@ -268,12 +260,3 @@ bool LoongArchTargetInfo::handleTargetFeatures( - } - return true; - } -- --bool LoongArchTargetInfo::isValidCPUName(StringRef Name) const { -- return llvm::LoongArch::isValidCPUName(Name); --} -- --void LoongArchTargetInfo::fillValidCPUList( -- SmallVectorImpl &Values) const { -- llvm::LoongArch::fillValidCPUList(Values); --} -diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h -index 46ce56b43..646c8d071 100644 ---- a/clang/lib/Basic/Targets/LoongArch.h -+++ b/clang/lib/Basic/Targets/LoongArch.h -@@ -24,7 +24,6 @@ namespace targets { - class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { - protected: - std::string ABI; -- std::string CPU; - bool HasFeatureD; - bool HasFeatureF; - -@@ -41,15 +40,6 @@ public: - WIntType = UnsignedInt; - } - -- bool setCPU(const std::string &Name) override { -- if (!isValidCPUName(Name)) -- return false; -- CPU = Name; -- return true; -- } -- -- StringRef getCPU() const { return CPU; } -- - StringRef getABI() const override { return ABI; } - - void getTargetDefines(const LangOptions &Opts, -@@ -90,9 +80,6 @@ public: - const std::vector &FeaturesVec) const override; - - bool hasFeature(StringRef Feature) const override; -- -- bool isValidCPUName(StringRef Name) const override; -- void fillValidCPUList(SmallVectorImpl &Values) const override; - }; - - class LLVM_LIBRARY_VISIBILITY LoongArch32TargetInfo -diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp -index f5d4018a4..4619b4214 100644 ---- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp -+++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp -@@ -12,8 +12,7 @@ - #include "clang/Driver/Driver.h" - #include "clang/Driver/DriverDiagnostic.h" - #include "clang/Driver/Options.h" --#include "llvm/TargetParser/Host.h" --#include "llvm/TargetParser/LoongArchTargetParser.h" -+#include "llvm/Support/LoongArchTargetParser.h" - - using namespace clang::driver; - using namespace clang::driver::tools; -@@ -99,18 +98,53 @@ StringRef loongarch::getLoongArchABI(const Driver &D, const ArgList &Args, - } - - // Choose a default based on the triple. -- return IsLA32 ? "ilp32d" : "lp64d"; -+ // Honor the explicit ABI modifier suffix in triple's environment part if -+ // present, falling back to {ILP32,LP64}D otherwise. -+ switch (Triple.getEnvironment()) { -+ case llvm::Triple::GNUSF: -+ return IsLA32 ? "ilp32s" : "lp64s"; -+ case llvm::Triple::GNUF32: -+ return IsLA32 ? "ilp32f" : "lp64f"; -+ case llvm::Triple::GNUF64: -+ // This was originally permitted (and indeed the canonical way) to -+ // represent the {ILP32,LP64}D ABIs, but in Feb 2023 Loongson decided to -+ // drop the explicit suffix in favor of unmarked `-gnu` for the -+ // "general-purpose" ABIs, among other non-technical reasons. -+ // -+ // The spec change did not mention whether existing usages of "gnuf64" -+ // shall remain valid or not, so we are going to continue recognizing it -+ // for some time, until it is clear that everyone else has migrated away -+ // from it. -+ [[fallthrough]]; -+ case llvm::Triple::GNU: -+ default: -+ return IsLA32 ? "ilp32d" : "lp64d"; -+ } - } - - void loongarch::getLoongArchTargetFeatures(const Driver &D, - const llvm::Triple &Triple, - const ArgList &Args, - std::vector &Features) { -- std::string ArchName; -- if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) -+ StringRef ArchName; -+ llvm::LoongArch::ArchKind ArchKind = llvm::LoongArch::ArchKind::AK_INVALID; -+ if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { -+ ArchKind = llvm::LoongArch::parseArch(A->getValue()); -+ if (ArchKind == llvm::LoongArch::ArchKind::AK_INVALID) { -+ D.Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args); -+ return; -+ } - ArchName = A->getValue(); -- ArchName = postProcessTargetCPUString(ArchName, Triple); -- llvm::LoongArch::getArchFeatures(ArchName, Features); -+ } -+ -+ // TODO: handle -march=native and -mtune=xx. -+ -+ // Select a default arch name. -+ if (ArchName.empty() && Triple.getArch() == llvm::Triple::loongarch64) -+ ArchName = "loongarch64"; -+ -+ if (!ArchName.empty()) -+ llvm::LoongArch::getArchFeatures(ArchName, Features); - - // Select floating-point features determined by -mdouble-float, - // -msingle-float, -msoft-float and -mfpu. -@@ -149,25 +183,3 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, - AddTargetFeature(Args, Features, options::OPT_munaligned_access, - options::OPT_mno_unaligned_access, "ual"); - } -- --std::string loongarch::postProcessTargetCPUString(const std::string &CPU, -- const llvm::Triple &Triple) { -- std::string CPUString = CPU; -- if (CPUString == "native") { -- CPUString = llvm::sys::getHostCPUName(); -- if (CPUString == "generic") -- CPUString = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64()); -- } -- if (CPUString.empty()) -- CPUString = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64()); -- return CPUString; --} -- --std::string loongarch::getLoongArchTargetCPU(const llvm::opt::ArgList &Args, -- const llvm::Triple &Triple) { -- std::string CPU; -- // If we have -march, use that. -- if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) -- CPU = A->getValue(); -- return postProcessTargetCPUString(CPU, Triple); --} -diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.h b/clang/lib/Driver/ToolChains/Arch/LoongArch.h -index d8280cd83..0084474e7 100644 ---- a/clang/lib/Driver/ToolChains/Arch/LoongArch.h -+++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.h -@@ -23,12 +23,6 @@ void getLoongArchTargetFeatures(const Driver &D, const llvm::Triple &Triple, - - StringRef getLoongArchABI(const Driver &D, const llvm::opt::ArgList &Args, - const llvm::Triple &Triple); -- --std::string postProcessTargetCPUString(const std::string &CPU, -- const llvm::Triple &Triple); -- --std::string getLoongArchTargetCPU(const llvm::opt::ArgList &Args, -- const llvm::Triple &Triple); - } // end namespace loongarch - } // end namespace tools - } // end namespace driver -diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp -index e5c3b1087..8e6f880be 100644 ---- a/clang/lib/Driver/ToolChains/Clang.cpp -+++ b/clang/lib/Driver/ToolChains/Clang.cpp -@@ -54,7 +54,6 @@ - #include "llvm/Support/Path.h" - #include "llvm/Support/Process.h" - #include "llvm/Support/YAMLParser.h" --#include "llvm/TargetParser/LoongArchTargetParser.h" - #include - - using namespace clang::driver; -@@ -1834,20 +1833,10 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, - - void Clang::AddLoongArchTargetArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { -- const llvm::Triple &Triple = getToolChain().getTriple(); -- - CmdArgs.push_back("-target-abi"); -- CmdArgs.push_back( -- loongarch::getLoongArchABI(getToolChain().getDriver(), Args, Triple) -- .data()); -- -- // Handle -mtune. -- if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) { -- std::string TuneCPU = A->getValue(); -- TuneCPU = loongarch::postProcessTargetCPUString(TuneCPU, Triple); -- CmdArgs.push_back("-tune-cpu"); -- CmdArgs.push_back(Args.MakeArgString(TuneCPU)); -- } -+ CmdArgs.push_back(loongarch::getLoongArchABI(getToolChain().getDriver(), Args, -+ getToolChain().getTriple()) -+ .data()); - } - - void Clang::AddMIPSTargetArgs(const ArgList &Args, -diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp -index b462e2fe1..34640b3c4 100644 ---- a/clang/lib/Driver/ToolChains/CommonArgs.cpp -+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp -@@ -455,10 +455,6 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args, - case llvm::Triple::wasm32: - case llvm::Triple::wasm64: - return std::string(getWebAssemblyTargetCPU(Args)); -- -- case llvm::Triple::loongarch32: -- case llvm::Triple::loongarch64: -- return loongarch::getLoongArchTargetCPU(Args, T); - } - } - -diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp -index c6fb290ff..ba4136902 100644 ---- a/clang/lib/Driver/ToolChains/Linux.cpp -+++ b/clang/lib/Driver/ToolChains/Linux.cpp -@@ -86,6 +86,39 @@ std::string Linux::getMultiarchTriple(const Driver &D, - case llvm::Triple::aarch64_be: - return "aarch64_be-linux-gnu"; - -+ case llvm::Triple::loongarch64: { -+ const char *Libc; -+ const char *FPFlavor; -+ -+ if (TargetTriple.isGNUEnvironment()) { -+ Libc = "gnu"; -+ } else if (TargetTriple.isMusl()) { -+ Libc = "musl"; -+ } else { -+ return TargetTriple.str(); -+ } -+ -+ switch (TargetEnvironment) { -+ default: -+ return TargetTriple.str(); -+ case llvm::Triple::GNUSF: -+ FPFlavor = "sf"; -+ break; -+ case llvm::Triple::GNUF32: -+ FPFlavor = "f32"; -+ break; -+ case llvm::Triple::GNU: -+ case llvm::Triple::GNUF64: -+ // This was going to be "f64" in an earlier Toolchain Conventions -+ // revision, but starting from Feb 2023 the F64 ABI variants are -+ // unmarked in their canonical forms. -+ FPFlavor = ""; -+ break; -+ } -+ -+ return (Twine("loongarch64-linux-") + Libc + FPFlavor).str(); -+ } -+ - case llvm::Triple::m68k: - return "m68k-linux-gnu"; - -diff --git a/clang/test/Driver/Inputs/debian_loong64_tree/usr/include/c++/13/backward/.keep b/clang/test/Driver/Inputs/debian_loong64_tree/usr/include/c++/13/backward/.keep -new file mode 100644 -index 000000000..e69de29bb -diff --git a/clang/test/Driver/Inputs/debian_loong64_tree/usr/include/loongarch64-linux-gnu/c++/.keep b/clang/test/Driver/Inputs/debian_loong64_tree/usr/include/loongarch64-linux-gnu/c++/.keep -new file mode 100644 -index 000000000..e69de29bb -diff --git a/clang/test/Driver/Inputs/debian_loong64_tree/usr/lib/gcc/loongarch64-linux-gnu/13/crtbegin.o b/clang/test/Driver/Inputs/debian_loong64_tree/usr/lib/gcc/loongarch64-linux-gnu/13/crtbegin.o -new file mode 100644 -index 000000000..e69de29bb -diff --git a/clang/test/Driver/Inputs/debian_loong64_tree/usr/lib/gcc/loongarch64-linux-gnu/13/crtend.o b/clang/test/Driver/Inputs/debian_loong64_tree/usr/lib/gcc/loongarch64-linux-gnu/13/crtend.o -new file mode 100644 -index 000000000..e69de29bb -diff --git a/clang/test/Driver/Inputs/debian_loong64_tree/usr/lib/gcc/loongarch64-linux-gnu/13/include/.keep b/clang/test/Driver/Inputs/debian_loong64_tree/usr/lib/gcc/loongarch64-linux-gnu/13/include/.keep -new file mode 100644 -index 000000000..e69de29bb -diff --git a/clang/test/Driver/Inputs/debian_loong64_tree/usr/lib/loongarch64-linux-gnu/crt1.o b/clang/test/Driver/Inputs/debian_loong64_tree/usr/lib/loongarch64-linux-gnu/crt1.o -new file mode 100644 -index 000000000..e69de29bb -diff --git a/clang/test/Driver/Inputs/debian_loong64_tree/usr/lib/loongarch64-linux-gnu/crti.o b/clang/test/Driver/Inputs/debian_loong64_tree/usr/lib/loongarch64-linux-gnu/crti.o -new file mode 100644 -index 000000000..e69de29bb -diff --git a/clang/test/Driver/Inputs/debian_loong64_tree/usr/lib/loongarch64-linux-gnu/crtn.o b/clang/test/Driver/Inputs/debian_loong64_tree/usr/lib/loongarch64-linux-gnu/crtn.o -new file mode 100644 -index 000000000..e69de29bb -diff --git a/clang/test/Driver/linux-header-search.cpp b/clang/test/Driver/linux-header-search.cpp -index 91e4f8825..e8e84f1e4 100644 ---- a/clang/test/Driver/linux-header-search.cpp -+++ b/clang/test/Driver/linux-header-search.cpp -@@ -244,6 +244,32 @@ - // CHECK-GENTOO-4-9-X-32: "-internal-externc-isystem" "[[SYSROOT]]/include" - // CHECK-GENTOO-4-9-X-32: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" - // -+// Check header search on Debian loong64 -+// RUN: %clang -### %s -fsyntax-only 2>&1 \ -+// RUN: --target=loongarch64-unknown-linux-gnu -stdlib=libstdc++ \ -+// RUN: --sysroot=%S/Inputs/debian_loong64_tree \ -+// RUN: --gcc-toolchain="" \ -+// RUN: | FileCheck --check-prefix=CHECK-LOONG64-GNU %s -+// -+// Check that "-gnuf64" is seen as "-gnu" for loong64. -+// RUN: %clang -### %s -fsyntax-only 2>&1 \ -+// RUN: --target=loongarch64-unknown-linux-gnuf64 -stdlib=libstdc++ \ -+// RUN: --sysroot=%S/Inputs/debian_loong64_tree \ -+// RUN: --gcc-toolchain="" \ -+// RUN: | FileCheck --check-prefix=CHECK-LOONG64-GNU %s -+// CHECK-LOONG64-GNU: "-cc1" -+// CHECK-LOONG64-GNU: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" -+// CHECK-LOONG64-GNU: "-isysroot" "[[SYSROOT:[^"]+]]" -+// CHECK-LOONG64-GNU: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/loongarch64-linux-gnu/13/../../../../include/c++/13" -+// CHECK-LOONG64-GNU: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/loongarch64-linux-gnu/13/../../../../include/c++/13/loongarch64-linux-gnu" -+// CHECK-LOONG64-GNU: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/loongarch64-linux-gnu/13/../../../../include/c++/13/backward" -+// CHECK-LOONG64-GNU: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" -+// CHECK-LOONG64-GNU: "-internal-isystem" "[[SYSROOT]]/usr/local/include" -+// CHECK-LOONG64-GNU: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/loongarch64-linux-gnu/13/../../../../loongarch64-linux-gnu/include" -+// CHECK-LOONG64-GNU: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/loongarch64-linux-gnu" -+// CHECK-LOONG64-GNU: "-internal-externc-isystem" "[[SYSROOT]]/include" -+// CHECK-LOONG64-GNU: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" -+// - // Check header search on Debian 6 / MIPS64 - // RUN: %clang -### %s -fsyntax-only 2>&1 \ - // RUN: --target=mips64-unknown-linux-gnuabi64 -stdlib=libstdc++ \ -diff --git a/clang/test/Driver/linux-ld.c b/clang/test/Driver/linux-ld.c -index 10e6bee18..e937de950 100644 ---- a/clang/test/Driver/linux-ld.c -+++ b/clang/test/Driver/linux-ld.c -@@ -830,6 +830,30 @@ - // CHECK-ARM-HF: "-dynamic-linker" "{{.*}}/lib/ld-linux-armhf.so.3" - // - // RUN: %clang -### %s -no-pie 2>&1 \ -+// RUN: --target=loongarch64-linux-gnu \ -+// RUN: | FileCheck --check-prefix=CHECK-LOONGARCH-LP64D %s -+// RUN: %clang -### %s -no-pie 2>&1 \ -+// RUN: --target=loongarch64-linux-gnuf64 \ -+// RUN: | FileCheck --check-prefix=CHECK-LOONGARCH-LP64D %s -+// CHECK-LOONGARCH-LP64D: "{{.*}}ld{{(.exe)?}}" -+// CHECK-LOONGARCH-LP64D: "-m" "elf64loongarch" -+// CHECK-LOONGARCH-LP64D: "-dynamic-linker" "{{.*}}/lib64/ld-linux-loongarch-lp64d.so.1" -+// -+// RUN: %clang -### %s -no-pie 2>&1 \ -+// RUN: --target=loongarch64-linux-gnuf32 \ -+// RUN: | FileCheck --check-prefix=CHECK-LOONGARCH-LP64F %s -+// CHECK-LOONGARCH-LP64F: "{{.*}}ld{{(.exe)?}}" -+// CHECK-LOONGARCH-LP64F: "-m" "elf64loongarch" -+// CHECK-LOONGARCH-LP64F: "-dynamic-linker" "{{.*}}/lib64/ld-linux-loongarch-lp64f.so.1" -+// -+// RUN: %clang -### %s -no-pie 2>&1 \ -+// RUN: --target=loongarch64-linux-gnusf \ -+// RUN: | FileCheck --check-prefix=CHECK-LOONGARCH-LP64S %s -+// CHECK-LOONGARCH-LP64S: "{{.*}}ld{{(.exe)?}}" -+// CHECK-LOONGARCH-LP64S: "-m" "elf64loongarch" -+// CHECK-LOONGARCH-LP64S: "-dynamic-linker" "{{.*}}/lib64/ld-linux-loongarch-lp64s.so.1" -+// -+// RUN: %clang -### %s -no-pie 2>&1 \ - // RUN: --target=powerpc64-linux-gnu \ - // RUN: | FileCheck --check-prefix=CHECK-PPC64 %s - // CHECK-PPC64: "{{.*}}ld{{(.exe)?}}" -@@ -1388,6 +1412,29 @@ - // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD-LINK %s - // CHECK-ANDROID-PTHREAD-LINK-NOT: argument unused during compilation: '-pthread' - // -+// Check linker invocation on a Debian LoongArch sysroot. -+// RUN: %clang -### %s -no-pie 2>&1 \ -+// RUN: --target=loongarch64-linux-gnu -rtlib=platform \ -+// RUN: --gcc-toolchain="" \ -+// RUN: --sysroot=%S/Inputs/debian_loong64_tree \ -+// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-LOONG64 %s -+// -+// Check that "-gnuf64" is seen as "-gnu" for loong64. -+// RUN: %clang -### %s -no-pie 2>&1 \ -+// RUN: --target=loongarch64-linux-gnuf64 -rtlib=platform \ -+// RUN: --gcc-toolchain="" \ -+// RUN: --sysroot=%S/Inputs/debian_loong64_tree \ -+// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-LOONG64 %s -+// CHECK-DEBIAN-ML-LOONG64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -+// CHECK-DEBIAN-ML-LOONG64: "[[SYSROOT]]/usr/lib/loongarch64-linux-gnu/crt1.o" -+// CHECK-DEBIAN-ML-LOONG64: "[[SYSROOT]]/usr/lib/loongarch64-linux-gnu/crti.o" -+// CHECK-DEBIAN-ML-LOONG64: "[[SYSROOT]]/usr/lib/gcc/loongarch64-linux-gnu/13/crtbegin.o" -+// CHECK-DEBIAN-ML-LOONG64: "-L[[SYSROOT]]/usr/lib/gcc/loongarch64-linux-gnu/13" -+// CHECK-DEBIAN-ML-LOONG64: "-L[[SYSROOT]]/usr/lib/loongarch64-linux-gnu" -+// CHECK-DEBIAN-ML-LOONG64: "-L[[SYSROOT]]/usr/lib" -+// CHECK-DEBIAN-ML-LOONG64: "[[SYSROOT]]/usr/lib/gcc/loongarch64-linux-gnu/13/crtend.o" -+// CHECK-DEBIAN-ML-LOONG64: "[[SYSROOT]]/usr/lib/loongarch64-linux-gnu/crtn.o" -+// - // Check linker invocation on Debian 6 MIPS 32/64-bit. - // RUN: %clang -### %s -no-pie 2>&1 \ - // RUN: --target=mipsel-linux-gnu -rtlib=platform \ -diff --git a/clang/test/Driver/loongarch-abi.c b/clang/test/Driver/loongarch-abi.c -index 9359f25da..12a81d664 100644 ---- a/clang/test/Driver/loongarch-abi.c -+++ b/clang/test/Driver/loongarch-abi.c -@@ -16,6 +16,34 @@ - // RUN: %clang --target=loongarch64-unknown-elf %s -fsyntax-only -### -mabi=lp64d 2>&1 \ - // RUN: | FileCheck --check-prefix=LP64D %s - -+// RUN: %clang --target=loongarch32-linux-gnusf %s -fsyntax-only -### 2>&1 \ -+// RUN: | FileCheck --check-prefix=ILP32S %s -+// RUN: %clang --target=loongarch32-linux-gnuf32 %s -fsyntax-only -### 2>&1 \ -+// RUN: | FileCheck --check-prefix=ILP32F %s -+// RUN: %clang --target=loongarch32-linux-gnuf64 %s -fsyntax-only -### 2>&1 \ -+// RUN: | FileCheck --check-prefix=ILP32D %s -+// RUN: %clang --target=loongarch32-linux-gnu %s -fsyntax-only -### 2>&1 \ -+// RUN: | FileCheck --check-prefix=ILP32D %s -+ -+// RUN: %clang --target=loongarch64-linux-gnusf %s -fsyntax-only -### 2>&1 \ -+// RUN: | FileCheck --check-prefix=LP64S %s -+// RUN: %clang --target=loongarch64-linux-gnuf32 %s -fsyntax-only -### 2>&1 \ -+// RUN: | FileCheck --check-prefix=LP64F %s -+// RUN: %clang --target=loongarch64-linux-gnuf64 %s -fsyntax-only -### 2>&1 \ -+// RUN: | FileCheck --check-prefix=LP64D %s -+// RUN: %clang --target=loongarch64-linux-gnu %s -fsyntax-only -### 2>&1 \ -+// RUN: | FileCheck --check-prefix=LP64D %s -+ -+// Check that -mabi prevails in case of conflicts with the triple-implied ABI. -+// RUN: %clang --target=loongarch32-linux-gnuf64 %s -fsyntax-only -### -mabi=ilp32s 2>&1 \ -+// RUN: | FileCheck --check-prefix=ILP32S %s -+// RUN: %clang --target=loongarch64-linux-gnuf64 %s -fsyntax-only -### -mabi=lp64s 2>&1 \ -+// RUN: | FileCheck --check-prefix=LP64S %s -+// RUN: %clang --target=loongarch32-linux-gnu %s -fsyntax-only -### -mabi=ilp32s 2>&1 \ -+// RUN: | FileCheck --check-prefix=ILP32S %s -+// RUN: %clang --target=loongarch64-linux-gnu %s -fsyntax-only -### -mabi=lp64s 2>&1 \ -+// RUN: | FileCheck --check-prefix=LP64S %s -+ - // ILP32S: "-target-abi" "ilp32s" - // ILP32F: "-target-abi" "ilp32f" - // ILP32D: "-target-abi" "ilp32d" -diff --git a/clang/test/Driver/loongarch-march-error.c b/clang/test/Driver/loongarch-march-error.c -index 6bfaa18b0..f447de655 100644 ---- a/clang/test/Driver/loongarch-march-error.c -+++ b/clang/test/Driver/loongarch-march-error.c -@@ -1,7 +1,7 @@ - // RUN: not %clang --target=loongarch64 -march=loongarch -fsyntax-only %s 2>&1 | \ --// RUN: FileCheck -DCPU=loongarch %s --// RUN: not %clang --target=loongarch64 -march=LA464 -fsyntax-only %s 2>&1 | \ --// RUN: FileCheck -DCPU=LA464 %s -+// RUN: FileCheck --check-prefix=LOONGARCH %s -+// LOONGARCH: error: invalid arch name '-march=loongarch' - --// CHECK: error: unknown target CPU '[[CPU]]' --// CHECK-NEXT: note: valid target CPU values are: {{.*}} -+// RUN: not %clang --target=loongarch64 -march=LA464 -fsyntax-only %s 2>&1 | \ -+// RUN: FileCheck --check-prefix=LA464-UPPER %s -+// LA464-UPPER: error: invalid arch name '-march=LA464' -diff --git a/clang/test/Driver/loongarch-march.c b/clang/test/Driver/loongarch-march.c -index 9214130cd..c3a5c9e8a 100644 ---- a/clang/test/Driver/loongarch-march.c -+++ b/clang/test/Driver/loongarch-march.c -@@ -7,20 +7,18 @@ - // RUN: %clang --target=loongarch64 -march=la464 -S -emit-llvm %s -o - | \ - // RUN: FileCheck %s --check-prefix=IR-LA464 - --// CC1-LOONGARCH64: "-target-cpu" "loongarch64" - // CC1-LOONGARCH64-NOT: "-target-feature" - // CC1-LOONGARCH64: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+ual" - // CC1-LOONGARCH64-NOT: "-target-feature" - // CC1-LOONGARCH64: "-target-abi" "lp64d" - --// CC1-LA464: "-target-cpu" "la464" - // CC1-LA464-NOT: "-target-feature" - // CC1-LA464: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" "-target-feature" "+ual" - // CC1-LA464-NOT: "-target-feature" - // CC1-LA464: "-target-abi" "lp64d" - --// IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+f,+ual" --// IR-LA464: attributes #[[#]] ={{.*}}"target-cpu"="la464" {{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+ual" -+// IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-features"="+64bit,+d,+f,+ual" -+// IR-LA464: attributes #[[#]] ={{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+ual" - - int foo(void) { - return 3; -diff --git a/clang/test/Driver/loongarch-mtune.c b/clang/test/Driver/loongarch-mtune.c -deleted file mode 100644 -index 6f3f39e9b..000000000 ---- a/clang/test/Driver/loongarch-mtune.c -+++ /dev/null -@@ -1,34 +0,0 @@ --// RUN: %clang --target=loongarch64 -mtune=loongarch64 -fsyntax-only %s -### 2>&1 | \ --// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=loongarch64 --// RUN: %clang --target=loongarch64 -mtune=loongarch64 -S -emit-llvm %s -o - | \ --// RUN: FileCheck %s --check-prefix=IRATTR -DCPU=loongarch64 -- --// RUN: %clang --target=loongarch64 -mtune=la464 -fsyntax-only %s -### 2>&1 | \ --// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=la464 --// RUN: %clang --target=loongarch64 -mtune=la464 -S -emit-llvm %s -o - | \ --// RUN: FileCheck %s --check-prefix=IRATTR -DCPU=la464 -- --// RUN: %clang --target=loongarch64 -mtune=invalidcpu -fsyntax-only %s -### 2>&1 | \ --// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=invalidcpu --// RUN: not %clang --target=loongarch64 -mtune=invalidcpu -S -emit-llvm %s -o /dev/null 2>&1 | \ --// RUN: FileCheck %s --check-prefix=ERROR -DCPU=invalidcpu -- --// RUN: %clang --target=loongarch64 -mtune=generic -fsyntax-only %s -### 2>&1 | \ --// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=generic --// RUN: not %clang --target=loongarch64 -mtune=generic -S -emit-llvm %s -o /dev/null 2>&1 | \ --// RUN: FileCheck %s --check-prefix=ERROR -DCPU=generic -- --// RUN: %clang --target=loongarch64 -mtune=generic-la64 -fsyntax-only %s -### 2>&1 | \ --// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=generic-la64 --// RUN: not %clang --target=loongarch64 -mtune=generic-la64 -S -emit-llvm %s -o /dev/null 2>&1 | \ --// RUN: FileCheck %s --check-prefix=ERROR -DCPU=generic-la64 -- --// CC1ARG: "-tune-cpu" "[[CPU]]" --// IRATTR: "tune-cpu"="[[CPU]]" -- --// ERROR: error: unknown target CPU '[[CPU]]' --// ERROR-NEXT: note: valid target CPU values are: {{.*}} -- --int foo(void) { -- return 3; --} -diff --git a/clang/test/Preprocessor/init-loongarch.c b/clang/test/Preprocessor/init-loongarch.c -index 4ef42a921..686c96813 100644 ---- a/clang/test/Preprocessor/init-loongarch.c -+++ b/clang/test/Preprocessor/init-loongarch.c -@@ -3,16 +3,16 @@ - // RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple loongarch32-unknown-linux /dev/null \ - // RUN: | FileCheck --match-full-lines --check-prefixes=LA32,LA32-LINUX %s - // RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple loongarch32 \ --// RUN: -fforce-enable-int128 /dev/null | FileCheck --match-full-lines \ --// RUN: --check-prefixes=LA32,LA32-INT128 %s -+// RUN: -fforce-enable-int128 /dev/null | FileCheck --match-full-lines \ -+// RUN: --check-prefixes=LA32,LA32-INT128 %s - - // RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple loongarch64 /dev/null \ - // RUN: | FileCheck --match-full-lines --check-prefix=LA64 %s - // RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple loongarch64-unknown-linux /dev/null \ - // RUN: | FileCheck --match-full-lines --check-prefixes=LA64,LA64-LINUX %s - // RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple loongarch64 \ --// RUN: -fforce-enable-int128 /dev/null | FileCheck --match-full-lines \ --// RUN: --check-prefixes=LA64,LA64-INT128 %s -+// RUN: -fforce-enable-int128 /dev/null | FileCheck --match-full-lines \ -+// RUN: --check-prefixes=LA64,LA64-INT128 %s - - //// Note that common macros are tested in init.c, such as __VERSION__. So they're not listed here. - -@@ -650,160 +650,141 @@ - // LA64-LINUX: #define unix 1 - - --/// Check __loongarch_{double,single,hard,soft}_float, __loongarch_{gr,fr}len, __loongarch_lp64. -+/// Check various macros prefixed with "__loongarch_" in different cases. -+/// "__loongarch__"" is not listed here as it has been checked above. - - // RUN: %clang --target=loongarch32 -mfpu=64 -mabi=ilp32d -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU64-ILP32D %s -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU64-ILP32D %s - // RUN: %clang --target=loongarch32 -mdouble-float -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU64-ILP32D %s --// LA32-FPU64-ILP32D: #define __loongarch_double_float 1 --// LA32-FPU64-ILP32D: #define __loongarch_frlen 64 --// LA32-FPU64-ILP32D: #define __loongarch_grlen 32 --// LA32-FPU64-ILP32D: #define __loongarch_hard_float 1 --// LA32-FPU64-ILP32D-NOT: #define __loongarch_lp64 --// LA32-FPU64-ILP32D-NOT: #define __loongarch_single_float --// LA32-FPU64-ILP32D-NOT: #define __loongarch_soft_float -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU64-ILP32D %s -+// LA32-FPU64-ILP32D: __loongarch_double_float 1 -+// LA32-FPU64-ILP32D-NEXT: __loongarch_frlen 64 -+// LA32-FPU64-ILP32D-NEXT: __loongarch_grlen 32 -+// LA32-FPU64-ILP32D-NEXT: __loongarch_hard_float 1 -+// LA32-FPU64-ILP32D-NOT: __loongarch_lp64 -+// LA32-FPU64-ILP32D-NOT: __loongarch_single_float -+// LA32-FPU64-ILP32D-NOT: __loongarch_soft_float - - // RUN: %clang --target=loongarch32 -mfpu=64 -mabi=ilp32f -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU64-ILP32F %s --// LA32-FPU64-ILP32F-NOT: #define __loongarch_double_float --// LA32-FPU64-ILP32F: #define __loongarch_frlen 64 --// LA32-FPU64-ILP32F: #define __loongarch_grlen 32 --// LA32-FPU64-ILP32F: #define __loongarch_hard_float 1 --// LA32-FPU64-ILP32F-NOT: #define __loongarch_lp64 --// LA32-FPU64-ILP32F: #define __loongarch_single_float 1 --// LA32-FPU64-ILP32F-NOT: #define __loongarch_soft_float -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU64-ILP32F %s -+// LA32-FPU64-ILP32F-NOT: __loongarch_double_float -+// LA32-FPU64-ILP32F: __loongarch_frlen 64 -+// LA32-FPU64-ILP32F-NEXT: __loongarch_grlen 32 -+// LA32-FPU64-ILP32F-NEXT: __loongarch_hard_float 1 -+// LA32-FPU64-ILP32F-NOT: __loongarch_lp64 -+// LA32-FPU64-ILP32F-NEXT: __loongarch_single_float 1 -+// LA32-FPU64-ILP32F-NOT: __loongarch_soft_float - - // RUN: %clang --target=loongarch32 -mfpu=64 -mabi=ilp32s -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU64-ILP32S %s --// LA32-FPU64-ILP32S-NOT: #define __loongarch_double_float --// LA32-FPU64-ILP32S: #define __loongarch_frlen 64 --// LA32-FPU64-ILP32S: #define __loongarch_grlen 32 --// LA32-FPU64-ILP32S-NOT: #define __loongarch_hard_float --// LA32-FPU64-ILP32S-NOT: #define __loongarch_lp64 --// LA32-FPU64-ILP32S-NOT: #define __loongarch_single_float --// LA32-FPU64-ILP32S: #define __loongarch_soft_float 1 -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU64-ILP32S %s -+// LA32-FPU64-ILP32S-NOT: __loongarch_double_float -+// LA32-FPU64-ILP32S: __loongarch_frlen 64 -+// LA32-FPU64-ILP32S-NEXT: __loongarch_grlen 32 -+// LA32-FPU64-ILP32S-NOT: __loongarch_hard_float -+// LA32-FPU64-ILP32S-NOT: __loongarch_lp64 -+// LA32-FPU64-ILP32S-NOT: __loongarch_single_float -+// LA32-FPU64-ILP32S-NEXT: __loongarch_soft_float 1 - - // RUN: %clang --target=loongarch32 -mfpu=32 -mabi=ilp32f -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU32-ILP32F %s -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU32-ILP32F %s - // RUN: %clang --target=loongarch32 -msingle-float -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU32-ILP32F %s --// LA32-FPU32-ILP32F-NOT: #define __loongarch_double_float --// LA32-FPU32-ILP32F: #define __loongarch_frlen 32 --// LA32-FPU32-ILP32F: #define __loongarch_grlen 32 --// LA32-FPU32-ILP32F: #define __loongarch_hard_float 1 --// LA32-FPU32-ILP32F-NOT: #define __loongarch_lp64 --// LA32-FPU32-ILP32F: #define __loongarch_single_float 1 --// LA32-FPU32-ILP32F-NOT: #define __loongarch_soft_float -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU32-ILP32F %s -+// LA32-FPU32-ILP32F-NOT: __loongarch_double_float -+// LA32-FPU32-ILP32F: __loongarch_frlen 32 -+// LA32-FPU32-ILP32F-NEXT: __loongarch_grlen 32 -+// LA32-FPU32-ILP32F-NEXT: __loongarch_hard_float 1 -+// LA32-FPU32-ILP32F-NOT: __loongarch_lp64 -+// LA32-FPU32-ILP32F-NEXT: __loongarch_single_float 1 -+// LA32-FPU32-ILP32F-NOT: __loongarch_soft_float - - // RUN: %clang --target=loongarch32 -mfpu=32 -mabi=ilp32s -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU32-ILP32S %s --// LA32-FPU32-ILP32S-NOT: #define __loongarch_double_float --// LA32-FPU32-ILP32S: #define __loongarch_frlen 32 --// LA32-FPU32-ILP32S: #define __loongarch_grlen 32 --// LA32-FPU32-ILP32S-NOT: #define __loongarch_hard_float --// LA32-FPU32-ILP32S-NOT: #define __loongarch_lp64 --// LA32-FPU32-ILP32S-NOT: #define __loongarch_single_float --// LA32-FPU32-ILP32S: #define __loongarch_soft_float 1 -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU32-ILP32S %s -+// LA32-FPU32-ILP32S-NOT: __loongarch_double_float -+// LA32-FPU32-ILP32S: __loongarch_frlen 32 -+// LA32-FPU32-ILP32S-NEXT: __loongarch_grlen 32 -+// LA32-FPU32-ILP32S-NOT: __loongarch_hard_float -+// LA32-FPU32-ILP32S-NOT: __loongarch_lp64 -+// LA32-FPU32-ILP32S-NOT: __loongarch_single_float -+// LA32-FPU32-ILP32S-NEXT: __loongarch_soft_float 1 - - // RUN: %clang --target=loongarch32 -mfpu=0 -mabi=ilp32s -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU0-ILP32S %s -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU0-ILP32S %s - // RUN: %clang --target=loongarch32 -mfpu=none -mabi=ilp32s -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU0-ILP32S %s -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU0-ILP32S %s - // RUN: %clang --target=loongarch32 -msoft-float -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA32-FPU0-ILP32S %s --// LA32-FPU0-ILP32S-NOT: #define __loongarch_double_float --// LA32-FPU0-ILP32S: #define __loongarch_frlen 0 --// LA32-FPU0-ILP32S: #define __loongarch_grlen 32 --// LA32-FPU0-ILP32S-NOT: #define __loongarch_hard_float --// LA32-FPU0-ILP32S-NOT: #define __loongarch_lp64 --// LA32-FPU0-ILP32S-NOT: #define __loongarch_single_float --// LA32-FPU0-ILP32S: #define __loongarch_soft_float 1 -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA32-FPU0-ILP32S %s -+// LA32-FPU0-ILP32S-NOT: __loongarch_double_float -+// LA32-FPU0-ILP32S: __loongarch_frlen 0 -+// LA32-FPU0-ILP32S-NEXT: __loongarch_grlen 32 -+// LA32-FPU0-ILP32S-NOT: __loongarch_hard_float -+// LA32-FPU0-ILP32S-NOT: __loongarch_lp64 -+// LA32-FPU0-ILP32S-NOT: __loongarch_single_float -+// LA32-FPU0-ILP32S-NEXT: __loongarch_soft_float 1 - - // RUN: %clang --target=loongarch64 -mfpu=64 -mabi=lp64d -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU64-LP64D %s -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU64-LP64D %s - // RUN: %clang --target=loongarch64 -mdouble-float -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU64-LP64D %s --// LA64-FPU64-LP64D: #define __loongarch_double_float 1 --// LA64-FPU64-LP64D: #define __loongarch_frlen 64 --// LA64-FPU64-LP64D: #define __loongarch_grlen 64 --// LA64-FPU64-LP64D: #define __loongarch_hard_float 1 --// LA64-FPU64-LP64D: #define __loongarch_lp64 1 --// LA64-FPU64-LP64D-NOT: #define __loongarch_single_float --// LA64-FPU64-LP64D-NOT: #define __loongarch_soft_float -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU64-LP64D %s -+// LA64-FPU64-LP64D: __loongarch_double_float 1 -+// LA64-FPU64-LP64D-NEXT: __loongarch_frlen 64 -+// LA64-FPU64-LP64D-NEXT: __loongarch_grlen 64 -+// LA64-FPU64-LP64D-NEXT: __loongarch_hard_float 1 -+// LA64-FPU64-LP64D-NEXT: __loongarch_lp64 1 -+// LA64-FPU64-LP64D-NOT: __loongarch_single_float -+// LA64-FPU64-LP64D-NOT: __loongarch_soft_float - - // RUN: %clang --target=loongarch64 -mfpu=64 -mabi=lp64f -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU64-LP64F %s --// LA64-FPU64-LP64F-NOT: #define __loongarch_double_float --// LA64-FPU64-LP64F: #define __loongarch_frlen 64 --// LA64-FPU64-LP64F: #define __loongarch_grlen 64 --// LA64-FPU64-LP64F: #define __loongarch_hard_float 1 --// LA64-FPU64-LP64F: #define __loongarch_lp64 1 --// LA64-FPU64-LP64F: #define __loongarch_single_float 1 --// LA64-FPU64-LP64F-NOT: #define __loongarch_soft_float -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU64-LP64F %s -+// LA64-FPU64-LP64F-NOT: __loongarch_double_float -+// LA64-FPU64-LP64F: __loongarch_frlen 64 -+// LA64-FPU64-LP64F-NEXT: __loongarch_grlen 64 -+// LA64-FPU64-LP64F-NEXT: __loongarch_hard_float 1 -+// LA64-FPU64-LP64F-NEXT: __loongarch_lp64 1 -+// LA64-FPU64-LP64F-NEXT: __loongarch_single_float 1 -+// LA64-FPU64-LP64F-NOT: __loongarch_soft_float - - // RUN: %clang --target=loongarch64 -mfpu=64 -mabi=lp64s -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU64-LP64S %s --// LA64-FPU64-LP64S-NOT: #define __loongarch_double_float --// LA64-FPU64-LP64S: #define __loongarch_frlen 64 --// LA64-FPU64-LP64S: #define __loongarch_grlen 64 --// LA64-FPU64-LP64S-NOT: #define __loongarch_hard_float --// LA64-FPU64-LP64S: #define __loongarch_lp64 1 --// LA64-FPU64-LP64S-NOT: #define __loongarch_single_float --// LA64-FPU64-LP64S: #define __loongarch_soft_float 1 -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU64-LP64S %s -+// LA64-FPU64-LP64S-NOT: __loongarch_double_float -+// LA64-FPU64-LP64S: __loongarch_frlen 64 -+// LA64-FPU64-LP64S-NEXT: __loongarch_grlen 64 -+// LA64-FPU64-LP64S-NOT: __loongarch_hard_float -+// LA64-FPU64-LP64S-NEXT: __loongarch_lp64 1 -+// LA64-FPU64-LP64S-NOT: __loongarch_single_float -+// LA64-FPU64-LP64S-NEXT: __loongarch_soft_float 1 - - // RUN: %clang --target=loongarch64 -mfpu=32 -mabi=lp64f -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU32-LP64F %s -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU32-LP64F %s - // RUN: %clang --target=loongarch64 -msingle-float -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU32-LP64F %s --// LA64-FPU32-LP64F-NOT: #define __loongarch_double_float --// LA64-FPU32-LP64F: #define __loongarch_frlen 32 --// LA64-FPU32-LP64F: #define __loongarch_grlen 64 --// LA64-FPU32-LP64F: #define __loongarch_hard_float 1 --// LA64-FPU32-LP64F: #define __loongarch_lp64 1 --// LA64-FPU32-LP64F: #define __loongarch_single_float 1 --// LA64-FPU32-LP64F-NOT: #define __loongarch_soft_float -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU32-LP64F %s -+// LA64-FPU32-LP64F-NOT: __loongarch_double_float -+// LA64-FPU32-LP64F: __loongarch_frlen 32 -+// LA64-FPU32-LP64F-NEXT: __loongarch_grlen 64 -+// LA64-FPU32-LP64F-NEXT: __loongarch_hard_float 1 -+// LA64-FPU32-LP64F-NEXT: __loongarch_lp64 1 -+// LA64-FPU32-LP64F-NEXT: __loongarch_single_float 1 -+// LA64-FPU32-LP64F-NOT: __loongarch_soft_float - - // RUN: %clang --target=loongarch64 -mfpu=32 -mabi=lp64s -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU32-LP64S %s --// LA64-FPU32-LP64S-NOT: #define __loongarch_double_float --// LA64-FPU32-LP64S: #define __loongarch_frlen 32 --// LA64-FPU32-LP64S: #define __loongarch_grlen 64 --// LA64-FPU32-LP64S-NOT: #define __loongarch_hard_float --// LA64-FPU32-LP64S: #define __loongarch_lp64 1 --// LA64-FPU32-LP64S-NOT: #define __loongarch_single_float --// LA64-FPU32-LP64S: #define __loongarch_soft_float 1 -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU32-LP64S %s -+// LA64-FPU32-LP64S-NOT: __loongarch_double_float -+// LA64-FPU32-LP64S: __loongarch_frlen 32 -+// LA64-FPU32-LP64S-NEXT: __loongarch_grlen 64 -+// LA64-FPU32-LP64S-NOT: __loongarch_hard_float -+// LA64-FPU32-LP64S-NEXT: __loongarch_lp64 1 -+// LA64-FPU32-LP64S-NOT: __loongarch_single_float -+// LA64-FPU32-LP64S-NEXT: __loongarch_soft_float 1 - - // RUN: %clang --target=loongarch64 -mfpu=0 -mabi=lp64s -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU0-LP64S %s -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU0-LP64S %s - // RUN: %clang --target=loongarch64 -mfpu=none -mabi=lp64s -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU0-LP64S %s -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU0-LP64S %s - // RUN: %clang --target=loongarch64 -msoft-float -x c -E -dM %s -o - \ --// RUN: | FileCheck --match-full-lines --check-prefix=LA64-FPU0-LP64S %s --// LA64-FPU0-LP64S-NOT: #define __loongarch_double_float --// LA64-FPU0-LP64S: #define __loongarch_frlen 0 --// LA64-FPU0-LP64S: #define __loongarch_grlen 64 --// LA64-FPU0-LP64S-NOT: #define __loongarch_hard_float --// LA64-FPU0-LP64S: #define __loongarch_lp64 1 --// LA64-FPU0-LP64S-NOT: #define __loongarch_single_float --// LA64-FPU0-LP64S: #define __loongarch_soft_float 1 -- --/// Check __loongarch_arch and __loongarch_tune. -- --// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - | \ --// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=loongarch64 %s --// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 | \ --// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=loongarch64 %s --// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la464 | \ --// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la464 -DTUNE=la464 %s --// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -mtune=loongarch64 | \ --// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=loongarch64 %s --// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -mtune=la464 | \ --// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=la464 %s --// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -mtune=la464 | \ --// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=la464 %s --// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la464 -mtune=loongarch64 | \ --// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la464 -DTUNE=loongarch64 %s -- --// ARCH-TUNE: #define __loongarch_arch "[[ARCH]]" --// ARCH-TUNE: #define __loongarch_tune "[[TUNE]]" -+// RUN: | grep __loongarch_ | FileCheck --check-prefix=LA64-FPU0-LP64S %s -+// LA64-FPU0-LP64S-NOT: __loongarch_double_float -+// LA64-FPU0-LP64S: __loongarch_frlen 0 -+// LA64-FPU0-LP64S-NEXT: __loongarch_grlen 64 -+// LA64-FPU0-LP64S-NOT: __loongarch_hard_float -+// LA64-FPU0-LP64S-NEXT: __loongarch_lp64 1 -+// LA64-FPU0-LP64S-NOT: __loongarch_single_float -+// LA64-FPU0-LP64S-NEXT: __loongarch_soft_float 1 diff --git a/0009-disable-recommonmark.patch b/0009-disable-recommonmark.patch new file mode 100644 index 0000000000000000000000000000000000000000..f6db5da7a1e8705264e120b793616ad789ffbcf3 --- /dev/null +++ b/0009-disable-recommonmark.patch @@ -0,0 +1,26 @@ +diff -Naur a/clang/docs/conf.py b/clang/docs/conf.py +--- a/clang/docs/conf.py 2020-09-15 09:12:24.318287611 +0000 ++++ b/clang/docs/conf.py 2020-09-15 15:01:00.025893199 +0000 +@@ -37,21 +37,7 @@ + ".rst": "restructuredtext", + } + +-try: +- import recommonmark +-except ImportError: +- # manpages do not use any .md sources +- if not tags.has("builder-man"): +- raise +-else: +- import sphinx +- +- if sphinx.version_info >= (3, 0): +- # This requires 0.5 or later. +- extensions.append("recommonmark") +- else: +- source_parsers = {".md": "recommonmark.parser.CommonMarkParser"} +- source_suffix[".md"] = "markdown" ++import sphinx + + # The encoding of source files. + # source_encoding = 'utf-8-sig' diff --git a/D138472.diff b/D138472.diff deleted file mode 100644 index 5d3cd607f060a361c5ac7ba7144fc231e3cd0cc0..0000000000000000000000000000000000000000 --- a/D138472.diff +++ /dev/null @@ -1,53 +0,0 @@ -From 04b642c646048dd9df652eba05d45beaa13bc895 Mon Sep 17 00:00:00 2001 -From: Konrad Kleine -Date: Mon, 23 Jan 2023 13:14:17 +0000 -Subject: [PATCH] Rebased D138472 - ---- - clang/CMakeLists.txt | 23 ++++++++++------------- - 1 file changed, 10 insertions(+), 13 deletions(-) - -diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt -index 090cfa352078..f87838776c32 100644 ---- a/clang/CMakeLists.txt -+++ b/clang/CMakeLists.txt -@@ -118,12 +118,11 @@ if(CLANG_BUILT_STANDALONE) - set(LLVM_UTILS_PROVIDED ON) - set(CLANG_TEST_DEPS FileCheck count not) - endif() -- set(UNITTEST_DIR ${LLVM_THIRD_PARTY_DIR}/unittest) -- if(EXISTS ${UNITTEST_DIR}/googletest/include/gtest/gtest.h -- AND NOT EXISTS ${LLVM_LIBRARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX} -- AND EXISTS ${UNITTEST_DIR}/CMakeLists.txt) -- add_subdirectory(${UNITTEST_DIR} third-party/unittest) -- endif() -+ endif() -+ -+ find_package(LLVMGTest HINTS "${LLVM_CMAKE_DIR}") -+ if (NOT TARGET llvm_gtest) -+ message(FATAL_ERROR "llvm-gtest not found. Please install llvm-gtest or disable tests with -DLLVM_INCLUDE_TESTS=OFF") - endif() - - if(LLVM_LIT) -@@ -506,13 +505,11 @@ endif() - - - if( CLANG_INCLUDE_TESTS ) -- if(EXISTS ${LLVM_THIRD_PARTY_DIR}/unittest/googletest/include/gtest/gtest.h) -- add_subdirectory(unittests) -- list(APPEND CLANG_TEST_DEPS ClangUnitTests) -- list(APPEND CLANG_TEST_PARAMS -- clang_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/test/Unit/lit.site.cfg -- ) -- endif() -+ add_subdirectory(unittests) -+ list(APPEND CLANG_TEST_DEPS ClangUnitTests) -+ list(APPEND CLANG_TEST_PARAMS -+ clang_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/test/Unit/lit.site.cfg -+ ) - add_subdirectory(test) - add_subdirectory(bindings/python/tests) - --- -2.34.3 - diff --git a/D141581.diff b/D141581.diff deleted file mode 100644 index c227e2220b1eb0a5d5fd3a5381d931d732f7ee99..0000000000000000000000000000000000000000 --- a/D141581.diff +++ /dev/null @@ -1,25 +0,0 @@ -diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt ---- a/clang/lib/Basic/CMakeLists.txt -+++ b/clang/lib/Basic/CMakeLists.txt -@@ -110,7 +110,7 @@ - - DEPENDS - omp_gen -- RISCVTargetParserTableGen -+ LLVMTargetParser - ) - - target_link_libraries(clangBasic -diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt ---- a/clang/lib/Driver/CMakeLists.txt -+++ b/clang/lib/Driver/CMakeLists.txt -@@ -93,7 +93,7 @@ - - DEPENDS - ClangDriverOptions -- RISCVTargetParserTableGen -+ LLVMTargetParser - - LINK_LIBS - clangBasic - diff --git a/cfg.patch b/cfg.patch new file mode 100644 index 0000000000000000000000000000000000000000..779558a20b40a4ddad7cfbd909f8bf476b75109c --- /dev/null +++ b/cfg.patch @@ -0,0 +1,298 @@ +commit ad4a5130277776d8f15f40ac5a6dede6ad3aabfb +Author: Timm Bäder +Date: Tue Aug 8 14:11:33 2023 +0200 + + [clang][CFG] Cleanup functions + + Add declarations declared with attribute(cleanup(...)) to the CFG, + similar to destructors. + + Differential Revision: https://reviews.llvm.org/D157385 + +diff --git a/clang/include/clang/Analysis/CFG.h b/clang/include/clang/Analysis/CFG.h +index cf4fa2da2a35..67383bb316d3 100644 +--- a/clang/include/clang/Analysis/CFG.h ++++ b/clang/include/clang/Analysis/CFG.h +@@ -14,10 +14,11 @@ + #ifndef LLVM_CLANG_ANALYSIS_CFG_H + #define LLVM_CLANG_ANALYSIS_CFG_H + +-#include "clang/Analysis/Support/BumpVector.h" +-#include "clang/Analysis/ConstructionContext.h" ++#include "clang/AST/Attr.h" + #include "clang/AST/ExprCXX.h" + #include "clang/AST/ExprObjC.h" ++#include "clang/Analysis/ConstructionContext.h" ++#include "clang/Analysis/Support/BumpVector.h" + #include "clang/Basic/LLVM.h" + #include "llvm/ADT/DenseMap.h" + #include "llvm/ADT/GraphTraits.h" +@@ -74,7 +75,8 @@ public: + MemberDtor, + TemporaryDtor, + DTOR_BEGIN = AutomaticObjectDtor, +- DTOR_END = TemporaryDtor ++ DTOR_END = TemporaryDtor, ++ CleanupFunction, + }; + + protected: +@@ -383,6 +385,32 @@ private: + } + }; + ++class CFGCleanupFunction final : public CFGElement { ++public: ++ CFGCleanupFunction() = default; ++ CFGCleanupFunction(const VarDecl *VD) ++ : CFGElement(Kind::CleanupFunction, VD) { ++ assert(VD->hasAttr()); ++ } ++ ++ const VarDecl *getVarDecl() const { ++ return static_cast(Data1.getPointer()); ++ } ++ ++ /// Returns the function to be called when cleaning up the var decl. ++ const FunctionDecl *getFunctionDecl() const { ++ const CleanupAttr *A = getVarDecl()->getAttr(); ++ return A->getFunctionDecl(); ++ } ++ ++private: ++ friend class CFGElement; ++ ++ static bool isKind(const CFGElement E) { ++ return E.getKind() == Kind::CleanupFunction; ++ } ++}; ++ + /// Represents C++ object destructor implicitly generated for automatic object + /// or temporary bound to const reference at the point of leaving its local + /// scope. +@@ -1142,6 +1170,10 @@ public: + Elements.push_back(CFGAutomaticObjDtor(VD, S), C); + } + ++ void appendCleanupFunction(const VarDecl *VD, BumpVectorContext &C) { ++ Elements.push_back(CFGCleanupFunction(VD), C); ++ } ++ + void appendLifetimeEnds(VarDecl *VD, Stmt *S, BumpVectorContext &C) { + Elements.push_back(CFGLifetimeEnds(VD, S), C); + } +diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp +index b82f9010a83f..03ab4c6fdf29 100644 +--- a/clang/lib/Analysis/CFG.cpp ++++ b/clang/lib/Analysis/CFG.cpp +@@ -881,6 +881,10 @@ private: + B->appendAutomaticObjDtor(VD, S, cfg->getBumpVectorContext()); + } + ++ void appendCleanupFunction(CFGBlock *B, VarDecl *VD) { ++ B->appendCleanupFunction(VD, cfg->getBumpVectorContext()); ++ } ++ + void appendLifetimeEnds(CFGBlock *B, VarDecl *VD, Stmt *S) { + B->appendLifetimeEnds(VD, S, cfg->getBumpVectorContext()); + } +@@ -1346,7 +1350,8 @@ private: + return {}; + } + +- bool hasTrivialDestructor(VarDecl *VD); ++ bool hasTrivialDestructor(const VarDecl *VD) const; ++ bool needsAutomaticDestruction(const VarDecl *VD) const; + }; + + } // namespace +@@ -1861,14 +1866,14 @@ void CFGBuilder::addAutomaticObjDestruction(LocalScope::const_iterator B, + if (B == E) + return; + +- SmallVector DeclsNonTrivial; +- DeclsNonTrivial.reserve(B.distance(E)); ++ SmallVector DeclsNeedDestruction; ++ DeclsNeedDestruction.reserve(B.distance(E)); + + for (VarDecl* D : llvm::make_range(B, E)) +- if (!hasTrivialDestructor(D)) +- DeclsNonTrivial.push_back(D); ++ if (needsAutomaticDestruction(D)) ++ DeclsNeedDestruction.push_back(D); + +- for (VarDecl *VD : llvm::reverse(DeclsNonTrivial)) { ++ for (VarDecl *VD : llvm::reverse(DeclsNeedDestruction)) { + if (BuildOpts.AddImplicitDtors) { + // If this destructor is marked as a no-return destructor, we need to + // create a new block for the destructor which does not have as a +@@ -1879,7 +1884,8 @@ void CFGBuilder::addAutomaticObjDestruction(LocalScope::const_iterator B, + Ty = getReferenceInitTemporaryType(VD->getInit()); + Ty = Context->getBaseElementType(Ty); + +- if (Ty->getAsCXXRecordDecl()->isAnyDestructorNoReturn()) ++ const CXXRecordDecl *CRD = Ty->getAsCXXRecordDecl(); ++ if (CRD && CRD->isAnyDestructorNoReturn()) + Block = createNoReturnBlock(); + } + +@@ -1890,8 +1896,10 @@ void CFGBuilder::addAutomaticObjDestruction(LocalScope::const_iterator B, + // objects, we end lifetime with scope end. + if (BuildOpts.AddLifetime) + appendLifetimeEnds(Block, VD, S); +- if (BuildOpts.AddImplicitDtors) ++ if (BuildOpts.AddImplicitDtors && !hasTrivialDestructor(VD)) + appendAutomaticObjDtor(Block, VD, S); ++ if (VD->hasAttr()) ++ appendCleanupFunction(Block, VD); + } + } + +@@ -1922,7 +1930,7 @@ void CFGBuilder::addScopeExitHandling(LocalScope::const_iterator B, + // is destroyed, for automatic variables, this happens when the end of the + // scope is added. + for (VarDecl* D : llvm::make_range(B, E)) +- if (hasTrivialDestructor(D)) ++ if (!needsAutomaticDestruction(D)) + DeclsTrivial.push_back(D); + + if (DeclsTrivial.empty()) +@@ -2095,7 +2103,11 @@ LocalScope* CFGBuilder::addLocalScopeForDeclStmt(DeclStmt *DS, + return Scope; + } + +-bool CFGBuilder::hasTrivialDestructor(VarDecl *VD) { ++bool CFGBuilder::needsAutomaticDestruction(const VarDecl *VD) const { ++ return !hasTrivialDestructor(VD) || VD->hasAttr(); ++} ++ ++bool CFGBuilder::hasTrivialDestructor(const VarDecl *VD) const { + // Check for const references bound to temporary. Set type to pointee. + QualType QT = VD->getType(); + if (QT->isReferenceType()) { +@@ -2149,7 +2161,7 @@ LocalScope* CFGBuilder::addLocalScopeForVarDecl(VarDecl *VD, + return Scope; + + if (!BuildOpts.AddLifetime && !BuildOpts.AddScopes && +- hasTrivialDestructor(VD)) { ++ !needsAutomaticDestruction(VD)) { + assert(BuildOpts.AddImplicitDtors); + return Scope; + } +@@ -5287,6 +5299,7 @@ CFGImplicitDtor::getDestructorDecl(ASTContext &astContext) const { + case CFGElement::CXXRecordTypedCall: + case CFGElement::ScopeBegin: + case CFGElement::ScopeEnd: ++ case CFGElement::CleanupFunction: + llvm_unreachable("getDestructorDecl should only be used with " + "ImplicitDtors"); + case CFGElement::AutomaticObjectDtor: { +@@ -5830,6 +5843,11 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper &Helper, + break; + } + ++ case CFGElement::Kind::CleanupFunction: ++ OS << "CleanupFunction (" ++ << E.castAs().getFunctionDecl()->getName() << ")\n"; ++ break; ++ + case CFGElement::Kind::LifetimeEnds: + Helper.handleDecl(E.castAs().getVarDecl(), OS); + OS << " (Lifetime ends)\n"; +diff --git a/clang/lib/Analysis/PathDiagnostic.cpp b/clang/lib/Analysis/PathDiagnostic.cpp +index 348afc42319e..0cb03943c547 100644 +--- a/clang/lib/Analysis/PathDiagnostic.cpp ++++ b/clang/lib/Analysis/PathDiagnostic.cpp +@@ -567,6 +567,7 @@ getLocationForCaller(const StackFrameContext *SFC, + } + case CFGElement::ScopeBegin: + case CFGElement::ScopeEnd: ++ case CFGElement::CleanupFunction: + llvm_unreachable("not yet implemented!"); + case CFGElement::LifetimeEnds: + case CFGElement::LoopExit: +diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +index 0e2ac78f7089..d7c5bd1d4042 100644 +--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp ++++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +@@ -993,6 +993,7 @@ void ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred, + ProcessLoopExit(E.castAs().getLoopStmt(), Pred); + return; + case CFGElement::LifetimeEnds: ++ case CFGElement::CleanupFunction: + case CFGElement::ScopeBegin: + case CFGElement::ScopeEnd: + return; +diff --git a/clang/test/Analysis/scopes-cfg-output.cpp b/clang/test/Analysis/scopes-cfg-output.cpp +index 6877d124e67a..4eb8967e3735 100644 +--- a/clang/test/Analysis/scopes-cfg-output.cpp ++++ b/clang/test/Analysis/scopes-cfg-output.cpp +@@ -1419,3 +1419,68 @@ label: + } + } + } ++ ++// CHECK: [B1] ++// CHECK-NEXT: 1: CFGScopeBegin(i) ++// CHECK-NEXT: 2: int i __attribute__((cleanup(cleanup_int))); ++// CHECK-NEXT: 3: CleanupFunction (cleanup_int) ++// CHECK-NEXT: 4: CFGScopeEnd(i) ++void cleanup_int(int *i); ++void test_cleanup_functions() { ++ int i __attribute__((cleanup(cleanup_int))); ++} ++ ++// CHECK: [B1] ++// CHECK-NEXT: 1: 10 ++// CHECK-NEXT: 2: i ++// CHECK-NEXT: 3: [B1.2] = [B1.1] ++// CHECK-NEXT: 4: return; ++// CHECK-NEXT: 5: CleanupFunction (cleanup_int) ++// CHECK-NEXT: 6: CFGScopeEnd(i) ++// CHECK-NEXT: Preds (1): B3 ++// CHECK-NEXT: Succs (1): B0 ++// CHECK: [B2] ++// CHECK-NEXT: 1: return; ++// CHECK-NEXT: 2: CleanupFunction (cleanup_int) ++// CHECK-NEXT: 3: CFGScopeEnd(i) ++// CHECK-NEXT: Preds (1): B3 ++// CHECK-NEXT: Succs (1): B0 ++// CHECK: [B3] ++// CHECK-NEXT: 1: CFGScopeBegin(i) ++// CHECK-NEXT: 2: int i __attribute__((cleanup(cleanup_int))); ++// CHECK-NEXT: 3: m ++// CHECK-NEXT: 4: [B3.3] (ImplicitCastExpr, LValueToRValue, int) ++// CHECK-NEXT: 5: 1 ++// CHECK-NEXT: 6: [B3.4] == [B3.5] ++// CHECK-NEXT: T: if [B3.6] ++// CHECK-NEXT: Preds (1): B4 ++// CHECK-NEXT: Succs (2): B2 B1 ++void test_cleanup_functions2(int m) { ++ int i __attribute__((cleanup(cleanup_int))); ++ ++ if (m == 1) { ++ return; ++ } ++ ++ i = 10; ++ return; ++} ++ ++// CHECK: [B1] ++// CHECK-NEXT: 1: CFGScopeBegin(f) ++// CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], F) ++// CHECK-NEXT: 3: F f __attribute__((cleanup(cleanup_F))); ++// CHECK-NEXT: 4: CleanupFunction (cleanup_F) ++// CHECK-NEXT: 5: [B1.3].~F() (Implicit destructor) ++// CHECK-NEXT: 6: CFGScopeEnd(f) ++// CHECK-NEXT: Preds (1): B2 ++// CHECK-NEXT: Succs (1): B0 ++class F { ++public: ++ ~F(); ++}; ++void cleanup_F(F *f); ++ ++void test() { ++ F f __attribute((cleanup(cleanup_F))); ++} diff --git a/clang-16.0.6.src.tar.xz b/clang-17.0.6.src.tar.xz similarity index 66% rename from clang-16.0.6.src.tar.xz rename to clang-17.0.6.src.tar.xz index d43cc7e9caa9acea330f607f601d0beaa21f93a5..35fdfaf91da3a6e31a3722e9682641a5b633e8b9 100644 Binary files a/clang-16.0.6.src.tar.xz and b/clang-17.0.6.src.tar.xz differ diff --git a/clang-tools-extra-16.0.6.src.tar.xz b/clang-tools-extra-17.0.6.src.tar.xz similarity index 30% rename from clang-tools-extra-16.0.6.src.tar.xz rename to clang-tools-extra-17.0.6.src.tar.xz index 10494d7bf3e2001c38412f291014b9e865d89c84..b37bc74a67cac232ff9ce364d98fdf2adbaca55d 100644 Binary files a/clang-tools-extra-16.0.6.src.tar.xz and b/clang-tools-extra-17.0.6.src.tar.xz differ diff --git a/clang.spec b/clang.spec index 55d1b37b06a367b8c39d59171a9992420c982582..c0674c08f1ef2821e4252969119c5b8f70ded1f5 100644 --- a/clang.spec +++ b/clang.spec @@ -1,4 +1,4 @@ -%define anolis_release 2 +%define anolis_release 1 %global toolchain clang @@ -7,7 +7,7 @@ %bcond_with compat_build %bcond_without check -%global maj_ver 16 +%global maj_ver 17 %global min_ver 0 %global patch_ver 6 %global clang_version %{maj_ver}.%{min_ver}.%{patch_ver} @@ -29,24 +29,27 @@ Source4: https://github.com/llvm/llvm-project/releases/download/llvmorg-% Source7: macros.%{name} # Patches for clang -Patch1: 0003-PATCH-Make-funwind-tables-the-default-on-all-archs.patch +Patch1: 0001-PATCH-clang-Make-funwind-tables-the-default-on-all-a.patch Patch2: 0003-PATCH-clang-Don-t-install-static-libraries.patch Patch3: 0001-Driver-Add-a-gcc-equivalent-triple-to-the-list-of-tr.patch # Drop the following patch after debugedit adds support to DWARF-5: # https://sourceware.org/bugzilla/show_bug.cgi?id=28728 -Patch5: 0010-PATCH-clang-Produce-DWARF4-by-default.patch -# Make clangBasic and clangDriver depend on LLVMTargetParser -# See https://reviews.llvm.org/D141581 -Patch7: D141581.diff -# clang/cmake: Use installed gtest libraries for stand-alone builds -# See https://reviews.llvm.org/D138472 -Patch8: D138472.diff - -Patch10: fix-ieee128-cross.diff +Patch4: 0001-Produce-DWARF4-by-default.patch +# Workaround a bug in ORC on ppc64le. +# More info is available here: https://reviews.llvm.org/D159115#4641826 +Patch5: 0001-Workaround-a-bug-in-ORC-on-ppc64le.patch +# Patches for https://issues.redhat.com/browse/RHEL-1650 +# Remove in clang 18. +Patch6: cfg.patch +Patch7: tsa.patch + + +# RHEL specific patches +# Avoid unwanted dependency on python-recommonmark +Patch101: 0009-disable-recommonmark.patch + # Add anolis support in driver Patch11: 1001-add-anolis-os-support-in-driver.patch -Patch12: 0001-backport-LoongArch-patches.patch -Patch13: 0002-LoongArch-fix-symbol-lookup-error.patch # Patches for clang-tools-extra # See https://reviews.llvm.org/D120301 @@ -469,6 +472,9 @@ LD_LIBRARY_PATH=%{buildroot}/%{_libdir} %{__ninja} check-all -C %{__cmake_buildd %{python3_sitelib}/clang/ %changelog +* Tue Mar 12 2024 Xiaoping Liu - 17.0.6-1 +- update to 17.0.6 + * Fri Aug 11 2023 Chen Li - 16.0.6-2 - Backport LoongArch patches from llvmorg-17.0.0-rc2 - Add the triple of loongarch64 for anolis os diff --git a/cmake-16.0.6.src.tar.xz b/cmake-16.0.6.src.tar.xz deleted file mode 100644 index a879639e5bd3fe11d0e23a0ae2bc0eee7e76eb8f..0000000000000000000000000000000000000000 Binary files a/cmake-16.0.6.src.tar.xz and /dev/null differ diff --git a/cmake-17.0.6.src.tar.xz b/cmake-17.0.6.src.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..aeec995a7c0ddaa99a8549223bb1cb8ddab8ab32 Binary files /dev/null and b/cmake-17.0.6.src.tar.xz differ diff --git a/fix-ieee128-cross.diff b/fix-ieee128-cross.diff deleted file mode 100644 index 218c2292ef201ec59a6e860d4c9c41665bacd481..0000000000000000000000000000000000000000 --- a/fix-ieee128-cross.diff +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/clang/test/Driver/ppc-float-abi-warning.cpp b/clang/test/Driver/ppc-float-abi-warning.cpp -index e3baa9f4c059..87d6d87a3b31 100644 ---- a/clang/test/Driver/ppc-float-abi-warning.cpp -+++ b/clang/test/Driver/ppc-float-abi-warning.cpp -@@ -17,10 +17,12 @@ - // RUN: -mabi=ieeelongdouble -stdlib=libc++ -Wno-unsupported-abi 2>&1 | \ - // RUN: FileCheck %s --check-prefix=NOWARN - // RUN: %clang -### --driver-mode=g++ -target powerpc64le-linux-gnu %s\ -+// RUN: --dyld-prefix=%S/Inputs/powerpc64le-linux-gnu-tree/gcc-12 \ - // RUN: -mabi=%if ppc_linux_default_ieeelongdouble %{ieeelongdouble%} \ - // RUN: %else %{ibmlongdouble%} -stdlib=libc++ 2>&1 | \ - // RUN: FileCheck %s --check-prefix=NOWARN - // RUN: %clang -### --driver-mode=g++ -target powerpc64le-linux-gnu %s\ -+// RUN: --dyld-prefix=%S/Inputs/powerpc64le-linux-gnu-tree/gcc-12 \ - // RUN: -mabi=%if ppc_linux_default_ieeelongdouble %{ibmlongdouble%} \ - // RUN: %else %{ieeelongdouble%} -stdlib=libc++ 2>&1 | FileCheck %s diff --git a/tsa.patch b/tsa.patch new file mode 100644 index 0000000000000000000000000000000000000000..2cf698e630b25b7de9d707c80c510a1c5231072a --- /dev/null +++ b/tsa.patch @@ -0,0 +1,124 @@ +commit cf8e189a99f988398a48148b9ea7901948665ab0 +Author: Timm Bäder +Date: Wed Sep 6 12:19:20 2023 +0200 + + [clang][TSA] Thread safety cleanup functions + + Consider cleanup functions in thread safety analysis. + + Differential Revision: https://reviews.llvm.org/D152504 + +diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +index 9d28325c1ea6..13e37ac2b56b 100644 +--- a/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h ++++ b/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +@@ -361,7 +361,7 @@ public: + unsigned NumArgs = 0; + + // Function arguments +- const Expr *const *FunArgs = nullptr; ++ llvm::PointerUnion FunArgs = nullptr; + + // is Self referred to with -> or .? + bool SelfArrow = false; +diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp +index 3107d035254d..3e6ceb7d54c4 100644 +--- a/clang/lib/Analysis/ThreadSafety.cpp ++++ b/clang/lib/Analysis/ThreadSafety.cpp +@@ -1773,7 +1773,8 @@ void BuildLockset::checkPtAccess(const Expr *Exp, AccessKind AK, + /// + /// \param Exp The call expression. + /// \param D The callee declaration. +-/// \param Self If \p Exp = nullptr, the implicit this argument. ++/// \param Self If \p Exp = nullptr, the implicit this argument or the argument ++/// of an implicitly called cleanup function. + /// \param Loc If \p Exp = nullptr, the location. + void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D, + til::LiteralPtr *Self, SourceLocation Loc) { +@@ -2417,6 +2418,15 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) { + AD.getTriggerStmt()->getEndLoc()); + break; + } ++ ++ case CFGElement::CleanupFunction: { ++ const CFGCleanupFunction &CF = BI.castAs(); ++ LocksetBuilder.handleCall(/*Exp=*/nullptr, CF.getFunctionDecl(), ++ SxBuilder.createVariable(CF.getVarDecl()), ++ CF.getVarDecl()->getLocation()); ++ break; ++ } ++ + case CFGElement::TemporaryDtor: { + auto TD = BI.castAs(); + +diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp +index b8286cef396c..63cc66852a9e 100644 +--- a/clang/lib/Analysis/ThreadSafetyCommon.cpp ++++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp +@@ -110,7 +110,8 @@ static StringRef ClassifyDiagnostic(QualType VDT) { + /// \param D The declaration to which the attribute is attached. + /// \param DeclExp An expression involving the Decl to which the attribute + /// is attached. E.g. the call to a function. +-/// \param Self S-expression to substitute for a \ref CXXThisExpr. ++/// \param Self S-expression to substitute for a \ref CXXThisExpr in a call, ++/// or argument to a cleanup function. + CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, + const NamedDecl *D, + const Expr *DeclExp, +@@ -144,7 +145,11 @@ CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, + + if (Self) { + assert(!Ctx.SelfArg && "Ambiguous self argument"); +- Ctx.SelfArg = Self; ++ assert(isa(D) && "Self argument requires function"); ++ if (isa(D)) ++ Ctx.SelfArg = Self; ++ else ++ Ctx.FunArgs = Self; + + // If the attribute has no arguments, then assume the argument is "this". + if (!AttrExp) +@@ -312,8 +317,14 @@ til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE, + ? (cast(D)->getCanonicalDecl() == Canonical) + : (cast(D)->getCanonicalDecl() == Canonical)) { + // Substitute call arguments for references to function parameters +- assert(I < Ctx->NumArgs); +- return translate(Ctx->FunArgs[I], Ctx->Prev); ++ if (const Expr *const *FunArgs = ++ Ctx->FunArgs.dyn_cast()) { ++ assert(I < Ctx->NumArgs); ++ return translate(FunArgs[I], Ctx->Prev); ++ } ++ ++ assert(I == 0); ++ return Ctx->FunArgs.get(); + } + } + // Map the param back to the param of the original function declaration +diff --git a/clang/test/Sema/warn-thread-safety-analysis.c b/clang/test/Sema/warn-thread-safety-analysis.c +index 355616b73d96..642ea88ec3c9 100644 +--- a/clang/test/Sema/warn-thread-safety-analysis.c ++++ b/clang/test/Sema/warn-thread-safety-analysis.c +@@ -72,6 +72,8 @@ int get_value(int *p) SHARED_LOCKS_REQUIRED(foo_.mu_){ + return *p; + } + ++void unlock_scope(struct Mutex *const *mu) __attribute__((release_capability(**mu))); ++ + int main(void) { + + Foo_fun1(1); // expected-warning{{calling function 'Foo_fun1' requires holding mutex 'mu2'}} \ +@@ -127,6 +129,13 @@ int main(void) { + // expected-note@-1{{mutex released here}} + mutex_shared_unlock(&mu1); // expected-warning {{releasing mutex 'mu1' that was not held}} + ++ /// Cleanup functions ++ { ++ struct Mutex* const __attribute__((cleanup(unlock_scope))) scope = &mu1; ++ mutex_exclusive_lock(scope); // Note that we have to lock through scope, because no alias analysis! ++ // Cleanup happens automatically -> no warning. ++ } ++ + return 0; + } +