<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>