Skip to content

Commit 3617624

Browse files
author
Erich Keane
committed
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
1 parent fa52674 commit 3617624

File tree

6 files changed

+37
-13
lines changed

6 files changed

+37
-13
lines changed

clang/lib/CodeGen/CGCall.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3791,6 +3791,16 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
37913791
llvm::FunctionType *IRFuncTy = getTypes().GetFunctionType(CallInfo);
37923792

37933793
const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl();
3794+
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
3795+
// We can only guarantee that a function is called from the correct
3796+
// context/function based on the appropriate target attributes,
3797+
// so only check in the case where we have both always_inline and target
3798+
// since otherwise we could be making a conditional call after a check for
3799+
// the proper cpu features (and it won't cause code generation issues due to
3800+
// function based code generation).
3801+
if (TargetDecl->hasAttr<AlwaysInlineAttr>() &&
3802+
TargetDecl->hasAttr<TargetAttr>())
3803+
checkTargetFeatures(Loc, FD);
37943804

37953805
#ifndef NDEBUG
37963806
if (!(CallInfo.isVariadic() && CallInfo.getArgStruct())) {

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4697,17 +4697,6 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee
46974697
const Decl *TargetDecl =
46984698
OrigCallee.getAbstractInfo().getCalleeDecl().getDecl();
46994699

4700-
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
4701-
// We can only guarantee that a function is called from the correct
4702-
// context/function based on the appropriate target attributes,
4703-
// so only check in the case where we have both always_inline and target
4704-
// since otherwise we could be making a conditional call after a check for
4705-
// the proper cpu features (and it won't cause code generation issues due to
4706-
// function based code generation).
4707-
if (TargetDecl->hasAttr<AlwaysInlineAttr>() &&
4708-
TargetDecl->hasAttr<TargetAttr>())
4709-
checkTargetFeatures(E, FD);
4710-
47114700
CalleeType = getContext().getCanonicalType(CalleeType);
47124701

47134702
auto PointeeType = cast<PointerType>(CalleeType)->getPointeeType();

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2179,6 +2179,13 @@ static bool hasRequiredFeatures(const SmallVectorImpl<StringRef> &ReqFeatures,
21792179
// called function.
21802180
void CodeGenFunction::checkTargetFeatures(const CallExpr *E,
21812181
const FunctionDecl *TargetDecl) {
2182+
return checkTargetFeatures(E->getBeginLoc(), TargetDecl);
2183+
}
2184+
2185+
// Emits an error if we don't have a valid set of target features for the
2186+
// called function.
2187+
void CodeGenFunction::checkTargetFeatures(SourceLocation Loc,
2188+
const FunctionDecl *TargetDecl) {
21822189
// Early exit if this is an indirect call.
21832190
if (!TargetDecl)
21842191
return;
@@ -2203,7 +2210,7 @@ void CodeGenFunction::checkTargetFeatures(const CallExpr *E,
22032210
return;
22042211
StringRef(FeatureList).split(ReqFeatures, ',');
22052212
if (!hasRequiredFeatures(ReqFeatures, CGM, FD, MissingFeature))
2206-
CGM.getDiags().Report(E->getBeginLoc(), diag::err_builtin_needs_feature)
2213+
CGM.getDiags().Report(Loc, diag::err_builtin_needs_feature)
22072214
<< TargetDecl->getDeclName()
22082215
<< CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID);
22092216

@@ -2229,7 +2236,7 @@ void CodeGenFunction::checkTargetFeatures(const CallExpr *E,
22292236
ReqFeatures.push_back(F.getKey());
22302237
}
22312238
if (!hasRequiredFeatures(ReqFeatures, CGM, FD, MissingFeature))
2232-
CGM.getDiags().Report(E->getBeginLoc(), diag::err_function_needs_feature)
2239+
CGM.getDiags().Report(Loc, diag::err_function_needs_feature)
22332240
<< FD->getDeclName() << TargetDecl->getDeclName() << MissingFeature;
22342241
}
22352242
}

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3605,6 +3605,7 @@ class CodeGenFunction : public CodeGenTypeCache {
36053605
CGCallee EmitCallee(const Expr *E);
36063606

36073607
void checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl);
3608+
void checkTargetFeatures(SourceLocation Loc, const FunctionDecl *TargetDecl);
36083609

36093610
llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee,
36103611
const Twine &name = "");
760 Bytes
Binary file not shown.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -S -verify -o -
2+
3+
struct S {
4+
__attribute__((always_inline, target("avx512f")))
5+
void foo(){}
6+
__attribute__((always_inline, target("avx512f")))
7+
operator int(){ return 0; }
8+
__attribute__((always_inline, target("avx512f")))
9+
void operator()(){ }
10+
11+
};
12+
13+
void usage(S & s) {
14+
s.foo(); // expected-error {{'foo' requires target feature 'avx512f'}}
15+
(void)(int)s; // expected-error {{'operator int' requires target feature 'avx512f'}}
16+
s(); // expected-error {{'operator()' requires target feature 'avx512f'}}
17+
}

0 commit comments

Comments
 (0)