Vendor import of clang release_70 branch r348686:
https://llvm.org/svn/llvm-project/cfe/branches/release_70@348686
This commit is contained in:
parent
6ae2bfad8a
commit
52c5eb8567
@ -1216,7 +1216,6 @@ public:
|
||||
value_type SingleElement;
|
||||
|
||||
public:
|
||||
iterator() = default;
|
||||
explicit iterator(pointer Pos, value_type Single = nullptr)
|
||||
: IteratorBase(Pos), SingleElement(Single) {}
|
||||
|
||||
|
@ -1953,6 +1953,39 @@ def Target : InheritableAttr {
|
||||
return parse(getFeaturesStr());
|
||||
}
|
||||
|
||||
StringRef getArchitecture() const {
|
||||
StringRef Features = getFeaturesStr();
|
||||
if (Features == "default") return {};
|
||||
|
||||
SmallVector<StringRef, 1> AttrFeatures;
|
||||
Features.split(AttrFeatures, ",");
|
||||
|
||||
for (auto &Feature : AttrFeatures) {
|
||||
Feature = Feature.trim();
|
||||
if (Feature.startswith("arch="))
|
||||
return Feature.drop_front(sizeof("arch=") - 1);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// Gets the list of features as simple string-refs with no +/- or 'no-'.
|
||||
// Only adds the items to 'Out' that are additions.
|
||||
void getAddedFeatures(llvm::SmallVectorImpl<StringRef> &Out) const {
|
||||
StringRef Features = getFeaturesStr();
|
||||
if (Features == "default") return;
|
||||
|
||||
SmallVector<StringRef, 1> AttrFeatures;
|
||||
Features.split(AttrFeatures, ",");
|
||||
|
||||
for (auto &Feature : AttrFeatures) {
|
||||
Feature = Feature.trim();
|
||||
|
||||
if (!Feature.startswith("no-") && !Feature.startswith("arch=") &&
|
||||
!Feature.startswith("fpmath=") && !Feature.startswith("tune="))
|
||||
Out.push_back(Feature);
|
||||
}
|
||||
}
|
||||
|
||||
template<class Compare>
|
||||
ParsedTargetAttr parse(Compare cmp) const {
|
||||
ParsedTargetAttr Attrs = parse();
|
||||
|
@ -9734,6 +9734,10 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
|
||||
return true;
|
||||
|
||||
if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
// Multiversioned functions always have to be emitted, because they are used
|
||||
// by the resolver.
|
||||
if (FD->isMultiVersion())
|
||||
return true;
|
||||
// Forward declarations aren't required.
|
||||
if (!FD->doesThisDeclarationHaveABody())
|
||||
return FD->doesDeclarationForceExternallyVisibleDefinition();
|
||||
|
@ -725,7 +725,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
|
||||
// If we're paying attention to global visibility, apply
|
||||
// -finline-visibility-hidden if this is an inline method.
|
||||
if (useInlineVisibilityHidden(D))
|
||||
LV.mergeVisibility(HiddenVisibility, true);
|
||||
LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -915,7 +915,7 @@ LinkageComputer::getLVForClassMember(const NamedDecl *D,
|
||||
// Note that we do this before merging information about
|
||||
// the class visibility.
|
||||
if (!LV.isVisibilityExplicit() && useInlineVisibilityHidden(D))
|
||||
LV.mergeVisibility(HiddenVisibility, true);
|
||||
LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false);
|
||||
}
|
||||
|
||||
// If this class member has an explicit visibility attribute, the only
|
||||
@ -1262,7 +1262,27 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D,
|
||||
!isTemplateInstantiation(FD->getTemplateSpecializationKind()))
|
||||
return LinkageInfo::none();
|
||||
|
||||
// If a function is hidden by -fvisibility-inlines-hidden option and
|
||||
// is not explicitly attributed as a hidden function,
|
||||
// we should not make static local variables in the function hidden.
|
||||
LV = getLVForDecl(FD, computation);
|
||||
if (isa<VarDecl>(D) && useInlineVisibilityHidden(FD) &&
|
||||
!LV.isVisibilityExplicit()) {
|
||||
assert(cast<VarDecl>(D)->isStaticLocal());
|
||||
// If this was an implicitly hidden inline method, check again for
|
||||
// explicit visibility on the parent class, and use that for static locals
|
||||
// if present.
|
||||
if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
|
||||
LV = getLVForDecl(MD->getParent(), computation);
|
||||
if (!LV.isVisibilityExplicit()) {
|
||||
Visibility globalVisibility =
|
||||
computation.isValueVisibility()
|
||||
? Context.getLangOpts().getValueVisibilityMode()
|
||||
: Context.getLangOpts().getTypeVisibilityMode();
|
||||
return LinkageInfo(VisibleNoLinkage, globalVisibility,
|
||||
/*visibilityExplicit=*/false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isExternallyVisible(LV.getLinkage()))
|
||||
return LinkageInfo::none();
|
||||
|
@ -2359,91 +2359,53 @@ void CodeGenFunction::EmitSanitizerStatReport(llvm::SanitizerStatKind SSK) {
|
||||
CGM.getSanStats().create(IRB, SSK);
|
||||
}
|
||||
|
||||
llvm::Value *CodeGenFunction::FormResolverCondition(
|
||||
const TargetMultiVersionResolverOption &RO) {
|
||||
llvm::Value *TrueCondition = nullptr;
|
||||
if (!RO.ParsedAttribute.Architecture.empty())
|
||||
TrueCondition = EmitX86CpuIs(RO.ParsedAttribute.Architecture);
|
||||
llvm::Value *
|
||||
CodeGenFunction::FormResolverCondition(const MultiVersionResolverOption &RO) {
|
||||
llvm::Value *Condition = nullptr;
|
||||
|
||||
if (!RO.ParsedAttribute.Features.empty()) {
|
||||
SmallVector<StringRef, 8> FeatureList;
|
||||
llvm::for_each(RO.ParsedAttribute.Features,
|
||||
[&FeatureList](const std::string &Feature) {
|
||||
FeatureList.push_back(StringRef{Feature}.substr(1));
|
||||
});
|
||||
llvm::Value *FeatureCmp = EmitX86CpuSupports(FeatureList);
|
||||
TrueCondition = TrueCondition ? Builder.CreateAnd(TrueCondition, FeatureCmp)
|
||||
: FeatureCmp;
|
||||
if (!RO.Conditions.Architecture.empty())
|
||||
Condition = EmitX86CpuIs(RO.Conditions.Architecture);
|
||||
|
||||
if (!RO.Conditions.Features.empty()) {
|
||||
llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Conditions.Features);
|
||||
Condition =
|
||||
Condition ? Builder.CreateAnd(Condition, FeatureCond) : FeatureCond;
|
||||
}
|
||||
return TrueCondition;
|
||||
return Condition;
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitTargetMultiVersionResolver(
|
||||
llvm::Function *Resolver,
|
||||
ArrayRef<TargetMultiVersionResolverOption> Options) {
|
||||
void CodeGenFunction::EmitMultiVersionResolver(
|
||||
llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
|
||||
assert((getContext().getTargetInfo().getTriple().getArch() ==
|
||||
llvm::Triple::x86 ||
|
||||
getContext().getTargetInfo().getTriple().getArch() ==
|
||||
llvm::Triple::x86_64) &&
|
||||
"Only implemented for x86 targets");
|
||||
|
||||
// Main function's basic block.
|
||||
llvm::BasicBlock *CurBlock = createBasicBlock("entry", Resolver);
|
||||
Builder.SetInsertPoint(CurBlock);
|
||||
EmitX86CpuInit();
|
||||
|
||||
llvm::Function *DefaultFunc = nullptr;
|
||||
for (const TargetMultiVersionResolverOption &RO : Options) {
|
||||
Builder.SetInsertPoint(CurBlock);
|
||||
llvm::Value *TrueCondition = FormResolverCondition(RO);
|
||||
|
||||
if (!TrueCondition) {
|
||||
DefaultFunc = RO.Function;
|
||||
} else {
|
||||
llvm::BasicBlock *RetBlock = createBasicBlock("ro_ret", Resolver);
|
||||
llvm::IRBuilder<> RetBuilder(RetBlock);
|
||||
RetBuilder.CreateRet(RO.Function);
|
||||
CurBlock = createBasicBlock("ro_else", Resolver);
|
||||
Builder.CreateCondBr(TrueCondition, RetBlock, CurBlock);
|
||||
}
|
||||
}
|
||||
|
||||
assert(DefaultFunc && "No default version?");
|
||||
// Emit return from the 'else-ist' block.
|
||||
Builder.SetInsertPoint(CurBlock);
|
||||
Builder.CreateRet(DefaultFunc);
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitCPUDispatchMultiVersionResolver(
|
||||
llvm::Function *Resolver,
|
||||
ArrayRef<CPUDispatchMultiVersionResolverOption> Options) {
|
||||
assert((getContext().getTargetInfo().getTriple().getArch() ==
|
||||
llvm::Triple::x86 ||
|
||||
getContext().getTargetInfo().getTriple().getArch() ==
|
||||
llvm::Triple::x86_64) &&
|
||||
"Only implemented for x86 targets");
|
||||
|
||||
// Main function's basic block.
|
||||
llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver);
|
||||
Builder.SetInsertPoint(CurBlock);
|
||||
EmitX86CpuInit();
|
||||
|
||||
for (const CPUDispatchMultiVersionResolverOption &RO : Options) {
|
||||
for (const MultiVersionResolverOption &RO : Options) {
|
||||
Builder.SetInsertPoint(CurBlock);
|
||||
llvm::Value *Condition = FormResolverCondition(RO);
|
||||
|
||||
// "generic" case should catch-all.
|
||||
if (RO.FeatureMask == 0) {
|
||||
// The 'default' or 'generic' case.
|
||||
if (!Condition) {
|
||||
assert(&RO == Options.end() - 1 &&
|
||||
"Default or Generic case must be last");
|
||||
Builder.CreateRet(RO.Function);
|
||||
return;
|
||||
}
|
||||
|
||||
llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver);
|
||||
llvm::IRBuilder<> RetBuilder(RetBlock);
|
||||
RetBuilder.CreateRet(RO.Function);
|
||||
CurBlock = createBasicBlock("resolver_else", Resolver);
|
||||
llvm::Value *TrueCondition = EmitX86CpuSupports(RO.FeatureMask);
|
||||
Builder.CreateCondBr(TrueCondition, RetBlock, CurBlock);
|
||||
Builder.CreateCondBr(Condition, RetBlock, CurBlock);
|
||||
}
|
||||
|
||||
// If no generic/default, emit an unreachable.
|
||||
Builder.SetInsertPoint(CurBlock);
|
||||
llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
|
||||
TrapCall->setDoesNotReturn();
|
||||
|
@ -4247,30 +4247,26 @@ public:
|
||||
|
||||
void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK);
|
||||
|
||||
struct TargetMultiVersionResolverOption {
|
||||
struct MultiVersionResolverOption {
|
||||
llvm::Function *Function;
|
||||
TargetAttr::ParsedTargetAttr ParsedAttribute;
|
||||
unsigned Priority;
|
||||
TargetMultiVersionResolverOption(
|
||||
const TargetInfo &TargInfo, llvm::Function *F,
|
||||
const clang::TargetAttr::ParsedTargetAttr &PT)
|
||||
: Function(F), ParsedAttribute(PT), Priority(0u) {
|
||||
for (StringRef Feat : PT.Features)
|
||||
Priority = std::max(Priority,
|
||||
TargInfo.multiVersionSortPriority(Feat.substr(1)));
|
||||
struct Conds {
|
||||
StringRef Architecture;
|
||||
llvm::SmallVector<StringRef, 8> Features;
|
||||
|
||||
if (!PT.Architecture.empty())
|
||||
Priority = std::max(Priority,
|
||||
TargInfo.multiVersionSortPriority(PT.Architecture));
|
||||
}
|
||||
Conds(StringRef Arch, ArrayRef<StringRef> Feats)
|
||||
: Architecture(Arch), Features(Feats.begin(), Feats.end()) {}
|
||||
} Conditions;
|
||||
|
||||
bool operator>(const TargetMultiVersionResolverOption &Other) const {
|
||||
return Priority > Other.Priority;
|
||||
}
|
||||
MultiVersionResolverOption(llvm::Function *F, StringRef Arch,
|
||||
ArrayRef<StringRef> Feats)
|
||||
: Function(F), Conditions(Arch, Feats) {}
|
||||
};
|
||||
void EmitTargetMultiVersionResolver(
|
||||
llvm::Function *Resolver,
|
||||
ArrayRef<TargetMultiVersionResolverOption> Options);
|
||||
|
||||
// Emits the body of a multiversion function's resolver. Assumes that the
|
||||
// options are already sorted in the proper order, with the 'default' option
|
||||
// last (if it exists).
|
||||
void EmitMultiVersionResolver(llvm::Function *Resolver,
|
||||
ArrayRef<MultiVersionResolverOption> Options);
|
||||
|
||||
struct CPUDispatchMultiVersionResolverOption {
|
||||
llvm::Function *Function;
|
||||
@ -4306,8 +4302,7 @@ private:
|
||||
llvm::Value *EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs);
|
||||
llvm::Value *EmitX86CpuSupports(uint32_t Mask);
|
||||
llvm::Value *EmitX86CpuInit();
|
||||
llvm::Value *
|
||||
FormResolverCondition(const TargetMultiVersionResolverOption &RO);
|
||||
llvm::Value *FormResolverCondition(const MultiVersionResolverOption &RO);
|
||||
};
|
||||
|
||||
inline DominatingLLVMValue::saved_type
|
||||
|
@ -2399,9 +2399,22 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) {
|
||||
static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old,
|
||||
llvm::Function *NewFn);
|
||||
|
||||
static unsigned
|
||||
TargetMVPriority(const TargetInfo &TI,
|
||||
const CodeGenFunction::MultiVersionResolverOption &RO) {
|
||||
unsigned Priority = 0;
|
||||
for (StringRef Feat : RO.Conditions.Features)
|
||||
Priority = std::max(Priority, TI.multiVersionSortPriority(Feat));
|
||||
|
||||
if (!RO.Conditions.Architecture.empty())
|
||||
Priority = std::max(
|
||||
Priority, TI.multiVersionSortPriority(RO.Conditions.Architecture));
|
||||
return Priority;
|
||||
}
|
||||
|
||||
void CodeGenModule::emitMultiVersionFunctions() {
|
||||
for (GlobalDecl GD : MultiVersionFuncs) {
|
||||
SmallVector<CodeGenFunction::TargetMultiVersionResolverOption, 10> Options;
|
||||
SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options;
|
||||
const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
|
||||
getContext().forEachMultiversionedFunctionVersion(
|
||||
FD, [this, &GD, &Options](const FunctionDecl *CurFD) {
|
||||
@ -2422,8 +2435,13 @@ void CodeGenModule::emitMultiVersionFunctions() {
|
||||
}
|
||||
assert(Func && "This should have just been created");
|
||||
}
|
||||
Options.emplace_back(getTarget(), cast<llvm::Function>(Func),
|
||||
CurFD->getAttr<TargetAttr>()->parse());
|
||||
|
||||
const auto *TA = CurFD->getAttr<TargetAttr>();
|
||||
llvm::SmallVector<StringRef, 8> Feats;
|
||||
TA->getAddedFeatures(Feats);
|
||||
|
||||
Options.emplace_back(cast<llvm::Function>(Func),
|
||||
TA->getArchitecture(), Feats);
|
||||
});
|
||||
|
||||
llvm::Function *ResolverFunc = cast<llvm::Function>(
|
||||
@ -2431,11 +2449,16 @@ void CodeGenModule::emitMultiVersionFunctions() {
|
||||
if (supportsCOMDAT())
|
||||
ResolverFunc->setComdat(
|
||||
getModule().getOrInsertComdat(ResolverFunc->getName()));
|
||||
|
||||
const TargetInfo &TI = getTarget();
|
||||
std::stable_sort(
|
||||
Options.begin(), Options.end(),
|
||||
std::greater<CodeGenFunction::TargetMultiVersionResolverOption>());
|
||||
[&TI](const CodeGenFunction::MultiVersionResolverOption &LHS,
|
||||
const CodeGenFunction::MultiVersionResolverOption &RHS) {
|
||||
return TargetMVPriority(TI, LHS) > TargetMVPriority(TI, RHS);
|
||||
});
|
||||
CodeGenFunction CGF(*this);
|
||||
CGF.EmitTargetMultiVersionResolver(ResolverFunc, Options);
|
||||
CGF.EmitMultiVersionResolver(ResolverFunc, Options);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2444,7 +2467,13 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
|
||||
assert(FD && "Not a FunctionDecl?");
|
||||
const auto *DD = FD->getAttr<CPUDispatchAttr>();
|
||||
assert(DD && "Not a cpu_dispatch Function?");
|
||||
llvm::Type *DeclTy = getTypes().ConvertTypeForMem(FD->getType());
|
||||
QualType CanonTy = Context.getCanonicalType(FD->getType());
|
||||
llvm::Type *DeclTy = getTypes().ConvertFunctionType(CanonTy, FD);
|
||||
|
||||
if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
|
||||
const CGFunctionInfo &FInfo = getTypes().arrangeCXXMethodDeclaration(CXXFD);
|
||||
DeclTy = getTypes().GetFunctionType(FInfo);
|
||||
}
|
||||
|
||||
StringRef ResolverName = getMangledName(GD);
|
||||
llvm::Type *ResolverType = llvm::FunctionType::get(
|
||||
@ -2455,15 +2484,14 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
|
||||
GetOrCreateLLVMFunction(ResolverName, ResolverType, GlobalDecl{},
|
||||
/*ForVTable=*/false));
|
||||
|
||||
SmallVector<CodeGenFunction::CPUDispatchMultiVersionResolverOption, 10>
|
||||
Options;
|
||||
SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options;
|
||||
const TargetInfo &Target = getTarget();
|
||||
for (const IdentifierInfo *II : DD->cpus()) {
|
||||
// Get the name of the target function so we can look it up/create it.
|
||||
std::string MangledName = getMangledNameImpl(*this, GD, FD, true) +
|
||||
getCPUSpecificMangling(*this, II->getName());
|
||||
llvm::Constant *Func = GetOrCreateLLVMFunction(
|
||||
MangledName, DeclTy, GD, /*ForVTable=*/false, /*DontDefer=*/false,
|
||||
MangledName, DeclTy, GD, /*ForVTable=*/false, /*DontDefer=*/true,
|
||||
/*IsThunk=*/false, llvm::AttributeList(), ForDefinition);
|
||||
llvm::SmallVector<StringRef, 32> Features;
|
||||
Target.getCPUSpecificCPUDispatchFeatures(II->getName(), Features);
|
||||
@ -2473,15 +2501,34 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
|
||||
Features.begin(), Features.end(), [&Target](StringRef Feat) {
|
||||
return !Target.validateCpuSupports(Feat);
|
||||
}), Features.end());
|
||||
Options.emplace_back(cast<llvm::Function>(Func),
|
||||
CodeGenFunction::GetX86CpuSupportsMask(Features));
|
||||
Options.emplace_back(cast<llvm::Function>(Func), StringRef{}, Features);
|
||||
}
|
||||
|
||||
llvm::sort(
|
||||
Options.begin(), Options.end(),
|
||||
std::greater<CodeGenFunction::CPUDispatchMultiVersionResolverOption>());
|
||||
[](const CodeGenFunction::MultiVersionResolverOption &LHS,
|
||||
const CodeGenFunction::MultiVersionResolverOption &RHS) {
|
||||
return CodeGenFunction::GetX86CpuSupportsMask(LHS.Conditions.Features) >
|
||||
CodeGenFunction::GetX86CpuSupportsMask(RHS.Conditions.Features);
|
||||
});
|
||||
|
||||
// If the list contains multiple 'default' versions, such as when it contains
|
||||
// 'pentium' and 'generic', don't emit the call to the generic one (since we
|
||||
// always run on at least a 'pentium'). We do this by deleting the 'least
|
||||
// advanced' (read, lowest mangling letter).
|
||||
while (Options.size() > 1 &&
|
||||
CodeGenFunction::GetX86CpuSupportsMask(
|
||||
(Options.end() - 2)->Conditions.Features) == 0) {
|
||||
StringRef LHSName = (Options.end() - 2)->Function->getName();
|
||||
StringRef RHSName = (Options.end() - 1)->Function->getName();
|
||||
if (LHSName.compare(RHSName) < 0)
|
||||
Options.erase(Options.end() - 2);
|
||||
else
|
||||
Options.erase(Options.end() - 1);
|
||||
}
|
||||
|
||||
CodeGenFunction CGF(*this);
|
||||
CGF.EmitCPUDispatchMultiVersionResolver(ResolverFunc, Options);
|
||||
CGF.EmitMultiVersionResolver(ResolverFunc, Options);
|
||||
}
|
||||
|
||||
/// If an ifunc for the specified mangled name is not in the module, create and
|
||||
|
@ -138,7 +138,7 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
|
||||
if (Args.hasArg(options::OPT_pie))
|
||||
CmdArgs.push_back("-pie");
|
||||
if (Args.hasArg(options::OPT_nopie))
|
||||
if (Args.hasArg(options::OPT_nopie) || Args.hasArg(options::OPT_pg))
|
||||
CmdArgs.push_back("-nopie");
|
||||
|
||||
if (Output.isFilename()) {
|
||||
|
@ -475,9 +475,6 @@ static Optional<NonLoc> tryRearrange(ProgramStateRef State,
|
||||
SingleTy = ResultTy;
|
||||
if (LSym->getType() != SingleTy)
|
||||
return None;
|
||||
// Substracting unsigned integers is a nightmare.
|
||||
if (!SingleTy->isSignedIntegerOrEnumerationType())
|
||||
return None;
|
||||
} else {
|
||||
// Don't rearrange other operations.
|
||||
return None;
|
||||
@ -485,6 +482,10 @@ static Optional<NonLoc> tryRearrange(ProgramStateRef State,
|
||||
|
||||
assert(!SingleTy.isNull() && "We should have figured out the type by now!");
|
||||
|
||||
// Rearrange signed symbolic expressions only
|
||||
if (!SingleTy->isSignedIntegerOrEnumerationType())
|
||||
return None;
|
||||
|
||||
SymbolRef RSym = Rhs.getAsSymbol();
|
||||
if (!RSym || RSym->getType() != SingleTy)
|
||||
return None;
|
||||
|
@ -934,3 +934,17 @@ int mixed_integer_types(int x, int y) {
|
||||
short a = x - 1U;
|
||||
return a - y;
|
||||
}
|
||||
|
||||
unsigned gu();
|
||||
unsigned fu() {
|
||||
unsigned x = gu();
|
||||
// Assert that no overflows occur in this test file.
|
||||
// Assuming that concrete integers are also within that range.
|
||||
assert(x <= ((unsigned)UINT_MAX / 4));
|
||||
return x;
|
||||
}
|
||||
|
||||
void unsigned_concrete_int_no_crash() {
|
||||
unsigned x = fu() + 1U, y = fu() + 1U;
|
||||
clang_analyzer_dump(x == y); // expected-warning {{((conj_$2{unsigned int}) + 1U) == ((conj_$7{unsigned int}) + 1U)}}
|
||||
}
|
||||
|
@ -96,6 +96,15 @@ void HasGeneric(void);
|
||||
// CHECK: ret void ()* @HasGeneric.A
|
||||
// CHECK-NOT: call void @llvm.trap
|
||||
|
||||
__attribute__((cpu_dispatch(atom, generic, pentium)))
|
||||
int GenericAndPentium(int i, double d);
|
||||
// CHECK: define i32 (i32, double)* @GenericAndPentium.resolver()
|
||||
// CHECK: call void @__cpu_indicator_init
|
||||
// CHECK: ret i32 (i32, double)* @GenericAndPentium.O
|
||||
// CHECK: ret i32 (i32, double)* @GenericAndPentium.B
|
||||
// CHECK-NOT: ret i32 (i32, double)* @GenericAndPentium.A
|
||||
// CHECK-NOT: call void @llvm.trap
|
||||
|
||||
// CHECK: attributes #[[S]] = {{.*}}"target-features"="+avx,+cmov,+f16c,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"
|
||||
// CHECK: attributes #[[K]] = {{.*}}"target-features"="+adx,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+cmov,+f16c,+fma,+lzcnt,+mmx,+movbe,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"
|
||||
// CHECK: attributes #[[O]] = {{.*}}"target-features"="+cmov,+mmx,+movbe,+sse,+sse2,+sse3,+ssse3,+x87"
|
||||
|
18
test/CodeGenCXX/attr-cpuspecific.cpp
Normal file
18
test/CodeGenCXX/attr-cpuspecific.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,LINUX
|
||||
|
||||
struct S {
|
||||
__attribute__((cpu_specific(atom)))
|
||||
void Func(){}
|
||||
__attribute__((cpu_dispatch(ivybridge,atom)))
|
||||
void Func(){}
|
||||
};
|
||||
|
||||
void foo() {
|
||||
S s;
|
||||
s.Func();
|
||||
}
|
||||
|
||||
// LINUX: define linkonce_odr void @_ZN1S4FuncEv.O
|
||||
// LINUX: define void (%struct.S*)* @_ZN1S4FuncEv.resolver
|
||||
// LINUX: ret void (%struct.S*)* @_ZN1S4FuncEv.S
|
||||
// LINUX: ret void (%struct.S*)* @_ZN1S4FuncEv.O
|
@ -72,6 +72,15 @@ int templ_use() {
|
||||
// CHECK: @_ZN5templIiE3fooEi.ifunc = ifunc i32 (%struct.templ*, i32), i32 (%struct.templ*, i32)* ()* @_ZN5templIiE3fooEi.resolver
|
||||
// CHECK: @_ZN5templIdE3fooEi.ifunc = ifunc i32 (%struct.templ.0*, i32), i32 (%struct.templ.0*, i32)* ()* @_ZN5templIdE3fooEi.resolver
|
||||
|
||||
// CHECK: define linkonce_odr i32 @_ZN1S3fooEi.sse4.2(%struct.S* %this, i32)
|
||||
// CHECK: ret i32 0
|
||||
|
||||
// CHECK: define linkonce_odr i32 @_ZN1S3fooEi.arch_ivybridge(%struct.S* %this, i32)
|
||||
// CHECK: ret i32 1
|
||||
|
||||
// CHECK: define linkonce_odr i32 @_ZN1S3fooEi(%struct.S* %this, i32)
|
||||
// CHECK: ret i32 2
|
||||
|
||||
// CHECK: define i32 @_Z3barv()
|
||||
// CHECK: %s = alloca %struct.S, align 1
|
||||
// CHECK: %s2 = alloca %struct.S, align 1
|
||||
@ -123,23 +132,14 @@ int templ_use() {
|
||||
// CHECK: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.sse4.2
|
||||
// CHECK: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi
|
||||
|
||||
// CHECK: define linkonce_odr i32 @_ZN1S3fooEi.sse4.2(%struct.S* %this, i32)
|
||||
// CHECK: ret i32 0
|
||||
|
||||
// CHECK: declare i32 @_ZN1S3fooEi.arch_sandybridge(%struct.S*, i32)
|
||||
|
||||
// CHECK: define linkonce_odr i32 @_ZN1S3fooEi.arch_ivybridge(%struct.S* %this, i32)
|
||||
// CHECK: ret i32 1
|
||||
|
||||
// CHECK: define linkonce_odr i32 @_ZN1S3fooEi(%struct.S* %this, i32)
|
||||
// CHECK: ret i32 2
|
||||
|
||||
// CHECK: define linkonce_odr i32 @_ZN5templIiE3fooEi.sse4.2
|
||||
// CHECK: declare i32 @_ZN5templIiE3fooEi.arch_sandybridge
|
||||
// CHECK: define linkonce_odr i32 @_ZN5templIiE3fooEi.arch_ivybridge
|
||||
// CHECK: define linkonce_odr i32 @_ZN5templIiE3fooEi
|
||||
|
||||
// CHECK: define linkonce_odr i32 @_ZN5templIdE3fooEi.sse4.2
|
||||
// CHECK: declare i32 @_ZN5templIdE3fooEi.arch_sandybridge
|
||||
// CHECK: define linkonce_odr i32 @_ZN5templIdE3fooEi.arch_ivybridge
|
||||
// CHECK: define linkonce_odr i32 @_ZN5templIdE3fooEi
|
||||
//
|
||||
// CHECK: declare i32 @_ZN1S3fooEi.arch_sandybridge(%struct.S*, i32)
|
||||
// CHECK: declare i32 @_ZN5templIiE3fooEi.arch_sandybridge
|
||||
// CHECK: declare i32 @_ZN5templIdE3fooEi.arch_sandybridge
|
||||
|
111
test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp
Normal file
111
test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck -check-prefixes=CHECK-NO-VIH %s
|
||||
// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility hidden -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s --check-prefix=CHECK-VIS-HIDDEN
|
||||
// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility protected -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s --check-prefix=CHECK-VIS-PROTECTED
|
||||
|
||||
// When a function is hidden due to -fvisibility-inlines-hidden option, static local variables of the function should not be hidden by the option.
|
||||
|
||||
// CHECK-DAG: @_ZZ4funcvE3var = internal global i32 0
|
||||
// CHECK-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
|
||||
// CHECK-DAG: @_ZZ12default_funcvE3var = internal global i32 0
|
||||
// CHECK-DAG: @_ZZ11inline_funcvE3var = linkonce_odr global i32 0, comdat
|
||||
// CHECK-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
|
||||
// CHECK-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
|
||||
// CHECK-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
|
||||
// CHECK-DAG: define i32 @_Z4funcv()
|
||||
// CHECK-DAG: define hidden i32 @_Z11hidden_funcv()
|
||||
// CHECK-DAG: define i32 @_Z12default_funcv()
|
||||
// CHECK-DAG: define linkonce_odr hidden i32 @_Z11inline_funcv()
|
||||
// CHECK-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
|
||||
// CHECK-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
|
||||
// CHECK-DAG: define linkonce_odr hidden i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
|
||||
// CHECK-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
|
||||
|
||||
// CHECK-NO-VIH-DAG: @_ZZ4funcvE3var = internal global i32 0
|
||||
// CHECK-NO-VIH-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
|
||||
// CHECK-NO-VIH-DAG: @_ZZ12default_funcvE3var = internal global i32 0
|
||||
// CHECK-NO-VIH-DAG: @_ZZ11inline_funcvE3var = linkonce_odr global i32 0, comdat
|
||||
// CHECK-NO-VIH-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
|
||||
// CHECK-NO-VIH-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
|
||||
// CHECK-NO-VIH-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
|
||||
// CHECK-NO-VIH-DAG: define i32 @_Z4funcv()
|
||||
// CHECK-NO-VIH-DAG: define hidden i32 @_Z11hidden_funcv()
|
||||
// CHECK-NO-VIH-DAG: define i32 @_Z12default_funcv()
|
||||
// CHECK-NO-VIH-DAG: define linkonce_odr i32 @_Z11inline_funcv()
|
||||
// CHECK-NO-VIH-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
|
||||
// CHECK-NO-VIH-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
|
||||
// CHECK-NO-VIH-DAG: define linkonce_odr i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
|
||||
// CHECK-NO-VIH-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
|
||||
|
||||
// CHECK-VIS-HIDDEN-DAG: @_ZZ4funcvE3var = internal global i32 0
|
||||
// CHECK-VIS-HIDDEN-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
|
||||
// CHECK-VIS-HIDDEN-DAG: @_ZZ12default_funcvE3var = internal global i32 0
|
||||
// CHECK-VIS-HIDDEN-DAG: @_ZZ11inline_funcvE3var = linkonce_odr hidden global i32 0, comdat
|
||||
// CHECK-VIS-HIDDEN-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
|
||||
// CHECK-VIS-HIDDEN-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
|
||||
// CHECK-VIS-HIDDEN-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
|
||||
// CHECK-VIS-HIDDEN-DAG: define hidden i32 @_Z4funcv()
|
||||
// CHECK-VIS-HIDDEN-DAG: define hidden i32 @_Z11hidden_funcv()
|
||||
// CHECK-VIS-HIDDEN-DAG: define i32 @_Z12default_funcv()
|
||||
// CHECK-VIS-HIDDEN-DAG: define linkonce_odr hidden i32 @_Z11inline_funcv()
|
||||
// CHECK-VIS-HIDDEN-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
|
||||
// CHECK-VIS-HIDDEN-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
|
||||
// CHECK-VIS-HIDDEN-DAG: define linkonce_odr hidden i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
|
||||
// CHECK-VIS-HIDDEN-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
|
||||
|
||||
// CHECK-VIS-PROTECTED-DAG: @_ZZ4funcvE3var = internal global i32 0
|
||||
// CHECK-VIS-PROTECTED-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
|
||||
// CHECK-VIS-PROTECTED-DAG: @_ZZ12default_funcvE3var = internal global i32 0
|
||||
// CHECK-VIS-PROTECTED-DAG: @_ZZ11inline_funcvE3var = linkonce_odr protected global i32 0, comdat
|
||||
// CHECK-VIS-PROTECTED-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
|
||||
// CHECK-VIS-PROTECTED-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
|
||||
// CHECK-VIS-PROTECTED-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
|
||||
// CHECK-VIS-PROTECTED-DAG: define protected i32 @_Z4funcv()
|
||||
// CHECK-VIS-PROTECTED-DAG: define hidden i32 @_Z11hidden_funcv()
|
||||
// CHECK-VIS-PROTECTED-DAG: define i32 @_Z12default_funcv()
|
||||
// CHECK-VIS-PROTECTED-DAG: define linkonce_odr hidden i32 @_Z11inline_funcv()
|
||||
// CHECK-VIS-PROTECTED-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
|
||||
// CHECK-VIS-PROTECTED-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
|
||||
// CHECK-VIS-PROTECTED-DAG: define linkonce_odr hidden i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
|
||||
// CHECK-VIS-PROTECTED-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
|
||||
|
||||
int func(void) {
|
||||
static int var = 0;
|
||||
return var++;
|
||||
}
|
||||
inline int inline_func(void) {
|
||||
static int var = 0;
|
||||
return var++;
|
||||
}
|
||||
int __attribute__((visibility("hidden"))) hidden_func(void) {
|
||||
static int var = 0;
|
||||
return var++;
|
||||
}
|
||||
inline int __attribute__((visibility("hidden"))) inline_hidden_func(void) {
|
||||
static int var = 0;
|
||||
return var++;
|
||||
}
|
||||
int __attribute__((visibility("default"))) default_func(void) {
|
||||
static int var = 0;
|
||||
return var++;
|
||||
}
|
||||
inline int __attribute__((visibility("default"))) inline_default_func(void) {
|
||||
static int var = 0;
|
||||
return var++;
|
||||
}
|
||||
struct __attribute__((visibility("default"))) ExportedClass {
|
||||
int inl_method() {
|
||||
static int var = 0;
|
||||
return var++;
|
||||
}
|
||||
int ext_method();
|
||||
};
|
||||
int ExportedClass::ext_method() { return inl_method(); }
|
||||
void bar(void) {
|
||||
func();
|
||||
inline_func();
|
||||
hidden_func();
|
||||
inline_hidden_func();
|
||||
default_func();
|
||||
inline_default_func();
|
||||
}
|
@ -12,7 +12,7 @@
|
||||
// RUN: %clang -no-canonical-prefixes -target i686-pc-openbsd -pg -pthread %s -### 2>&1 \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-PG %s
|
||||
// CHECK-PG: clang{{.*}}" "-cc1" "-triple" "i686-pc-openbsd"
|
||||
// CHECK-PG: ld{{.*}}" "-e" "__start" "--eh-frame-hdr" "-Bdynamic" "-dynamic-linker" "{{.*}}ld.so" "-o" "a.out" "{{.*}}gcrt0.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-lgcc" "-lpthread_p" "-lc_p" "-lgcc" "{{.*}}crtend.o"
|
||||
// CHECK-PG: ld{{.*}}" "-e" "__start" "--eh-frame-hdr" "-Bdynamic" "-dynamic-linker" "{{.*}}ld.so" "-nopie" "-o" "a.out" "{{.*}}gcrt0.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-lgcc" "-lpthread_p" "-lc_p" "-lgcc" "{{.*}}crtend.o"
|
||||
|
||||
// Check CPU type for MIPS64
|
||||
// RUN: %clang -target mips64-unknown-openbsd -### -c %s 2>&1 \
|
||||
|
Loading…
x
Reference in New Issue
Block a user