Skip to content

CodeGen, IR: Add target-{cpu,features} attributes to functions created via createWithDefaultAttr(). #96721

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions clang/lib/CodeGen/CodeGenAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,9 @@ void BackendConsumer::HandleTranslationUnit(ASTContext &C) {
Ctx.setDiagnosticHandler(std::make_unique<ClangDiagnosticHandler>(
CodeGenOpts, this));

Ctx.setDefaultTargetCPU(TargetOpts.CPU);
Ctx.setDefaultTargetFeatures(llvm::join(TargetOpts.Features, ","));

Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
setupLLVMOptimizationRemarks(
Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses,
Expand Down Expand Up @@ -1205,6 +1208,9 @@ void CodeGenAction::ExecuteAction() {
Ctx.setDiagnosticHandler(
std::make_unique<ClangDiagnosticHandler>(CodeGenOpts, &Result));

Ctx.setDefaultTargetCPU(TargetOpts.CPU);
Ctx.setDefaultTargetFeatures(llvm::join(TargetOpts.Features, ","));

Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
setupLLVMOptimizationRemarks(
Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses,
Expand Down
6 changes: 3 additions & 3 deletions clang/test/CodeGen/asan-frame-pointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ int global;

// NONE: define internal void @asan.module_ctor() #[[#ATTR:]] {
// NONE: define internal void @asan.module_dtor() #[[#ATTR]] {
// NONE: attributes #[[#ATTR]] = { nounwind }
// NONE: attributes #[[#ATTR]] = { nounwind

// NONLEAF: define internal void @asan.module_ctor() #[[#ATTR:]] {
// NONLEAF: define internal void @asan.module_dtor() #[[#ATTR]] {
// NONLEAF: attributes #[[#ATTR]] = { nounwind "frame-pointer"="non-leaf" }
// NONLEAF: attributes #[[#ATTR]] = { nounwind "frame-pointer"="non-leaf"

// ALL: define internal void @asan.module_ctor() #[[#ATTR:]] {
// ALL: define internal void @asan.module_dtor() #[[#ATTR]] {
// ALL: attributes #[[#ATTR]] = { nounwind "frame-pointer"="all" }
// ALL: attributes #[[#ATTR]] = { nounwind "frame-pointer"="all"
4 changes: 2 additions & 2 deletions clang/test/CodeGen/asan-globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ void func() {
// CHECK-NEXT: call void @__asan_unregister_globals
// CHECK-NEXT: ret void

// CHECK: attributes #[[#ATTR]] = { nounwind }
// CHECK: attributes #[[#ATTR]] = { nounwind

/// If -fasynchronous-unwind-tables, set the module flag "uwtable". ctor/dtor
/// will thus get the uwtable attribute.
// RUN: %clang_cc1 -emit-llvm -fsanitize=address -funwind-tables=2 -o - %s | FileCheck %s --check-prefixes=UWTABLE
// UWTABLE: define internal void @asan.module_dtor() #[[#ATTR:]] {
// UWTABLE: attributes #[[#ATTR]] = { nounwind uwtable }
// UWTABLE: attributes #[[#ATTR]] = { nounwind uwtable
// UWTABLE: ![[#]] = !{i32 7, !"uwtable", i32 2}

// IGNORELIST-SRC: @{{.*}}extra_global{{.*}} ={{.*}} global
Expand Down
17 changes: 17 additions & 0 deletions clang/test/CodeGen/coverage-target-attr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// RUN: %clang_cc1 -emit-llvm -coverage-notes-file=test.gcno -coverage-data-file=test.gcda -triple aarch64-linux-android30 -target-cpu generic -target-feature +tagged-globals -fsanitize=hwaddress %s -o %t
// RUN: FileCheck %s < %t

// CHECK: define internal void @__llvm_gcov_writeout() unnamed_addr [[ATTR:#[0-9]+]]
// CHECK: define internal void @__llvm_gcov_reset() unnamed_addr [[ATTR]]
// CHECK: define internal void @__llvm_gcov_init() unnamed_addr [[ATTR]]
// CHECK: define internal void @hwasan.module_ctor() [[ATTR2:#[0-9]+]]
// CHECK: attributes [[ATTR]] = {{.*}} "target-cpu"="generic" "target-features"="+tagged-globals"
// CHECK: attributes [[ATTR2]] = {{.*}} "target-cpu"="generic" "target-features"="+tagged-globals"

__attribute__((weak)) int foo = 0;

__attribute__((weak)) void bar() {}

int main() {
if (foo) bar();
}
2 changes: 1 addition & 1 deletion clang/test/CodeGen/sanitize-metadata-nosanitize.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ __attribute__((no_sanitize("all"))) int test_no_sanitize_all(int *x, int *y) {
// CHECK: attributes #1 = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
// CHECK: attributes #2 = { disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
// CHECK: attributes #3 = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "no_sanitize_thread" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
// CHECK: attributes #4 = { nounwind }
// CHECK: attributes #4 = { nounwind "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
//.
// CHECK: !2 = !{!"sanmd_covered!C", !3}
// CHECK: !3 = !{i64 0}
Expand Down
6 changes: 5 additions & 1 deletion llvm/include/llvm/IR/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,14 @@ class LLVM_EXTERNAL_VISIBILITY Function : public GlobalObject,
const Twine &N, Module &M);

/// Creates a function with some attributes recorded in llvm.module.flags
/// applied.
/// and the LLVMContext applied.
///
/// Use this when synthesizing new functions that need attributes that would
/// have been set by command line options.
///
/// This function should not be called from backends or the LTO pipeline. If
/// it is called from one of those places, some default attributes will not be
/// applied to the function.
static Function *createWithDefaultAttr(FunctionType *Ty, LinkageTypes Linkage,
unsigned AddrSpace,
const Twine &N = "",
Expand Down
16 changes: 16 additions & 0 deletions llvm/include/llvm/IR/LLVMContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,22 @@ class LLVMContext {
[[deprecated("Always returns false")]]
bool supportsTypedPointers() const;

/// Get or set the current "default" target CPU (target-cpu function
/// attribute). The intent is that compiler frontends will set this to a value
/// that reflects the attribute that a function would get "by default" without
/// any specific function attributes, and compiler passes will attach the
/// attribute to newly created functions that are not associated with a
/// particular function, such as global initializers.
/// Function::createWithDefaultAttr() will create functions with this
/// attribute. This function should only be called by passes that run at
/// compile time and not by the backend or LTO passes.
StringRef getDefaultTargetCPU();
void setDefaultTargetCPU(StringRef CPU);

/// Similar to {get,set}DefaultTargetCPU() but for default target-features.
StringRef getDefaultTargetFeatures();
void setDefaultTargetFeatures(StringRef Features);

private:
// Module needs access to the add/removeModule methods.
friend class Module;
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/IR/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,12 @@ Function *Function::createWithDefaultAttr(FunctionType *Ty,
}
if (M->getModuleFlag("function_return_thunk_extern"))
B.addAttribute(Attribute::FnRetThunkExtern);
StringRef DefaultCPU = F->getContext().getDefaultTargetCPU();
if (!DefaultCPU.empty())
B.addAttribute("target-cpu", DefaultCPU);
StringRef DefaultFeatures = F->getContext().getDefaultTargetFeatures();
if (!DefaultFeatures.empty())
B.addAttribute("target-features", DefaultFeatures);
F->addFnAttrs(B);
return F;
}
Expand Down
16 changes: 16 additions & 0 deletions llvm/lib/IR/LLVMContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,3 +390,19 @@ void LLVMContext::setOpaquePointers(bool Enable) const {
bool LLVMContext::supportsTypedPointers() const {
return false;
}

StringRef LLVMContext::getDefaultTargetCPU() {
return pImpl->DefaultTargetCPU;
}

void LLVMContext::setDefaultTargetCPU(StringRef CPU) {
pImpl->DefaultTargetCPU = CPU;
}

StringRef LLVMContext::getDefaultTargetFeatures() {
return pImpl->DefaultTargetFeatures;
}

void LLVMContext::setDefaultTargetFeatures(StringRef Features) {
pImpl->DefaultTargetFeatures = Features;
}
3 changes: 3 additions & 0 deletions llvm/lib/IR/LLVMContextImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1723,6 +1723,9 @@ class LLVMContextImpl {
}

void deleteTrailingDbgRecords(BasicBlock *B) { TrailingDbgRecords.erase(B); }

std::string DefaultTargetCPU;
std::string DefaultTargetFeatures;
};

} // end namespace llvm
Expand Down
Loading