From ea00c2a06f5135b88c8331f35108d174d412725b Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Sat, 21 Mar 2015 06:15:15 +0000 Subject: [PATCH] Add CodeGen support for adding cpu attributes on functions based on the target-cpu, if different from the triple's cpu, and target-features as they're written that are passed down from the driver. Together with LLVM r232885 this should allow the LTO'ing of binaries that contain modules compiled with different code generation options on a subset of architectures with full backend support (x86, powerpc, aarch64). llvm-svn: 232888 --- clang/lib/CodeGen/CGCall.cpp | 21 +++++++++++++++++++++ clang/test/CodeGen/function-target-features.c | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 clang/test/CodeGen/function-target-features.c diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 3cb72bd..4b4fa7c 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -31,6 +31,7 @@ #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Intrinsics.h" #include "llvm/Transforms/Utils/Local.h" +#include using namespace clang; using namespace CodeGen; @@ -1475,6 +1476,26 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, if (!CodeGenOpts.StackRealignment) FuncAttrs.addAttribute("no-realign-stack"); + + // Add target-cpu and target-features work if they differ from the defaults. + std::string &CPU = getTarget().getTargetOpts().CPU; + if (CPU != "" && CPU != getTarget().getTriple().getArchName()) + FuncAttrs.addAttribute("target-cpu", getTarget().getTargetOpts().CPU); + + // TODO: FeaturesAsWritten gets us the features on the command line, + // for canonicalization purposes we might want to avoid putting features + // in the target-features set if we know it'll be one of the default + // features in the backend, e.g. corei7-avx and +avx. + std::vector &Features = + getTarget().getTargetOpts().FeaturesAsWritten; + if (!Features.empty()) { + std::stringstream S; + std::copy(Features.begin(), Features.end(), + std::ostream_iterator(S, ",")); + // The drop_back gets rid of the trailing space. + FuncAttrs.addAttribute("target-features", + StringRef(S.str()).drop_back(1)); + } } ClangToLLVMArgMapping IRFunctionArgs(getContext(), FI); diff --git a/clang/test/CodeGen/function-target-features.c b/clang/test/CodeGen/function-target-features.c new file mode 100644 index 0000000..5665b1f --- /dev/null +++ b/clang/test/CodeGen/function-target-features.c @@ -0,0 +1,21 @@ +// This test verifies that we produce target-cpu and target-features attributes +// on functions when they're different from the standard cpu and have written +// features. + +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-feature +avx | FileCheck %s -check-prefix=AVX-FEATURE +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-feature +avx | FileCheck %s -check-prefix=AVX-NO-CPU +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-feature +avx512f -target-feature +avx512er | FileCheck %s -check-prefix=TWO-AVX +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-cpu corei7 | FileCheck %s -check-prefix=CORE-CPU +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-cpu corei7 -target-feature +avx | FileCheck %s -check-prefix=CORE-CPU-AND-FEATURES +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-cpu x86-64 | FileCheck %s -check-prefix=X86-64-CPU-NOT +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-cpu corei7-avx -target-feature -avx | FileCheck %s -check-prefix=AVX-MINUS-FEATURE + +void foo() {} + +// AVX-FEATURE: "target-features"="+avx" +// AVX-NO-CPU-NOT: target-cpu +// TWO-AVX: "target-features"="+avx512f,+avx512er" +// CORE-CPU: "target-cpu"="corei7" +// CORE-CPU-AND-FEATURES: "target-cpu"="corei7" "target-features"="+avx" +// X86-64-CPU-NOT: "target-cpu" +// AVX-MINUS-FEATURE: "target-features"="-avx" -- 2.7.4