From af128791464810123bcd60a6d9d0902b5c550aef Mon Sep 17 00:00:00 2001 From: Fangrui Song 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 Signed-off-by: jianxin.lai Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D131230 --- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/test/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 3258a97..57c9e58 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 89c9cc8..aa407c17 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 b65e657..9f4fca0 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 2c90cb9..5290802 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 ec482cf2..7e99a88 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 1c67add..3efe773 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 b5032ae..e2336be 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 d51feae..5fc46c2 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.7.4