Skip to content

Commit 733ad3f

Browse files
authored
[LTO] Override TargetABI from module flags if present when creating TargetMachine (#126497)
…argetMachine RISC-V's data layout is determined by the ABI, not just the target triple. However, the TargetMachine is created using the data layout from the target triple, which is not always correct. This patch uses the target ABI from the module and passes it to the TargetMachine, ensuring that the data layout is set correctly according to the ABI. The same problem will happen with other targets like MIPS, but unfortunately, MIPS didn't emit the target-abi into the module flags, so this patch only fixes the issue for RISC-V. NOTE: MIPS with -mabi=n32 can trigger the same issue. Another possible solution is add new parameter to the TargetMachine constructor, but that would require changes in all the targets.
1 parent bedb907 commit 733ad3f

File tree

5 files changed

+40
-1
lines changed

5 files changed

+40
-1
lines changed

llvm/include/llvm/IR/Module.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,9 @@ class LLVM_ABI Module {
10671067

10681068
/// Set the target variant version build SDK version metadata.
10691069
void setDarwinTargetVariantSDKVersion(VersionTuple Version);
1070+
1071+
/// Returns target-abi from MDString, null if target-abi is absent.
1072+
StringRef getTargetABIFromMD();
10701073
};
10711074

10721075
/// Given "llvm.used" or "llvm.compiler.used" as a global name, collect the

llvm/lib/IR/Module.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,3 +915,11 @@ VersionTuple Module::getDarwinTargetVariantSDKVersion() const {
915915
void Module::setDarwinTargetVariantSDKVersion(VersionTuple Version) {
916916
addSDKVersionMD(Version, *this, "darwin.target_variant.SDK Version");
917917
}
918+
919+
StringRef Module::getTargetABIFromMD() {
920+
StringRef TargetABI;
921+
if (auto *TargetABIMD =
922+
dyn_cast_or_null<MDString>(getModuleFlag("target-abi")))
923+
TargetABI = TargetABIMD->getString();
924+
return TargetABI;
925+
}

llvm/lib/LTO/LTOBackend.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,13 @@ createTargetMachine(const Config &Conf, const Target *TheTarget, Module &M) {
221221
else
222222
CodeModel = M.getCodeModel();
223223

224+
TargetOptions TargetOpts = Conf.Options;
225+
if (TargetOpts.MCOptions.ABIName.empty()) {
226+
TargetOpts.MCOptions.ABIName = M.getTargetABIFromMD();
227+
}
228+
224229
std::unique_ptr<TargetMachine> TM(TheTarget->createTargetMachine(
225-
TheTriple.str(), Conf.CPU, Features.getString(), Conf.Options, RelocModel,
230+
TheTriple.str(), Conf.CPU, Features.getString(), TargetOpts, RelocModel,
226231
CodeModel, Conf.CGOptLevel));
227232

228233
assert(TM && "Failed to create target machine");

llvm/test/LTO/RISCV/lit.local.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
if "RISCV" not in config.root.targets:
2+
config.unsupported = True

llvm/test/LTO/RISCV/riscv-ilp32e.ll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; Check that we don't crash on DataLayout incompatibility issue.
2+
; RUN: llvm-as %s -o %t.o
3+
; RUN: llvm-lto2 run -r %t.o,_start %t.o -o %t.elf
4+
; RUN: llvm-readobj -h %t.elf.0 | FileCheck %s --check-prefixes=CHECK
5+
; CHECK: Machine: EM_RISCV (0xF3)
6+
; CHECK: EF_RISCV_RVE (0x8)
7+
8+
9+
target datalayout = "e-m:e-p:32:32-i64:64-n32-S32"
10+
target triple = "riscv32-unknown-unknown-elf"
11+
12+
define dso_local i32 @_start() #0 {
13+
entry:
14+
ret i32 0
15+
}
16+
17+
attributes #0 = { "target-cpu"="generic-rv32" "target-features"="+32bit,+e" }
18+
19+
!llvm.module.flags = !{!0}
20+
21+
!0 = !{i32 1, !"target-abi", !"ilp32e"}

0 commit comments

Comments
 (0)