From 999b9b939d1d6e6d57b08a6686b47f22f38a343a Mon Sep 17 00:00:00 2001 From: AdityaK Date: Fri, 26 Jul 2024 14:22:40 -0700 Subject: [PATCH] Use TargetABI to assign default-target features in getDefaultSubtargetFeatures It is currently not possible to provide any reasonable target-features for compiler generated functions (See: #69780) Having a target-abi will provide a way to add minimal requirements for target-features like `+d` for RISC-V. --- llvm/include/llvm/IR/Function.h | 2 ++ llvm/include/llvm/IR/Module.h | 3 +++ llvm/lib/IR/Function.cpp | 20 ++++++++++++++++++++ llvm/lib/IR/Module.cpp | 8 ++++++++ llvm/lib/Transforms/IPO/CrossDSOCFI.cpp | 12 +++++++++--- llvm/test/Transforms/CrossDSOCFI/riscv.ll | 19 +++++++++++++++++++ 6 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Transforms/CrossDSOCFI/riscv.ll diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index e7afcbd31420c1..77ffde6a95a9c6 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -190,6 +190,8 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node { static Function *Create(FunctionType *Ty, LinkageTypes Linkage, const Twine &N, Module &M); + StringRef getDefaultTargetFeatures(const StringRef TargetABI); + /// Creates a function with some attributes recorded in llvm.module.flags /// and the LLVMContext applied. /// diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h index 12b50fc506516e..3368184af4103e 100644 --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -1065,6 +1065,9 @@ class LLVM_ABI Module { /// 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/Function.cpp b/llvm/lib/IR/Function.cpp index 9c5dd5aeb92e97..18ab34aa7ef952 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -48,6 +48,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ModRef.h" +#include "llvm/TargetParser/Triple.h" #include #include #include @@ -387,6 +388,25 @@ Function *Function::Create(FunctionType *Ty, LinkageTypes Linkage, return Create(Ty, Linkage, M.getDataLayout().getProgramAddressSpace(), N, &M); } +StringRef Function::getDefaultTargetFeatures(const StringRef TargetABI) { + Triple T(getParent()->getTargetTriple()); + StringRef attr = ""; + if (T.isRISCV64()) { + if (TargetABI.contains("lp64d")) + attr = "+d"; + else if (TargetABI.contains("lp64f")) + attr = "+f"; + else if (TargetABI.contains("lp64q")) + attr = "+q"; + } else if (T.isRISCV32() && TargetABI.contains("ilp32f")) { + attr = "+f"; + } else if (T.isARM() || T.isThumb()) { + attr = "+thumb-mode"; + } + + return attr; +} + Function *Function::createWithDefaultAttr(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N, diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index c7b9f8744d8d35..3ee53528a825e5 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(getModuleFlag("target-abi"))) + TargetABI = TargetABIMD->getString(); + return TargetABI; +} diff --git a/llvm/lib/Transforms/IPO/CrossDSOCFI.cpp b/llvm/lib/Transforms/IPO/CrossDSOCFI.cpp index 2d884078940cc0..92b9ece7484a6f 100644 --- a/llvm/lib/Transforms/IPO/CrossDSOCFI.cpp +++ b/llvm/lib/Transforms/IPO/CrossDSOCFI.cpp @@ -86,14 +86,20 @@ void CrossDSOCFI::buildCFICheck(Module &M) { "__cfi_check", Type::getVoidTy(Ctx), Type::getInt64Ty(Ctx), PointerType::getUnqual(Ctx), PointerType::getUnqual(Ctx)); Function *F = cast(C.getCallee()); + std::string DefaultFeatures = + F->getContext().getDefaultTargetFeatures().str(); // Take over the existing function. The frontend emits a weak stub so that the // linker knows about the symbol; this pass replaces the function body. F->deleteBody(); F->setAlignment(Align(4096)); - Triple T(M.getTargetTriple()); - if (T.isARM() || T.isThumb()) - F->addFnAttr("target-features", "+thumb-mode"); + // Set existing target-features. + if (!DefaultFeatures.empty()) + F->addFnAttr("target-features", DefaultFeatures); + + DefaultFeatures = F->getDefaultTargetFeatures(M.getTargetABIFromMD()); + if (!DefaultFeatures.empty()) + F->addFnAttr("target-features", DefaultFeatures); auto args = F->arg_begin(); Value &CallSiteTypeId = *(args++); diff --git a/llvm/test/Transforms/CrossDSOCFI/riscv.ll b/llvm/test/Transforms/CrossDSOCFI/riscv.ll new file mode 100644 index 00000000000000..9427ff5e8cf0e1 --- /dev/null +++ b/llvm/test/Transforms/CrossDSOCFI/riscv.ll @@ -0,0 +1,19 @@ +; RUN: opt -S -passes=cross-dso-cfi < %s | FileCheck --check-prefix=RISCV64 %s + +target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128" +target triple = "riscv64-unknown-linux-gnu" + +define signext i8 @f() !type !0 !type !1 { +entry: + ret i8 1 +} + +!llvm.module.flags = !{!2, !3} + +!0 = !{i64 0, !"_ZTSFcvE"} +!1 = !{i64 0, i64 111} +!2 = !{i32 4, !"Cross-DSO CFI", i32 1} +!3 = !{i32 1, !"target-abi", !"lp64d"} + +; RISCV64: define void @__cfi_check({{.*}} #[[A:.*]] align 4096 +; RISCV64: attributes #[[A]] = { {{.*}}"target-features"="+d"