diff --git a/0009-Backport-LoongArch-improve-the-support-for-compiler-rt-and-bugfix.patch b/0009-Backport-LoongArch-improve-the-support-for-compiler-rt-and-bugfix.patch new file mode 100644 index 0000000000000000000000000000000000000000..d858146d5926d899b0b1697f7ba7231e9a1f5eed --- /dev/null +++ b/0009-Backport-LoongArch-improve-the-support-for-compiler-rt-and-bugfix.patch @@ -0,0 +1,639 @@ +From 2ff5a2bd0a7d14c675cbc5f0e11bf6916b960b20 Mon Sep 17 00:00:00 2001 +From: Ami-zhang <96056515+Ami-zhang@users.noreply.github.com> +Date: Thu, 28 Sep 2023 15:20:27 +0800 +Subject: [PATCH 1/9] [Driver] Support -fsanitize=cfi-icall on loongarch64 + (#67310) + +(cherry picked from commit 55accc82bec48acae769b086ad9a5dc29da77f02) +--- + clang/lib/Driver/ToolChain.cpp | 3 ++- + clang/test/Driver/fsanitize.c | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp +index 0146d8af3549..69811c095594 100644 +--- a/clang/lib/Driver/ToolChain.cpp ++++ b/clang/lib/Driver/ToolChain.cpp +@@ -1273,7 +1273,8 @@ SanitizerMask ToolChain::getSupportedSanitizers() const { + if (getTriple().getArch() == llvm::Triple::x86 || + getTriple().getArch() == llvm::Triple::x86_64 || + getTriple().getArch() == llvm::Triple::arm || getTriple().isWasm() || +- getTriple().isAArch64() || getTriple().isRISCV()) ++ getTriple().isAArch64() || getTriple().isRISCV() || ++ getTriple().isLoongArch64()) + Res |= SanitizerKind::CFIICall; + if (getTriple().getArch() == llvm::Triple::x86_64 || + getTriple().isAArch64(64) || getTriple().isRISCV()) +diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c +index 9442f6b91471..4a525d75ea11 100644 +--- a/clang/test/Driver/fsanitize.c ++++ b/clang/test/Driver/fsanitize.c +@@ -600,6 +600,7 @@ + // RUN: %clang --target=aarch64_be -fvisibility=hidden -fsanitize=cfi -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI + // RUN: %clang --target=riscv32 -fvisibility=hidden -fsanitize=cfi -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI + // RUN: %clang --target=riscv64 -fvisibility=hidden -fsanitize=cfi -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI ++// RUN: %clang --target=loongarch64 -fvisibility=hidden -fsanitize=cfi -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI + // CHECK-CFI: -emit-llvm-bc{{.*}}-fsanitize=cfi-derived-cast,cfi-icall,cfi-mfcall,cfi-unrelated-cast,cfi-nvcall,cfi-vcall + // CHECK-CFI-NOMFCALL: -emit-llvm-bc{{.*}}-fsanitize=cfi-derived-cast,cfi-icall,cfi-unrelated-cast,cfi-nvcall,cfi-vcall + // CHECK-CFI-DCAST: -emit-llvm-bc{{.*}}-fsanitize=cfi-derived-cast +-- +2.20.1 + + +From acfb50b03b0be3eda5282f26bad34ffc18595b30 Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Fri, 8 Sep 2023 10:54:35 -0700 +Subject: [PATCH 2/9] [Clang][LoongArch] Generate _mcount instead of mcount + (#65657) + +When building the LoongArch Linux kernel without +`CONFIG_DYNAMIC_FTRACE`, the build fails to link because the mcount +symbol is `mcount`, not `_mcount` like GCC generates and the kernel +expects: + +``` +ld.lld: error: undefined symbol: mcount +>>> referenced by version.c +>>> init/version.o:(early_hostname) in archive vmlinux.a +>>> referenced by do_mounts.c +>>> init/do_mounts.o:(rootfs_init_fs_context) in archive vmlinux.a +>>> referenced by main.c +>>> init/main.o:(__traceiter_initcall_level) in archive vmlinux.a +>>> referenced 97011 more times +>>> did you mean: _mcount +>>> defined in: vmlinux.a(arch/loongarch/kernel/mcount.o) +``` + +Set `MCountName` in `LoongArchTargetInfo` to `_mcount`, which resolves +the build failure. + +(cherry picked from commit cc2b09bee017147527e7bd1eb5272f4f70a7b900) +--- + clang/lib/Basic/Targets/LoongArch.h | 1 + + clang/test/CodeGen/mcount.c | 2 ++ + 2 files changed, 3 insertions(+) + +diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h +index 8f4150b2539d..3313102492cb 100644 +--- a/clang/lib/Basic/Targets/LoongArch.h ++++ b/clang/lib/Basic/Targets/LoongArch.h +@@ -40,6 +40,7 @@ public: + LongDoubleWidth = 128; + LongDoubleAlign = 128; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); ++ MCountName = "_mcount"; + SuitableAlign = 128; + WCharType = SignedInt; + WIntType = UnsignedInt; +diff --git a/clang/test/CodeGen/mcount.c b/clang/test/CodeGen/mcount.c +index 8f994ab4e754..bdd609c1dfc5 100644 +--- a/clang/test/CodeGen/mcount.c ++++ b/clang/test/CodeGen/mcount.c +@@ -7,6 +7,8 @@ + // RUN: %clang_cc1 -pg -triple x86_64-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s + // RUN: %clang_cc1 -pg -triple arm-netbsd-eabi -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s + // RUN: %clang_cc1 -pg -triple aarch64-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s ++// RUN: %clang_cc1 -pg -triple loongarch32 -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s ++// RUN: %clang_cc1 -pg -triple loongarch64 -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s + // RUN: %clang_cc1 -pg -triple mips-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s + // RUN: %clang_cc1 -pg -triple mips-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s + // RUN: %clang_cc1 -pg -triple mipsel-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +-- +2.20.1 + + +From a841576d7a53d3d8fd61aa854af7d9c2dd204536 Mon Sep 17 00:00:00 2001 +From: Weining Lu +Date: Thu, 26 Oct 2023 11:50:28 +0800 +Subject: [PATCH 3/9] [LoongArch][test] Add some ABI regression tests for empty + struct. NFC + +How empty structs (not as fields of container struct) are passed in C++ +is not explicitly documented in psABI. This patch adds some tests +showing the current handing of clang. Some of the results are different +from gcc. Following patch(es) will try to fix the mismatch. + +(cherry picked from commit 8149066fa532d82ff62a0629d5a9fab6bd4da768) +--- + .../LoongArch/abi-lp64d-empty-structs.c | 53 +++++++++++++++++++ + 1 file changed, 53 insertions(+) + +diff --git a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c +index fb90bf556c19..d0daafac336e 100644 +--- a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c ++++ b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c +@@ -81,9 +81,62 @@ struct s8 test_s8(struct s8 a) { + return a; + } + ++/// Note: Below tests check how empty structs are passed while above tests check ++/// empty structs as fields of container struct are ignored when flattening ++/// structs to examine whether the container structs can be passed via FARs. ++ + // 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; + } ++ ++// CHECK-C: define{{.*}} void @test_s10() ++// CHECK-CXX: define{{.*}} void @_Z8test_s103s10() ++struct s10 { }; ++struct s10 test_s10(struct s10 a) { ++ return a; ++} ++ ++// CHECK-C: define{{.*}} void @test_s11() ++// CHECK-CXX: define{{.*}} i64 @_Z8test_s113s11(i64 {{.*}}) ++struct s11 { struct { } s; }; ++struct s11 test_s11(struct s11 a) { ++ return a; ++} ++ ++// CHECK-C: define{{.*}} void @test_s12() ++// CHECK-CXX: define{{.*}} void @_Z8test_s123s12() ++struct s12 { int i[0]; }; ++struct s12 test_s12(struct s12 a) { ++ return a; ++} ++ ++// CHECK-C: define{{.*}} void @test_s13() ++// CHECK-CXX: define{{.*}} void @_Z8test_s133s13() ++struct s13 { struct { } s[0]; }; ++struct s13 test_s13(struct s13 a) { ++ return a; ++} ++ ++// CHECK-C: define{{.*}} void @test_s14() ++// CHECK-CXX: define{{.*}} i64 @_Z8test_s143s14(i64 {{.*}}) ++struct s14 { struct { } s[1]; }; ++struct s14 test_s14(struct s14 a) { ++ return a; ++} ++ ++// CHECK-C: define{{.*}} void @test_s15() ++// CHECK-CXX: define{{.*}} void @_Z8test_s153s15() ++struct s15 { int : 0; }; ++struct s15 test_s15(struct s15 a) { ++ return a; ++} ++ ++// CHECK-C: define{{.*}} void @test_s16() ++// CHECK-CXX: define{{.*}} void @_Z8test_s163s16() ++struct s16 { int : 1; }; ++struct s16 test_s16(struct s16 a) { ++ return a; ++} +-- +2.20.1 + + +From 6248fa0fc405952a8b907624c27b2dd1ee86a962 Mon Sep 17 00:00:00 2001 +From: Lu Weining +Date: Tue, 31 Oct 2023 21:18:06 +0800 +Subject: [PATCH 4/9] [LoongArch] Fix ABI mismatch with gcc/g++ about empty + structs passing (#70320) + +How empty structs (not as fields of container struct) are passed in C++ +is not explicitly documented in psABI. However, this patch fixes the +mismatch with g++. + +Note that the unnamed bitfield case `struct { int : 1; }` in C is also +fixed. Previously clang regards it as an empty struct and then ignores +it when passing. Now size of the struct is counted; since it's size is +not 0, clang will not ignore it even in C. + +While https://reviews.llvm.org/D156116 fixed the handling of empty +struct when considering eligibility of the container struct for the FP +calling convention ('flattening'), this patch fixes the handling of +passing the empty struct itself. + +Fix https://github.com/llvm/llvm-project/issues/70319 + +(cherry picked from commit 9ca6bf3fb7b7df373723b3275730f101f9ff816b) +--- + clang/lib/CodeGen/Targets/LoongArch.cpp | 10 ++++++---- + clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c | 8 ++++---- + 2 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp +index 7483bf6d6d1e..bc508a99da9c 100644 +--- a/clang/lib/CodeGen/Targets/LoongArch.cpp ++++ b/clang/lib/CodeGen/Targets/LoongArch.cpp +@@ -308,12 +308,14 @@ ABIArgInfo LoongArchABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, + CGCXXABI::RAA_DirectInMemory); + } + +- // Ignore empty structs/unions. +- if (isEmptyRecord(getContext(), Ty, true)) +- return ABIArgInfo::getIgnore(); +- + uint64_t Size = getContext().getTypeSize(Ty); + ++ // Ignore empty struct or union whose size is zero, e.g. `struct { }` in C or ++ // `struct { int a[0]; }` in C++. In C++, `struct { }` is empty but it's size ++ // is 1 byte and g++ doesn't ignore it; clang++ matches this behaviour. ++ if (isEmptyRecord(getContext(), Ty, true) && Size == 0) ++ return ABIArgInfo::getIgnore(); ++ + // Pass floating point values via FARs if possible. + if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() && + FRLen >= Size && FARsLeft) { +diff --git a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c +index d0daafac336e..281b7b15841a 100644 +--- a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c ++++ b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c +@@ -93,7 +93,7 @@ struct s9 test_s9(struct s9 a) { + } + + // CHECK-C: define{{.*}} void @test_s10() +-// CHECK-CXX: define{{.*}} void @_Z8test_s103s10() ++// CHECK-CXX: define{{.*}} i64 @_Z8test_s103s10(i64 {{.*}}) + struct s10 { }; + struct s10 test_s10(struct s10 a) { + return a; +@@ -128,14 +128,14 @@ struct s14 test_s14(struct s14 a) { + } + + // CHECK-C: define{{.*}} void @test_s15() +-// CHECK-CXX: define{{.*}} void @_Z8test_s153s15() ++// CHECK-CXX: define{{.*}} i64 @_Z8test_s153s15(i64 {{.*}}) + struct s15 { int : 0; }; + struct s15 test_s15(struct s15 a) { + return a; + } + +-// CHECK-C: define{{.*}} void @test_s16() +-// CHECK-CXX: define{{.*}} void @_Z8test_s163s16() ++// CHECK-C: define{{.*}} i64 @test_s16(i64 {{.*}}) ++// CHECK-CXX: define{{.*}} i64 @_Z8test_s163s16(i64 {{.*}}) + struct s16 { int : 1; }; + struct s16 test_s16(struct s16 a) { + return a; +-- +2.20.1 + + +From 028d0d88cd73c724f954577dc90cbbc2873a6832 Mon Sep 17 00:00:00 2001 +From: Weining Lu +Date: Thu, 2 Nov 2023 09:29:43 +0800 +Subject: [PATCH 5/9] [LoongArch] Pre-commit test for issue #70890 + +(cherry picked from commit 749083b91f31f370cf64831d3e7e6215b6d51442) +--- + .../LoongArch/abi-lp64d-empty-unions.c | 26 +++++++++++++++++++ + 1 file changed, 26 insertions(+) + create mode 100644 clang/test/CodeGen/LoongArch/abi-lp64d-empty-unions.c + +diff --git a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-unions.c b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-unions.c +new file mode 100644 +index 000000000000..b0607425336e +--- /dev/null ++++ b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-unions.c +@@ -0,0 +1,26 @@ ++// 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 ++ ++#include ++ ++// CHECK-C: define{{.*}} void @test1() ++// CHECK-CXX: define{{.*}} i64 @_Z5test12u1(i64{{[^,]*}}) ++union u1 { }; ++union u1 test1(union u1 a) { ++ return a; ++} ++ ++struct s1 { ++ union u1 u; ++ int i; ++ float f; ++}; ++ ++// CHECK-C: define{{.*}} { i32, float } @test2(i32{{[^,]*}}, float{{[^,]*}}) ++/// FIXME: This doesn't match g++. ++// CHECK-CXX: define{{.*}} { i32, float } @_Z5test22s1(i32{{[^,]*}}, float{{[^,]*}}) ++struct s1 test2(struct s1 a) { ++ return a; ++} +-- +2.20.1 + + +From 8c4371c0e53635a23852d0dc7025b4c48495277b Mon Sep 17 00:00:00 2001 +From: Lu Weining +Date: Sat, 4 Nov 2023 10:04:37 +0800 +Subject: [PATCH 6/9] [LoongArch] Fix ABI mismatch with g++ when handling empty + unions (#71025) + +In g++, empty unions are not ignored like empty structs when flattening +structs to examine whether the structs can be passed via FARs in C++. +This patch aligns clang++ with g++. + +Fix https://github.com/llvm/llvm-project/issues/70890. + +(cherry picked from commit 4253fdc2c462da61cc0deb74a43265665720c828) +--- + clang/lib/CodeGen/Targets/LoongArch.cpp | 7 ++++--- + clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c | 2 +- + clang/test/CodeGen/LoongArch/abi-lp64d-empty-unions.c | 3 +-- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp +index bc508a99da9c..63b9a1fdb988 100644 +--- a/clang/lib/CodeGen/Targets/LoongArch.cpp ++++ b/clang/lib/CodeGen/Targets/LoongArch.cpp +@@ -170,10 +170,11 @@ 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, true)) +- return true; + const RecordDecl *RD = RTy->getDecl(); +- // Unions aren't eligible unless they're empty (which is caught above). ++ if (isEmptyRecord(getContext(), Ty, true, true) && ++ (!RD->isUnion() || !isa(RD))) ++ return true; ++ // Unions aren't eligible unless they're empty in C (which is caught above). + if (RD->isUnion()) + return false; + const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); +diff --git a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c +index 281b7b15841a..2f7596f0ebdc 100644 +--- a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c ++++ b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c +@@ -3,7 +3,7 @@ + // 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 ++// Fields containing empty structs 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 +diff --git a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-unions.c b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-unions.c +index b0607425336e..363e37efb646 100644 +--- a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-unions.c ++++ b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-unions.c +@@ -19,8 +19,7 @@ struct s1 { + }; + + // CHECK-C: define{{.*}} { i32, float } @test2(i32{{[^,]*}}, float{{[^,]*}}) +-/// FIXME: This doesn't match g++. +-// CHECK-CXX: define{{.*}} { i32, float } @_Z5test22s1(i32{{[^,]*}}, float{{[^,]*}}) ++// CHECK-CXX: define{{.*}} [2 x i64] @_Z5test22s1([2 x i64]{{[^,]*}}) + struct s1 test2(struct s1 a) { + return a; + } +-- +2.20.1 + + +From 8e855955a009ec398b9f7da88e980dae9d20c420 Mon Sep 17 00:00:00 2001 +From: Fangrui Song +Date: Tue, 14 Nov 2023 00:43:40 -0800 +Subject: [PATCH 7/9] [Driver] Default LoongArch to + -fno-direct-access-external-data for non-PIC (#72221) + +For -fno-pic, if an extern variable is defined in a DSO, a copy +relocation will be needed. However, loongarch*-linux does not and will +not support copy relocations. + +Change Driver to default to -fno-direct-access-external-data for +LoongArch && non-PIC. +Keep Frontend conditions unchanged (-fdirect-access-external-data || +-fno-direct-access-external-data && PIC>0 => direct access). + +Fix #71645 + +(cherry picked from commit 47eeee297775347cbdb7624d6a766c2a3eec4a59) +--- + clang/lib/Driver/ToolChains/Clang.cpp | 7 ++++++- + clang/test/Driver/fdirect-access-external-data.c | 6 ++++++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp +index 6b5930990f11..b21aeaee7f5a 100644 +--- a/clang/lib/Driver/ToolChains/Clang.cpp ++++ b/clang/lib/Driver/ToolChains/Clang.cpp +@@ -5632,10 +5632,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, + // defaults to -fno-direct-access-external-data. Pass the option if different + // from the default. + if (Arg *A = Args.getLastArg(options::OPT_fdirect_access_external_data, +- options::OPT_fno_direct_access_external_data)) ++ options::OPT_fno_direct_access_external_data)) { + if (A->getOption().matches(options::OPT_fdirect_access_external_data) != + (PICLevel == 0)) + A->render(Args, CmdArgs); ++ } else if (PICLevel == 0 && Triple.isLoongArch()) { ++ // Some targets default to -fno-direct-access-external-data even for ++ // -fno-pic. ++ CmdArgs.push_back("-fno-direct-access-external-data"); ++ } + + if (Args.hasFlag(options::OPT_fno_plt, options::OPT_fplt, false)) { + CmdArgs.push_back("-fno-plt"); +diff --git a/clang/test/Driver/fdirect-access-external-data.c b/clang/test/Driver/fdirect-access-external-data.c +index f132b1b088af..a6da776e6977 100644 +--- a/clang/test/Driver/fdirect-access-external-data.c ++++ b/clang/test/Driver/fdirect-access-external-data.c +@@ -9,6 +9,12 @@ + // RUN: %clang -### -c -target aarch64 %s -fpic 2>&1 | FileCheck %s --check-prefix=DEFAULT + // RUN: %clang -### -c -target aarch64 %s -fpic -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DIRECT + ++/// loongarch* targets default to -fno-direct-access-external-data even for -fno-pic. ++// RUN: %clang -### -c --target=loongarch64 -fno-pic %s 2>&1 | FileCheck %s --check-prefix=INDIRECT ++// RUN: %clang -### -c --target=loongarch64 -fpie %s 2>&1 | FileCheck %s --check-prefix=DEFAULT ++// RUN: %clang -### -c --target=loongarch32 -fno-pic -fdirect-access-external-data %s 2>&1 | FileCheck %s --check-prefix=DEFAULT ++// RUN: %clang -### -c --target=loongarch32 -fpie -fdirect-access-external-data %s 2>&1 | FileCheck %s --check-prefix=DIRECT ++ + // DEFAULT-NOT: direct-access-external-data" + // DIRECT: "-fdirect-access-external-data" + // INDIRECT: "-fno-direct-access-external-data" +-- +2.20.1 + + +From 29409970a5c68e20022a05457127102a66abfead Mon Sep 17 00:00:00 2001 +From: wanglei +Date: Tue, 5 Mar 2024 19:44:28 +0800 +Subject: [PATCH 8/9] [Clang][LoongArch] Precommit test for fix wrong return + value type of __iocsrrd_h. NFC + +(cherry picked from commit aeda1a6e800e0dd6c91c0332b4db95094ad5b301) +(cherry picked from commit a9ba36c7e7d7fa076f201843e3b826b6c6d7f5ef) +--- + clang/test/CodeGen/LoongArch/intrinsic-la32.c | 29 ++++++++++++++----- + clang/test/CodeGen/LoongArch/intrinsic-la64.c | 21 ++++++++++++-- + 2 files changed, 40 insertions(+), 10 deletions(-) + +diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la32.c b/clang/test/CodeGen/LoongArch/intrinsic-la32.c +index 93d54f511a9c..6a8d99880be3 100644 +--- a/clang/test/CodeGen/LoongArch/intrinsic-la32.c ++++ b/clang/test/CodeGen/LoongArch/intrinsic-la32.c +@@ -169,8 +169,8 @@ unsigned int cpucfg(unsigned int a) { + + // LA32-LABEL: @rdtime( + // LA32-NEXT: entry: +-// LA32-NEXT: [[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc !2 +-// LA32-NEXT: [[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !3 ++// LA32-NEXT: [[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc [[META2:![0-9]+]] ++// LA32-NEXT: [[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc [[META3:![0-9]+]] + // LA32-NEXT: ret void + // + void rdtime() { +@@ -201,13 +201,28 @@ void loongarch_movgr2fcsr(int a) { + __builtin_loongarch_movgr2fcsr(1, a); + } + +-// CHECK-LABEL: @cacop_w( +-// CHECK-NEXT: entry: +-// CHECK-NEXT: tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A:%.*]], i32 1024) +-// CHECK-NEXT: tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A]], i32 1024) +-// CHECK-NEXT: ret void ++// LA32-LABEL: @cacop_w( ++// LA32-NEXT: entry: ++// LA32-NEXT: tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A:%.*]], i32 1024) ++// LA32-NEXT: tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A]], i32 1024) ++// LA32-NEXT: ret void + // + void cacop_w(unsigned long int a) { + __cacop_w(1, a, 1024); + __builtin_loongarch_cacop_w(1, a, 1024); + } ++ ++// LA32-LABEL: @iocsrrd_h_result( ++// LA32-NEXT: entry: ++// LA32-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.iocsrrd.h(i32 [[A:%.*]]) ++// LA32-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.iocsrrd.h(i32 [[A]]) ++// LA32-NEXT: [[CONV2:%.*]] = and i32 [[TMP0]], 255 ++// LA32-NEXT: [[ADD:%.*]] = add i32 [[TMP1]], [[CONV2]] ++// LA32-NEXT: [[CONV4:%.*]] = trunc i32 [[ADD]] to i16 ++// LA32-NEXT: ret i16 [[CONV4]] ++// ++unsigned short iocsrrd_h_result(unsigned int a) { ++ unsigned short b = __iocsrrd_h(a); ++ unsigned short c = __builtin_loongarch_iocsrrd_h(a); ++ return b+c; ++} +diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la64.c b/clang/test/CodeGen/LoongArch/intrinsic-la64.c +index a740882eef54..48b6a7a3d227 100644 +--- a/clang/test/CodeGen/LoongArch/intrinsic-la64.c ++++ b/clang/test/CodeGen/LoongArch/intrinsic-la64.c +@@ -387,7 +387,7 @@ unsigned int cpucfg(unsigned int a) { + + // CHECK-LABEL: @rdtime_d( + // CHECK-NEXT: entry: +-// CHECK-NEXT: [[TMP0:%.*]] = tail call { i64, i64 } asm sideeffect "rdtime.d $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc !2 ++// CHECK-NEXT: [[TMP0:%.*]] = tail call { i64, i64 } asm sideeffect "rdtime.d $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc [[META2:![0-9]+]] + // CHECK-NEXT: ret void + // + void rdtime_d() { +@@ -396,8 +396,8 @@ void rdtime_d() { + + // CHECK-LABEL: @rdtime( + // CHECK-NEXT: entry: +-// CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !3 +-// CHECK-NEXT: [[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !4 ++// CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc [[META3:![0-9]+]] ++// CHECK-NEXT: [[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc [[META4:![0-9]+]] + // CHECK-NEXT: ret void + // + void rdtime() { +@@ -427,3 +427,18 @@ void loongarch_movgr2fcsr(int a) { + __movgr2fcsr(1, a); + __builtin_loongarch_movgr2fcsr(1, a); + } ++ ++// CHECK-LABEL: @iocsrrd_h_result( ++// CHECK-NEXT: entry: ++// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.iocsrrd.h(i32 [[A:%.*]]) ++// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.iocsrrd.h(i32 [[A]]) ++// CHECK-NEXT: [[CONV2:%.*]] = and i32 [[TMP0]], 255 ++// CHECK-NEXT: [[ADD:%.*]] = add i32 [[TMP1]], [[CONV2]] ++// CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[ADD]] to i16 ++// CHECK-NEXT: ret i16 [[CONV4]] ++// ++unsigned short iocsrrd_h_result(unsigned int a) { ++ unsigned short b = __iocsrrd_h(a); ++ unsigned short c = __builtin_loongarch_iocsrrd_h(a); ++ return b+c; ++} +-- +2.20.1 + + +From 47425dfdd1582ec652aba1c289f3a80fe25c1a8c Mon Sep 17 00:00:00 2001 +From: wanglei +Date: Wed, 6 Mar 2024 10:03:28 +0800 +Subject: [PATCH 9/9] [Clang][LoongArch] Fix wrong return value type of + __iocsrrd_h (#84100) + +relate: +https: //gcc.gnu.org/pipermail/gcc-patches/2024-February/645016.html +(cherry picked from commit 2f479b811274fede36535e34ecb545ac22e399c3) +(cherry picked from commit 9b9aee16d4dcf1b4af49988ebd7918fa4ce77e44) +--- + clang/lib/Headers/larchintrin.h | 2 +- + clang/test/CodeGen/LoongArch/intrinsic-la32.c | 8 ++++---- + clang/test/CodeGen/LoongArch/intrinsic-la64.c | 8 ++++---- + 3 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/clang/lib/Headers/larchintrin.h b/clang/lib/Headers/larchintrin.h +index c5c533ee0b8c..24dd29ce91ff 100644 +--- a/clang/lib/Headers/larchintrin.h ++++ b/clang/lib/Headers/larchintrin.h +@@ -156,7 +156,7 @@ extern __inline unsigned char + return (unsigned char)__builtin_loongarch_iocsrrd_b((unsigned int)_1); + } + +-extern __inline unsigned char ++extern __inline unsigned short + __attribute__((__gnu_inline__, __always_inline__, __artificial__)) + __iocsrrd_h(unsigned int _1) { + return (unsigned short)__builtin_loongarch_iocsrrd_h((unsigned int)_1); +diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la32.c b/clang/test/CodeGen/LoongArch/intrinsic-la32.c +index 6a8d99880be3..eb3f8cbe7ac4 100644 +--- a/clang/test/CodeGen/LoongArch/intrinsic-la32.c ++++ b/clang/test/CodeGen/LoongArch/intrinsic-la32.c +@@ -215,11 +215,11 @@ void cacop_w(unsigned long int a) { + // LA32-LABEL: @iocsrrd_h_result( + // LA32-NEXT: entry: + // LA32-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.iocsrrd.h(i32 [[A:%.*]]) ++// LA32-NEXT: [[CONV_I:%.*]] = trunc i32 [[TMP0]] to i16 + // LA32-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.iocsrrd.h(i32 [[A]]) +-// LA32-NEXT: [[CONV2:%.*]] = and i32 [[TMP0]], 255 +-// LA32-NEXT: [[ADD:%.*]] = add i32 [[TMP1]], [[CONV2]] +-// LA32-NEXT: [[CONV4:%.*]] = trunc i32 [[ADD]] to i16 +-// LA32-NEXT: ret i16 [[CONV4]] ++// LA32-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16 ++// LA32-NEXT: [[CONV3:%.*]] = add i16 [[TMP2]], [[CONV_I]] ++// LA32-NEXT: ret i16 [[CONV3]] + // + unsigned short iocsrrd_h_result(unsigned int a) { + unsigned short b = __iocsrrd_h(a); +diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la64.c b/clang/test/CodeGen/LoongArch/intrinsic-la64.c +index 48b6a7a3d227..50ec358f546e 100644 +--- a/clang/test/CodeGen/LoongArch/intrinsic-la64.c ++++ b/clang/test/CodeGen/LoongArch/intrinsic-la64.c +@@ -431,11 +431,11 @@ void loongarch_movgr2fcsr(int a) { + // CHECK-LABEL: @iocsrrd_h_result( + // CHECK-NEXT: entry: + // CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.iocsrrd.h(i32 [[A:%.*]]) ++// CHECK-NEXT: [[CONV_I:%.*]] = trunc i32 [[TMP0]] to i16 + // CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.iocsrrd.h(i32 [[A]]) +-// CHECK-NEXT: [[CONV2:%.*]] = and i32 [[TMP0]], 255 +-// CHECK-NEXT: [[ADD:%.*]] = add i32 [[TMP1]], [[CONV2]] +-// CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[ADD]] to i16 +-// CHECK-NEXT: ret i16 [[CONV4]] ++// CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16 ++// CHECK-NEXT: [[CONV3:%.*]] = add i16 [[TMP2]], [[CONV_I]] ++// CHECK-NEXT: ret i16 [[CONV3]] + // + unsigned short iocsrrd_h_result(unsigned int a) { + unsigned short b = __iocsrrd_h(a); +-- +2.20.1 + diff --git a/clang.spec b/clang.spec index 84919a5a6501d1ea692766acd388f8fb3398cb1a..0152e88c442289b227075a45f5424afd9ebe551b 100644 --- a/clang.spec +++ b/clang.spec @@ -36,7 +36,7 @@ Name: %{pkg_name} Version: %{clang_version} -Release: 11 +Release: 12 Summary: A C language family front-end for LLVM License: NCSA @@ -53,6 +53,7 @@ Patch5: 0005-backport-Disable-InterpreterExceptionTest-on-RISC-V.patch Patch6: 0006-clang-LoongArch-Add-loongarch64-to-os-triple.patch Patch7: 0007-add-more-warning-options-to-fgcc-compatible.patch Patch8: 0008-Backport-LoongArch-Add-the-support-for-vector.patch +Patch9: 0009-Backport-LoongArch-improve-the-support-for-compiler-rt-and-bugfix.patch # Patches for clang-tools-extra # See https://reviews.llvm.org/D120301 @@ -381,6 +382,9 @@ LD_LIBRARY_PATH=%{buildroot}/%{install_libdir} %{__ninja} check-all -C ./_build %{install_bindir}/git-clang-format %changelog +* Tue Apr 09 2024 zhanglimin - 17.0.6-12 +- Improve the support for compiler-rt and fix some bugs on LoongArch. + * Fri Mar 29 2024 zhanglimin -17.0.6-11 - Add the support for vector on LoongArch.