blob: cf6b2e608f24cbdc9a88419d2fe2873f8dfee460 [file] [log] [blame]
From af128791464810123bcd60a6d9d0902b5c550aef Mon Sep 17 00:00:00 2001
From: Fangrui Song <i@maskray.me>
Date: Tue, 7 Feb 2023 17:13:21 -0800
Subject: [PATCH] [RISCV] Allow mismatched SmallDataLimit and use Min for
conflicting values
Fix an issue about module linking with LTO.
When compiling with PIE, the small data limitation needs to be consistent with that in PIC, otherwise there will be linking errors due to conflicting values.
bar.c
```
int bar() { return 1; }
```
foo.c
```
int foo() { return 1; }
```
```
clang --target=riscv64-unknown-linux-gnu -flto -c foo.c -o foo.o -fPIE
clang --target=riscv64-unknown-linux-gnu -flto -c bar.c -o bar.o -fPIC
clang --target=riscv64-unknown-linux-gnu -flto foo.o bar.o -flto -nostdlib -v -fuse-ld=lld
```
```
ld.lld: error: linking module flags 'SmallDataLimit': IDs have conflicting values in 'bar.o' and 'ld-temp.o'
clang-15: error: linker command failed with exit code 1 (use -v to see invocation)
```
Use Min instead of Error for conflicting SmallDataLimit.
Authored by: @joshua-arch1
Signed-off-by: xiaojing.zhang <xiaojing.zhang@xcalibyte.com>
Signed-off-by: jianxin.lai <jianxin.lai@xcalibyte.com>
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D131230
---
clang/lib/CodeGen/CodeGenModule.cpp | 2 +-
.../CodeGen/RISCV/riscv-sdata-module-flag.c | 26 +++++++++----------
.../RISCV/rvv-intrinsics-handcrafted/vlenb.c | 4 +--
llvm/test/CodeGen/RISCV/sdata-limit-0.ll | 2 +-
llvm/test/CodeGen/RISCV/sdata-limit-4.ll | 2 +-
llvm/test/CodeGen/RISCV/sdata-limit-8.ll | 2 +-
llvm/test/CodeGen/RISCV/sdata-local-sym.ll | 2 +-
.../LoopVectorize/RISCV/riscv-interleaved.ll | 2 +-
8 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 3258a97c4699..57c9e589be3b 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -980,7 +980,7 @@ void CodeGenModule::EmitOpenCLMetadata() {
void CodeGenModule::EmitBackendOptionsMetadata(
const CodeGenOptions CodeGenOpts) {
if (getTriple().isRISCV()) {
- getModule().addModuleFlag(llvm::Module::Error, "SmallDataLimit",
+ getModule().addModuleFlag(llvm::Module::Min, "SmallDataLimit",
CodeGenOpts.SmallDataLimit);
}
}
diff --git a/clang/test/CodeGen/RISCV/riscv-sdata-module-flag.c b/clang/test/CodeGen/RISCV/riscv-sdata-module-flag.c
index 89c9cc8cb0d0..aa407c17ea05 100644
--- a/clang/test/CodeGen/RISCV/riscv-sdata-module-flag.c
+++ b/clang/test/CodeGen/RISCV/riscv-sdata-module-flag.c
@@ -28,20 +28,20 @@
void test(void) {}
-// RV32-DEFAULT: !{i32 1, !"SmallDataLimit", i32 8}
-// RV32-G4: !{i32 1, !"SmallDataLimit", i32 4}
-// RV32-S0: !{i32 1, !"SmallDataLimit", i32 0}
-// RV32-S2G4: !{i32 1, !"SmallDataLimit", i32 4}
-// RV32-T16: !{i32 1, !"SmallDataLimit", i32 16}
-// RV32-PIC: !{i32 1, !"SmallDataLimit", i32 0}
+// RV32-DEFAULT: !{i32 8, !"SmallDataLimit", i32 8}
+// RV32-G4: !{i32 8, !"SmallDataLimit", i32 4}
+// RV32-S0: !{i32 8, !"SmallDataLimit", i32 0}
+// RV32-S2G4: !{i32 8, !"SmallDataLimit", i32 4}
+// RV32-T16: !{i32 8, !"SmallDataLimit", i32 16}
+// RV32-PIC: !{i32 8, !"SmallDataLimit", i32 0}
-// RV64-DEFAULT: !{i32 1, !"SmallDataLimit", i32 8}
-// RV64-G4: !{i32 1, !"SmallDataLimit", i32 4}
-// RV64-S0: !{i32 1, !"SmallDataLimit", i32 0}
-// RV64-S2G4: !{i32 1, !"SmallDataLimit", i32 4}
-// RV64-T16: !{i32 1, !"SmallDataLimit", i32 16}
-// RV64-PIC: !{i32 1, !"SmallDataLimit", i32 0}
-// RV64-LARGE: !{i32 1, !"SmallDataLimit", i32 0}
+// RV64-DEFAULT: !{i32 8, !"SmallDataLimit", i32 8}
+// RV64-G4: !{i32 8, !"SmallDataLimit", i32 4}
+// RV64-S0: !{i32 8, !"SmallDataLimit", i32 0}
+// RV64-S2G4: !{i32 8, !"SmallDataLimit", i32 4}
+// RV64-T16: !{i32 8, !"SmallDataLimit", i32 16}
+// RV64-PIC: !{i32 8, !"SmallDataLimit", i32 0}
+// RV64-LARGE: !{i32 8, !"SmallDataLimit", i32 0}
// The value will be passed by module flag instead of target feature.
// RV32-S0-NOT: +small-data-limit=
diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c
index b65e657652fc..9f4fca00a796 100644
--- a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c
+++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c
@@ -29,11 +29,11 @@ unsigned long test_vlenb(void) {
//.
// RV32: !0 = !{i32 1, !"wchar_size", i32 4}
// RV32: !1 = !{i32 1, !"target-abi", !"ilp32d"}
-// RV32: !2 = !{i32 1, !"SmallDataLimit", i32 0}
+// RV32: !2 = !{i32 8, !"SmallDataLimit", i32 0}
// RV32: !3 = !{!"vlenb"}
//.
// RV64: !0 = !{i32 1, !"wchar_size", i32 4}
// RV64: !1 = !{i32 1, !"target-abi", !"lp64d"}
-// RV64: !2 = !{i32 1, !"SmallDataLimit", i32 0}
+// RV64: !2 = !{i32 8, !"SmallDataLimit", i32 0}
// RV64: !3 = !{!"vlenb"}
//.
diff --git a/llvm/test/CodeGen/RISCV/sdata-limit-0.ll b/llvm/test/CodeGen/RISCV/sdata-limit-0.ll
index 2c90cb9666a2..5290802a2865 100644
--- a/llvm/test/CodeGen/RISCV/sdata-limit-0.ll
+++ b/llvm/test/CodeGen/RISCV/sdata-limit-0.ll
@@ -6,7 +6,7 @@
; SmallDataLimit set to 0, so we expect no data will put in sbss and sdata.
!llvm.module.flags = !{!0}
-!0 = !{i32 1, !"SmallDataLimit", i32 0}
+!0 = !{i32 8, !"SmallDataLimit", i32 0}
; RV32-NOT: .section .sbss
; RV32-NOT: .section .sdata
diff --git a/llvm/test/CodeGen/RISCV/sdata-limit-4.ll b/llvm/test/CodeGen/RISCV/sdata-limit-4.ll
index ec482cf2ae96..7e99a88b4dee 100644
--- a/llvm/test/CodeGen/RISCV/sdata-limit-4.ll
+++ b/llvm/test/CodeGen/RISCV/sdata-limit-4.ll
@@ -7,7 +7,7 @@
; SmallDataLimit set to 4, so we expect @v will be put in sbss,
; but @r won't be put in sdata.
!llvm.module.flags = !{!0}
-!0 = !{i32 1, !"SmallDataLimit", i32 4}
+!0 = !{i32 8, !"SmallDataLimit", i32 4}
; RV32: .section .sbss
; RV32-NOT: .section .sdata
diff --git a/llvm/test/CodeGen/RISCV/sdata-limit-8.ll b/llvm/test/CodeGen/RISCV/sdata-limit-8.ll
index 1c67addf1070..3efe7739813e 100644
--- a/llvm/test/CodeGen/RISCV/sdata-limit-8.ll
+++ b/llvm/test/CodeGen/RISCV/sdata-limit-8.ll
@@ -7,7 +7,7 @@
; SmallDataLimit set to 8, so we expect @v will be put in sbss
; and @r will be put in sdata.
!llvm.module.flags = !{!0}
-!0 = !{i32 1, !"SmallDataLimit", i32 8}
+!0 = !{i32 8, !"SmallDataLimit", i32 8}
; RV32: .section .sbss
; RV32: .section .sdata
diff --git a/llvm/test/CodeGen/RISCV/sdata-local-sym.ll b/llvm/test/CodeGen/RISCV/sdata-local-sym.ll
index b5032aecefed..e2336be51d08 100644
--- a/llvm/test/CodeGen/RISCV/sdata-local-sym.ll
+++ b/llvm/test/CodeGen/RISCV/sdata-local-sym.ll
@@ -8,7 +8,7 @@
; SmallDataLimit set to 8, so we expect @v will be put in sbss
; and @r will be put in sdata.
!llvm.module.flags = !{!0}
-!0 = !{i32 1, !"SmallDataLimit", i32 8}
+!0 = !{i32 8, !"SmallDataLimit", i32 8}
; RV32: .section .sbss
; RV32: .section .sdata
diff --git a/llvm/test/Transforms/LoopVectorize/RISCV/riscv-interleaved.ll b/llvm/test/Transforms/LoopVectorize/RISCV/riscv-interleaved.ll
index d51feae33e72..5fc46c203167 100644
--- a/llvm/test/Transforms/LoopVectorize/RISCV/riscv-interleaved.ll
+++ b/llvm/test/Transforms/LoopVectorize/RISCV/riscv-interleaved.ll
@@ -41,7 +41,7 @@ attributes #0 = { nofree norecurse nosync nounwind writeonly "frame-pointer"="no
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 1, !"target-abi", !"lp64"}
-!2 = !{i32 1, !"SmallDataLimit", i32 8}
+!2 = !{i32 8, !"SmallDataLimit", i32 8}
!3 = !{!"clang version 13.0.0"}
!4 = !{!5, !5, i64 0}
!5 = !{!"int", !6, i64 0}
--
2.39.1.519.gcb327c4b5f-goog