aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKito Cheng <kito.cheng@sifive.com>2025-03-07 14:09:26 +0800
committerGitHub <noreply@github.com>2025-03-07 14:09:26 +0800
commit733ad3fdebf782be5afffdb8310a0ce15675086c (patch)
treed46669d7366337a7b14dcfffb180e2974068efd9
parentbedb9077c38cf01a3f9303d68599ea95677be5b7 (diff)
downloadllvm-733ad3fdebf782be5afffdb8310a0ce15675086c.zip
llvm-733ad3fdebf782be5afffdb8310a0ce15675086c.tar.gz
llvm-733ad3fdebf782be5afffdb8310a0ce15675086c.tar.bz2
[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.
-rw-r--r--llvm/include/llvm/IR/Module.h3
-rw-r--r--llvm/lib/IR/Module.cpp8
-rw-r--r--llvm/lib/LTO/LTOBackend.cpp7
-rw-r--r--llvm/test/LTO/RISCV/lit.local.cfg2
-rw-r--r--llvm/test/LTO/RISCV/riscv-ilp32e.ll21
5 files changed, 40 insertions, 1 deletions
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 2fd2d68..91ccd76 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -1067,6 +1067,9 @@ public:
/// Set the target variant version build SDK version metadata.
void setDarwinTargetVariantSDKVersion(VersionTuple Version);
+
+ /// Returns target-abi from MDString, null if target-abi is absent.
+ StringRef getTargetABIFromMD();
};
/// Given "llvm.used" or "llvm.compiler.used" as a global name, collect the
diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp
index c7b9f87..c7daaaf 100644
--- a/llvm/lib/IR/Module.cpp
+++ b/llvm/lib/IR/Module.cpp
@@ -915,3 +915,11 @@ VersionTuple Module::getDarwinTargetVariantSDKVersion() const {
void Module::setDarwinTargetVariantSDKVersion(VersionTuple Version) {
addSDKVersionMD(Version, *this, "darwin.target_variant.SDK Version");
}
+
+StringRef Module::getTargetABIFromMD() {
+ StringRef TargetABI;
+ if (auto *TargetABIMD =
+ dyn_cast_or_null<MDString>(getModuleFlag("target-abi")))
+ TargetABI = TargetABIMD->getString();
+ return TargetABI;
+}
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index b38252a..139c39a 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -221,8 +221,13 @@ createTargetMachine(const Config &Conf, const Target *TheTarget, Module &M) {
else
CodeModel = M.getCodeModel();
+ TargetOptions TargetOpts = Conf.Options;
+ if (TargetOpts.MCOptions.ABIName.empty()) {
+ TargetOpts.MCOptions.ABIName = M.getTargetABIFromMD();
+ }
+
std::unique_ptr<TargetMachine> TM(TheTarget->createTargetMachine(
- TheTriple.str(), Conf.CPU, Features.getString(), Conf.Options, RelocModel,
+ TheTriple.str(), Conf.CPU, Features.getString(), TargetOpts, RelocModel,
CodeModel, Conf.CGOptLevel));
assert(TM && "Failed to create target machine");
diff --git a/llvm/test/LTO/RISCV/lit.local.cfg b/llvm/test/LTO/RISCV/lit.local.cfg
new file mode 100644
index 0000000..a3d2298
--- /dev/null
+++ b/llvm/test/LTO/RISCV/lit.local.cfg
@@ -0,0 +1,2 @@
+if "RISCV" not in config.root.targets:
+ config.unsupported = True
diff --git a/llvm/test/LTO/RISCV/riscv-ilp32e.ll b/llvm/test/LTO/RISCV/riscv-ilp32e.ll
new file mode 100644
index 0000000..bbca58e
--- /dev/null
+++ b/llvm/test/LTO/RISCV/riscv-ilp32e.ll
@@ -0,0 +1,21 @@
+; Check that we don't crash on DataLayout incompatibility issue.
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-lto2 run -r %t.o,_start %t.o -o %t.elf
+; RUN: llvm-readobj -h %t.elf.0 | FileCheck %s --check-prefixes=CHECK
+; CHECK: Machine: EM_RISCV (0xF3)
+; CHECK: EF_RISCV_RVE (0x8)
+
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32-S32"
+target triple = "riscv32-unknown-unknown-elf"
+
+define dso_local i32 @_start() #0 {
+entry:
+ ret i32 0
+}
+
+attributes #0 = { "target-cpu"="generic-rv32" "target-features"="+32bit,+e" }
+
+!llvm.module.flags = !{!0}
+
+!0 = !{i32 1, !"target-abi", !"ilp32e"}