Skip to content

Commit

Permalink
[RISCV] Allow mismatched SmallDataLimit and use Min for conflicting v…
Browse files Browse the repository at this point in the history
…alues

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
  • Loading branch information
MaskRay committed Feb 8, 2023
1 parent 9aa00c8 commit af12879
Show file tree
Hide file tree
Showing 8 changed files with 21 additions and 21 deletions.
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CodeGenModule.cpp
Expand Up @@ -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);
}
}
Expand Down
26 changes: 13 additions & 13 deletions clang/test/CodeGen/RISCV/riscv-sdata-module-flag.c
Expand Up @@ -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=
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vlenb.c
Expand Up @@ -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"}
//.
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/RISCV/sdata-limit-0.ll
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/RISCV/sdata-limit-4.ll
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/RISCV/sdata-limit-8.ll
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/RISCV/sdata-local-sym.ll
Expand Up @@ -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
Expand Down
Expand Up @@ -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}
Expand Down

0 comments on commit af12879

Please sign in to comment.