mirror of
https://github.com/intel/llvm.git
synced 2026-02-02 10:08:59 +08:00
Ensure Target Features always_inline error happens in C++ cases.
A handful of C++ cases as reported in PR42352 didn't actually give an error when always_inlining with a different target feature list. This resulted in broken IR. llvm-svn: 364109
This commit is contained in:
@@ -3791,6 +3791,16 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
|
||||
llvm::FunctionType *IRFuncTy = getTypes().GetFunctionType(CallInfo);
|
||||
|
||||
const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl();
|
||||
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
|
||||
// We can only guarantee that a function is called from the correct
|
||||
// context/function based on the appropriate target attributes,
|
||||
// so only check in the case where we have both always_inline and target
|
||||
// since otherwise we could be making a conditional call after a check for
|
||||
// the proper cpu features (and it won't cause code generation issues due to
|
||||
// function based code generation).
|
||||
if (TargetDecl->hasAttr<AlwaysInlineAttr>() &&
|
||||
TargetDecl->hasAttr<TargetAttr>())
|
||||
checkTargetFeatures(Loc, FD);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (!(CallInfo.isVariadic() && CallInfo.getArgStruct())) {
|
||||
|
||||
@@ -4697,17 +4697,6 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee
|
||||
const Decl *TargetDecl =
|
||||
OrigCallee.getAbstractInfo().getCalleeDecl().getDecl();
|
||||
|
||||
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
|
||||
// We can only guarantee that a function is called from the correct
|
||||
// context/function based on the appropriate target attributes,
|
||||
// so only check in the case where we have both always_inline and target
|
||||
// since otherwise we could be making a conditional call after a check for
|
||||
// the proper cpu features (and it won't cause code generation issues due to
|
||||
// function based code generation).
|
||||
if (TargetDecl->hasAttr<AlwaysInlineAttr>() &&
|
||||
TargetDecl->hasAttr<TargetAttr>())
|
||||
checkTargetFeatures(E, FD);
|
||||
|
||||
CalleeType = getContext().getCanonicalType(CalleeType);
|
||||
|
||||
auto PointeeType = cast<PointerType>(CalleeType)->getPointeeType();
|
||||
|
||||
@@ -2179,6 +2179,13 @@ static bool hasRequiredFeatures(const SmallVectorImpl<StringRef> &ReqFeatures,
|
||||
// called function.
|
||||
void CodeGenFunction::checkTargetFeatures(const CallExpr *E,
|
||||
const FunctionDecl *TargetDecl) {
|
||||
return checkTargetFeatures(E->getBeginLoc(), TargetDecl);
|
||||
}
|
||||
|
||||
// Emits an error if we don't have a valid set of target features for the
|
||||
// called function.
|
||||
void CodeGenFunction::checkTargetFeatures(SourceLocation Loc,
|
||||
const FunctionDecl *TargetDecl) {
|
||||
// Early exit if this is an indirect call.
|
||||
if (!TargetDecl)
|
||||
return;
|
||||
@@ -2203,7 +2210,7 @@ void CodeGenFunction::checkTargetFeatures(const CallExpr *E,
|
||||
return;
|
||||
StringRef(FeatureList).split(ReqFeatures, ',');
|
||||
if (!hasRequiredFeatures(ReqFeatures, CGM, FD, MissingFeature))
|
||||
CGM.getDiags().Report(E->getBeginLoc(), diag::err_builtin_needs_feature)
|
||||
CGM.getDiags().Report(Loc, diag::err_builtin_needs_feature)
|
||||
<< TargetDecl->getDeclName()
|
||||
<< CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID);
|
||||
|
||||
@@ -2229,7 +2236,7 @@ void CodeGenFunction::checkTargetFeatures(const CallExpr *E,
|
||||
ReqFeatures.push_back(F.getKey());
|
||||
}
|
||||
if (!hasRequiredFeatures(ReqFeatures, CGM, FD, MissingFeature))
|
||||
CGM.getDiags().Report(E->getBeginLoc(), diag::err_function_needs_feature)
|
||||
CGM.getDiags().Report(Loc, diag::err_function_needs_feature)
|
||||
<< FD->getDeclName() << TargetDecl->getDeclName() << MissingFeature;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3605,6 +3605,7 @@ public:
|
||||
CGCallee EmitCallee(const Expr *E);
|
||||
|
||||
void checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl);
|
||||
void checkTargetFeatures(SourceLocation Loc, const FunctionDecl *TargetDecl);
|
||||
|
||||
llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee,
|
||||
const Twine &name = "");
|
||||
|
||||
BIN
clang/test/CodeGenCXX/target-builtin-error.o
Normal file
BIN
clang/test/CodeGenCXX/target-builtin-error.o
Normal file
Binary file not shown.
17
clang/test/CodeGenCXX/target-features-error.cpp
Normal file
17
clang/test/CodeGenCXX/target-features-error.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -S -verify -o -
|
||||
|
||||
struct S {
|
||||
__attribute__((always_inline, target("avx512f")))
|
||||
void foo(){}
|
||||
__attribute__((always_inline, target("avx512f")))
|
||||
operator int(){ return 0; }
|
||||
__attribute__((always_inline, target("avx512f")))
|
||||
void operator()(){ }
|
||||
|
||||
};
|
||||
|
||||
void usage(S & s) {
|
||||
s.foo(); // expected-error {{'foo' requires target feature 'avx512f'}}
|
||||
(void)(int)s; // expected-error {{'operator int' requires target feature 'avx512f'}}
|
||||
s(); // expected-error {{'operator()' requires target feature 'avx512f'}}
|
||||
}
|
||||
Reference in New Issue
Block a user