<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Wed, Nov 11, 2015 at 6:08 PM Akira Hatanaka <<a href="mailto:ahatanak@gmail.com">ahatanak@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>I think you are suggesting we change the inliner to produce a diagnostic (error or warning?) when the callee is marked always_inline and its function attributes are not compatible with the caller's (functionsHaveCompatibleAttributes returns false). Is that correct?</div></div><div dir="ltr"><div><br></div></div></blockquote><div><br></div><div>Yep. And I think an error is appropriate here. The programmer said that the function must always inline and it's not always being inlined.</div><div><br></div><div>I think it's a larger change because it'll require some refactoring and the ability to give reasons out of the always inline pass when faced with cost analysis.</div><div><br></div><div>-eric</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div></div><div><div class="gmail_extra"><div class="gmail_quote">On Wed, Nov 11, 2015 at 4:48 PM, Eric Christopher <span dir="ltr"><<a href="mailto:echristo@gmail.com" target="_blank">echristo@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">FWIW we should also have the backend avoid inlining and perhaps produce a diagnostic if something makes it there as well.<div><br></div><div>-eric<br><br><div class="gmail_quote"><div dir="ltr">On Wed, Nov 11, 2015 at 4:46 PM Eric Christopher via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">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>
</blockquote></div></div></div>
</blockquote></div><br></div></div></div></blockquote></div></div>