<div dir="ltr">This all sounds a little weird as _mm_mul_ps only requires sse. Can you give me a testcase and command line that you're using to trigger this?<div><br></div><div>Thanks!<br><div><br></div><div>-eric</div></div></div><br><div class="gmail_quote"><div dir="ltr">On Fri, Nov 13, 2015 at 8:28 PM Bruno Cardoso Lopes <<a href="mailto:bruno.cardoso@gmail.com">bruno.cardoso@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Eric,<br>
<br>
This is very nice!<br>
<br>
After the addition of this feature, LNT started crashing on x86_64h:<br>
<br>
FAIL: SingleSource/UnitTests/Vector/SSE/sse_expandfft.compile_time (3 of 2244)<br>
FAIL: SingleSource/UnitTests/Vector/SSE/sse_isamax.compile_time (4 of 2244)<br>
FAIL: SingleSource/UnitTests/Vector/SSE/sse_shift.compile_time (5 of 2244)<br>
FAIL: SingleSource/UnitTests/Vector/SSE/sse_stepfft.compile_time (6 of 2244)<br>
<... among other internal ones><br>
<br>
The reason is that x86_64h implies "-fsgsbase", whereas SSE intrinsics<br>
do require it. Since this isn't the case for plain x86_64, it only<br>
shows up on x86_64h, example:<br>
<br>
sse.expandfft.c:195:18: error: always_inline function '_mm_mul_ps'<br>
requires target feature 'fsgsbase', but would be inlined into function<br>
'cfft2' that is<br>
compiled without support for 'fsgsbase'<br>
V0 = _mm_mul_ps(V6,V3);<br>
<br>
We could annotate cfft2 with 'fsgsbase' in the tests, but it seems odd<br>
to me that we would need to care about any function that use x86<br>
intrinsics when compiling for x86_64h. Any thoughts on that?<br>
<br>
<br>
On Wed, Nov 11, 2015 at 4:44 PM, Eric Christopher via cfe-commits<br>
<<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br>
> Author: echristo<br>
> Date: Wed Nov 11 18:44:12 2015<br>
> New Revision: 252834<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=252834&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=252834&view=rev</a><br>
> Log:<br>
> Provide a frontend based error for always_inline functions that require<br>
> target features that the caller function doesn't provide. This matches<br>
> the existing backend failure to inline functions that don't have<br>
> matching target features - and diagnoses earlier in the case of<br>
> always_inline.<br>
><br>
> Fix up a few test cases that were, in fact, invalid if you tried<br>
> to generate code from the backend with the specified target features<br>
> and add a couple of tests to illustrate what's going on.<br>
><br>
> This should fix PR25246.<br>
><br>
> Added:<br>
> cfe/trunk/test/CodeGen/target-features-error-2.c<br>
> cfe/trunk/test/CodeGen/target-features-error.c<br>
> Modified:<br>
> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
> cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
> cfe/trunk/lib/CodeGen/CodeGenFunction.cpp<br>
> cfe/trunk/test/CodeGen/3dnow-builtins.c<br>
> cfe/trunk/test/CodeGen/avx512vl-builtins.c<br>
><br>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=252834&r1=252833&r2=252834&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=252834&r1=252833&r2=252834&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Nov 11 18:44:12 2015<br>
> @@ -431,6 +431,9 @@ def err_builtin_definition : Error<"defi<br>
> def err_arm_invalid_specialreg : Error<"invalid special register for builtin">;<br>
> def err_invalid_cpu_supports : Error<"invalid cpu feature string for builtin">;<br>
> def err_builtin_needs_feature : Error<"%0 needs target feature %1">;<br>
> +def err_function_needs_feature<br>
> + : Error<"function %0 and always_inline callee function %1 are required to "<br>
> + "have matching target features">;<br>
> def warn_builtin_unknown : Warning<"use of unknown builtin %0">,<br>
> InGroup<ImplicitFunctionDeclare>, DefaultError;<br>
> def warn_dyn_class_memaccess : Warning<<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=252834&r1=252833&r2=252834&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=252834&r1=252833&r2=252834&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Wed Nov 11 18:44:12 2015<br>
> @@ -3747,6 +3747,15 @@ RValue CodeGenFunction::EmitCall(QualTyp<br>
> assert(CalleeType->isFunctionPointerType() &&<br>
> "Call must have function pointer type!");<br>
><br>
> + if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))<br>
> + // If this isn't an always_inline function we can't guarantee that any<br>
> + // function isn't being used correctly so only check if we have the<br>
> + // attribute and a set of target attributes that might be different from<br>
> + // our default.<br>
> + if (TargetDecl->hasAttr<AlwaysInlineAttr>() &&<br>
> + TargetDecl->hasAttr<TargetAttr>())<br>
> + checkTargetFeatures(E, FD);<br>
> +<br>
> CalleeType = getContext().getCanonicalType(CalleeType);<br>
><br>
> const auto *FnType =<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=252834&r1=252833&r2=252834&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=252834&r1=252833&r2=252834&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Nov 11 18:44:12 2015<br>
> @@ -1843,7 +1843,8 @@ template void CGBuilderInserter<Preserve<br>
> llvm::BasicBlock::iterator InsertPt) const;<br>
> #undef PreserveNames<br>
><br>
> -// Returns true if we have a valid set of target features.<br>
> +// Emits an error if we don't have a valid set of target features for the<br>
> +// called function.<br>
> void CodeGenFunction::checkTargetFeatures(const CallExpr *E,<br>
> const FunctionDecl *TargetDecl) {<br>
> // Early exit if this is an indirect call.<br>
> @@ -1856,31 +1857,70 @@ void CodeGenFunction::checkTargetFeature<br>
> if (!FD)<br>
> return;<br>
><br>
> + // Grab the required features for the call. For a builtin this is listed in<br>
> + // the td file with the default cpu, for an always_inline function this is any<br>
> + // listed cpu and any listed features.<br>
> unsigned BuiltinID = TargetDecl->getBuiltinID();<br>
> - const char *FeatureList =<br>
> - CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID);<br>
> -<br>
> - if (!FeatureList || StringRef(FeatureList) == "")<br>
> - return;<br>
> -<br>
> - llvm::StringMap<bool> FeatureMap;<br>
> - CGM.getFunctionFeatureMap(FeatureMap, FD);<br>
> -<br>
> - // If we have at least one of the features in the feature list return<br>
> - // true, otherwise return false.<br>
> - SmallVector<StringRef, 1> AttrFeatures;<br>
> - StringRef(FeatureList).split(AttrFeatures, ",");<br>
> - if (!std::all_of(AttrFeatures.begin(), AttrFeatures.end(),<br>
> - [&](StringRef &Feature) {<br>
> - SmallVector<StringRef, 1> OrFeatures;<br>
> - Feature.split(OrFeatures, "|");<br>
> - return std::any_of(OrFeatures.begin(), OrFeatures.end(),<br>
> - [&](StringRef &Feature) {<br>
> - return FeatureMap[Feature];<br>
> - });<br>
> - }))<br>
> - CGM.getDiags().Report(E->getLocStart(), diag::err_builtin_needs_feature)<br>
> - << TargetDecl->getDeclName()<br>
> - << CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID);<br>
> + if (BuiltinID) {<br>
> + SmallVector<StringRef, 1> ReqFeatures;<br>
> + const char *FeatureList =<br>
> + CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID);<br>
> + // Return if the builtin doesn't have any required features.<br>
> + if (!FeatureList || StringRef(FeatureList) == "")<br>
> + return;<br>
> + StringRef(FeatureList).split(ReqFeatures, ",");<br>
> +<br>
> + // If there aren't any required features listed then go ahead and return.<br>
> + if (ReqFeatures.empty())<br>
> + return;<br>
> +<br>
> + // Now build up the set of caller features and verify that all the required<br>
> + // features are there.<br>
> + llvm::StringMap<bool> CallerFeatureMap;<br>
> + CGM.getFunctionFeatureMap(CallerFeatureMap, FD);<br>
> +<br>
> + // If we have at least one of the features in the feature list return<br>
> + // true, otherwise return false.<br>
> + if (!std::all_of(<br>
> + ReqFeatures.begin(), ReqFeatures.end(), [&](StringRef &Feature) {<br>
> + SmallVector<StringRef, 1> OrFeatures;<br>
> + Feature.split(OrFeatures, "|");<br>
> + return std::any_of(OrFeatures.begin(), OrFeatures.end(),<br>
> + [&](StringRef &Feature) {<br>
> + return CallerFeatureMap.lookup(Feature);<br>
> + });<br>
> + }))<br>
> + CGM.getDiags().Report(E->getLocStart(), diag::err_builtin_needs_feature)<br>
> + << TargetDecl->getDeclName()<br>
> + << CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID);<br>
> +<br>
> + } else if (TargetDecl->hasAttr<TargetAttr>()) {<br>
> + // Get the required features for the callee.<br>
> + SmallVector<StringRef, 1> ReqFeatures;<br>
> + llvm::StringMap<bool> CalleeFeatureMap;<br>
> + CGM.getFunctionFeatureMap(CalleeFeatureMap, TargetDecl);<br>
> + for (const auto &F : CalleeFeatureMap)<br>
> + ReqFeatures.push_back(F.getKey());<br>
> + // If there aren't any required features listed then go ahead and return.<br>
> + if (ReqFeatures.empty())<br>
> + return;<br>
> +<br>
> + // Now get the features that the caller provides.<br>
> + llvm::StringMap<bool> CallerFeatureMap;<br>
> + CGM.getFunctionFeatureMap(CallerFeatureMap, FD);<br>
> +<br>
> + // If we have at least one of the features in the feature list return<br>
> + // true, otherwise return false.<br>
> + if (!std::all_of(<br>
> + ReqFeatures.begin(), ReqFeatures.end(), [&](StringRef &Feature) {<br>
> + SmallVector<StringRef, 1> OrFeatures;<br>
> + Feature.split(OrFeatures, "|");<br>
> + return std::any_of(OrFeatures.begin(), OrFeatures.end(),<br>
> + [&](StringRef &Feature) {<br>
> + return CallerFeatureMap.lookup(Feature);<br>
> + });<br>
> + }))<br>
> + CGM.getDiags().Report(E->getLocStart(), diag::err_function_needs_feature)<br>
> + << FD->getDeclName() << TargetDecl->getDeclName();<br>
> + }<br>
> }<br>
> -<br>
><br>
> Modified: cfe/trunk/test/CodeGen/3dnow-builtins.c<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/3dnow-builtins.c?rev=252834&r1=252833&r2=252834&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/3dnow-builtins.c?rev=252834&r1=252833&r2=252834&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/CodeGen/3dnow-builtins.c (original)<br>
> +++ cfe/trunk/test/CodeGen/3dnow-builtins.c Wed Nov 11 18:44:12 2015<br>
> @@ -1,6 +1,6 @@<br>
> // REQUIRES: x86-registered-target<br>
> -// RUN: %clang_cc1 %s -triple=x86_64-unknown-unknown -target-feature +3dnow -emit-llvm -o - -Werror | FileCheck %s<br>
> -// RUN: %clang_cc1 %s -triple=x86_64-unknown-unknown -target-feature +3dnow -S -o - -Werror | FileCheck %s --check-prefix=CHECK-ASM<br>
> +// RUN: %clang_cc1 %s -triple=x86_64-unknown-unknown -target-feature +3dnowa -emit-llvm -o - -Werror | FileCheck %s<br>
> +// RUN: %clang_cc1 %s -triple=x86_64-unknown-unknown -target-feature +3dnowa -S -o - -Werror | FileCheck %s --check-prefix=CHECK-ASM<br>
><br>
> // Don't include mm_malloc.h, it's system specific.<br>
> #define __MM_MALLOC_H<br>
><br>
> Modified: cfe/trunk/test/CodeGen/avx512vl-builtins.c<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/avx512vl-builtins.c?rev=252834&r1=252833&r2=252834&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/avx512vl-builtins.c?rev=252834&r1=252833&r2=252834&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/CodeGen/avx512vl-builtins.c (original)<br>
> +++ cfe/trunk/test/CodeGen/avx512vl-builtins.c Wed Nov 11 18:44:12 2015<br>
> @@ -5,102 +5,6 @@<br>
><br>
> #include <immintrin.h><br>
><br>
> -__mmask8 test_mm256_cmpeq_epi32_mask(__m256i __a, __m256i __b) {<br>
> - // CHECK-LABEL: @test_mm256_cmpeq_epi32_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpeq.d.256<br>
> - return (__mmask8)_mm256_cmpeq_epi32_mask(__a, __b);<br>
> -}<br>
> -<br>
> -__mmask8 test_mm256_mask_cmpeq_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) {<br>
> - // CHECK-LABEL: @test_mm256_mask_cmpeq_epi32_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpeq.d.256<br>
> - return (__mmask8)_mm256_mask_cmpeq_epi32_mask(__u, __a, __b);<br>
> -}<br>
> -<br>
> -__mmask8 test_mm_cmpeq_epi32_mask(__m128i __a, __m128i __b) {<br>
> - // CHECK-LABEL: @test_mm_cmpeq_epi32_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpeq.d.128<br>
> - return (__mmask8)_mm_cmpeq_epi32_mask(__a, __b);<br>
> -}<br>
> -<br>
> -__mmask8 test_mm_mask_cmpeq_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) {<br>
> - // CHECK-LABEL: @test_mm_mask_cmpeq_epi32_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpeq.d.128<br>
> - return (__mmask8)_mm_mask_cmpeq_epi32_mask(__u, __a, __b);<br>
> -}<br>
> -<br>
> -__mmask8 test_mm256_cmpeq_epi64_mask(__m256i __a, __m256i __b) {<br>
> - // CHECK-LABEL: @test_mm256_cmpeq_epi64_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpeq.q.256<br>
> - return (__mmask8)_mm256_cmpeq_epi64_mask(__a, __b);<br>
> -}<br>
> -<br>
> -__mmask8 test_mm256_mask_cmpeq_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) {<br>
> - // CHECK-LABEL: @test_mm256_mask_cmpeq_epi64_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpeq.q.256<br>
> - return (__mmask8)_mm256_mask_cmpeq_epi64_mask(__u, __a, __b);<br>
> -}<br>
> -<br>
> -__mmask8 test_mm_cmpeq_epi64_mask(__m128i __a, __m128i __b) {<br>
> - // CHECK-LABEL: @test_mm_cmpeq_epi64_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpeq.q.128<br>
> - return (__mmask8)_mm_cmpeq_epi64_mask(__a, __b);<br>
> -}<br>
> -<br>
> -__mmask8 test_mm_mask_cmpeq_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) {<br>
> - // CHECK-LABEL: @test_mm_mask_cmpeq_epi64_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpeq.q.128<br>
> - return (__mmask8)_mm_mask_cmpeq_epi64_mask(__u, __a, __b);<br>
> -}<br>
> -<br>
> -__mmask8 test_mm256_cmpgt_epi32_mask(__m256i __a, __m256i __b) {<br>
> - // CHECK-LABEL: @test_mm256_cmpgt_epi32_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpgt.d.256<br>
> - return (__mmask8)_mm256_cmpgt_epi32_mask(__a, __b);<br>
> -}<br>
> -<br>
> -__mmask8 test_mm256_mask_cmpgt_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) {<br>
> - // CHECK-LABEL: @test_mm256_mask_cmpgt_epi32_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpgt.d.256<br>
> - return (__mmask8)_mm256_mask_cmpgt_epi32_mask(__u, __a, __b);<br>
> -}<br>
> -<br>
> -__mmask8 test_mm_cmpgt_epi32_mask(__m128i __a, __m128i __b) {<br>
> - // CHECK-LABEL: @test_mm_cmpgt_epi32_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpgt.d.128<br>
> - return (__mmask8)_mm_cmpgt_epi32_mask(__a, __b);<br>
> -}<br>
> -<br>
> -__mmask8 test_mm_mask_cmpgt_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) {<br>
> - // CHECK-LABEL: @test_mm_mask_cmpgt_epi32_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpgt.d.128<br>
> - return (__mmask8)_mm_mask_cmpgt_epi32_mask(__u, __a, __b);<br>
> -}<br>
> -<br>
> -__mmask8 test_mm256_cmpgt_epi64_mask(__m256i __a, __m256i __b) {<br>
> - // CHECK-LABEL: @test_mm256_cmpgt_epi64_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpgt.q.256<br>
> - return (__mmask8)_mm256_cmpgt_epi64_mask(__a, __b);<br>
> -}<br>
> -<br>
> -__mmask8 test_mm256_mask_cmpgt_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) {<br>
> - // CHECK-LABEL: @test_mm256_mask_cmpgt_epi64_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpgt.q.256<br>
> - return (__mmask8)_mm256_mask_cmpgt_epi64_mask(__u, __a, __b);<br>
> -}<br>
> -<br>
> -__mmask8 test_mm_cmpgt_epi64_mask(__m128i __a, __m128i __b) {<br>
> - // CHECK-LABEL: @test_mm_cmpgt_epi64_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpgt.q.128<br>
> - return (__mmask8)_mm_cmpgt_epi64_mask(__a, __b);<br>
> -}<br>
> -<br>
> -__mmask8 test_mm_mask_cmpgt_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) {<br>
> - // CHECK-LABEL: @test_mm_mask_cmpgt_epi64_mask<br>
> - // CHECK: @llvm.x86.avx512.mask.pcmpgt.q.128<br>
> - return (__mmask8)_mm_mask_cmpgt_epi64_mask(__u, __a, __b);<br>
> -}<br>
> -<br>
> __mmask8 test_mm_cmpeq_epu32_mask(__m128i __a, __m128i __b) {<br>
> // CHECK-LABEL: @test_mm_cmpeq_epu32_mask<br>
> // CHECK: @llvm.x86.avx512.mask.ucmp.d.128(<4 x i32> {{.*}}, <4 x i32> {{.*}}, i32 0, i8 -1)<br>
><br>
> Added: cfe/trunk/test/CodeGen/target-features-error-2.c<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/target-features-error-2.c?rev=252834&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/target-features-error-2.c?rev=252834&view=auto</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/CodeGen/target-features-error-2.c (added)<br>
> +++ cfe/trunk/test/CodeGen/target-features-error-2.c Wed Nov 11 18:44:12 2015<br>
> @@ -0,0 +1,7 @@<br>
> +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -S -verify -o -<br>
> +#define __MM_MALLOC_H<br>
> +#include <x86intrin.h><br>
> +<br>
> +int baz(__m256i a) {<br>
> + return _mm256_extract_epi32(a, 3); // expected-error {{function 'baz' and always_inline callee function '_mm256_extract_epi32' are required to have matching target features}}<br>
> +}<br>
><br>
> Added: cfe/trunk/test/CodeGen/target-features-error.c<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/target-features-error.c?rev=252834&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/target-features-error.c?rev=252834&view=auto</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/CodeGen/target-features-error.c (added)<br>
> +++ cfe/trunk/test/CodeGen/target-features-error.c Wed Nov 11 18:44:12 2015<br>
> @@ -0,0 +1,8 @@<br>
> +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -S -verify -o -<br>
> +int __attribute__((target("avx"), always_inline)) foo(int a) {<br>
> + return a + 4;<br>
> +}<br>
> +int bar() {<br>
> + return foo(4); // expected-error {{function 'bar' and always_inline callee function 'foo' are required to have matching target features}}<br>
> +}<br>
> +<br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
<br>
<br>
<br>
--<br>
Bruno Cardoso Lopes<br>
<a href="http://www.brunocardoso.cc" rel="noreferrer" target="_blank">http://www.brunocardoso.cc</a><br>
</blockquote></div>