diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index 7ee8a0dc2a0db..c03ba9487a6dc 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -1513,12 +1513,18 @@ static void initFeatureMaps(const ASTContext &Ctx, static bool checkAVXParamFeature(DiagnosticsEngine &Diag, SourceLocation CallLoc, + const FunctionDecl &Callee, const llvm::StringMap &CallerMap, const llvm::StringMap &CalleeMap, QualType Ty, StringRef Feature, bool IsArgument) { bool CallerHasFeat = CallerMap.lookup(Feature); bool CalleeHasFeat = CalleeMap.lookup(Feature); + // No explicit features and the function is internal, be permissive. + if (!CallerHasFeat && !CalleeHasFeat && + (!Callee.isExternallyVisible() || Callee.hasAttr())) + return false; + if (!CallerHasFeat && !CalleeHasFeat) return Diag.Report(CallLoc, diag::warn_avx_calling_convention) << IsArgument << Ty << Feature; @@ -1534,18 +1540,18 @@ static bool checkAVXParamFeature(DiagnosticsEngine &Diag, } static bool checkAVXParam(DiagnosticsEngine &Diag, ASTContext &Ctx, - SourceLocation CallLoc, + SourceLocation CallLoc, const FunctionDecl &Callee, const llvm::StringMap &CallerMap, const llvm::StringMap &CalleeMap, QualType Ty, bool IsArgument) { uint64_t Size = Ctx.getTypeSize(Ty); if (Size > 256) - return checkAVXParamFeature(Diag, CallLoc, CallerMap, CalleeMap, Ty, + return checkAVXParamFeature(Diag, CallLoc, Callee, CallerMap, CalleeMap, Ty, "avx512f", IsArgument); if (Size > 128) - return checkAVXParamFeature(Diag, CallLoc, CallerMap, CalleeMap, Ty, "avx", - IsArgument); + return checkAVXParamFeature(Diag, CallLoc, Callee, CallerMap, CalleeMap, Ty, + "avx", IsArgument); return false; } @@ -1582,8 +1588,8 @@ void X86_64TargetCodeGenInfo::checkFunctionCallABI(CodeGenModule &CGM, if (ArgIndex < Callee->getNumParams()) Ty = Callee->getParamDecl(ArgIndex)->getType(); - if (checkAVXParam(CGM.getDiags(), CGM.getContext(), CallLoc, CallerMap, - CalleeMap, Ty, /*IsArgument*/ true)) + if (checkAVXParam(CGM.getDiags(), CGM.getContext(), CallLoc, *Callee, + CallerMap, CalleeMap, Ty, /*IsArgument*/ true)) return; } ++ArgIndex; @@ -1594,7 +1600,7 @@ void X86_64TargetCodeGenInfo::checkFunctionCallABI(CodeGenModule &CGM, if (Callee->getReturnType()->isVectorType() && CGM.getContext().getTypeSize(Callee->getReturnType()) > 128) { initFeatureMaps(CGM.getContext(), CallerMap, Caller, CalleeMap, Callee); - checkAVXParam(CGM.getDiags(), CGM.getContext(), CallLoc, CallerMap, + checkAVXParam(CGM.getDiags(), CGM.getContext(), CallLoc, *Callee, CallerMap, CalleeMap, Callee->getReturnType(), /*IsArgument*/ false); } diff --git a/clang/test/CodeGen/target-builtin-error-3.c b/clang/test/CodeGen/target-builtin-error-3.c index 3de76e253d9b1..056dc940f7a93 100644 --- a/clang/test/CodeGen/target-builtin-error-3.c +++ b/clang/test/CodeGen/target-builtin-error-3.c @@ -24,6 +24,26 @@ static inline half16 __attribute__((__overloadable__)) convert_half( float16 a ) } void avx_test( uint16_t *destData, float16 argbF) { - // expected-warning@+1{{AVX vector argument of type 'float16' (vector of 16 'float' values) without 'avx512f' enabled changes the ABI}} ((half16U *)destData)[0] = convert_half(argbF); } + +half16 test( float16 a ) { + half16 r; + r.lo = convert_half(a.lo); + return r; +} +void avx_test2( uint16_t *destData, float16 argbF) +{ + // expected-warning@+1{{AVX vector argument of type 'float16' (vector of 16 'float' values) without 'avx512f' enabled changes the ABI}} + ((half16U *)destData)[0] = test(argbF); +} + +__attribute__((always_inline)) half16 test2( float16 a ) { + half16 r; + r.lo = convert_half(a.lo); + return r; +} +void avx_test3( uint16_t *destData, float16 argbF) +{ + ((half16U *)destData)[0] = test2(argbF); +}