<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><a name="_MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></a></p>
<p class="MsoNormal"><a name="_____replyseparator"></a><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"> David Blaikie [mailto:dblaikie@gmail.com]
<br>
<b>Sent:</b> Monday, October 29, 2018 11:41 AM<br>
<b>To:</b> Keane, Erich <erich.keane@intel.com><br>
<b>Cc:</b> Eric Christopher <echristo@gmail.com>; cfe-commits@lists.llvm.org<br>
<b>Subject:</b> Re: r344957 - Give Multiversion-inline functions linkonce linkage<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Mon, Oct 29, 2018 at 11:30 AM Keane, Erich <<a href="mailto:erich.keane@intel.com">erich.keane@intel.com</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">GCC actually doesn’t support function multiversioning in C mode, so this fix is part of our extension
 to support C with multiversioning.</span><o:p></o:p></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><br>
Ah, what's the motivation for that?<span style="color:#1F497D"><o:p></o:p></span></p>
<p class="MsoNormal"><b><i><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">[Keane, Erich] Basically, I identified no good reason to not support it.  GCC’s motivation is lost to time as far as I can tell.  This multiversioning is
 super useful in my employer’s math/intrinsic libraries (MKL uses this feature extensively), so enabling it in C seemed like a positive improvement.  We’ve made some other behavioral changes to make ‘target’ work more sanely to suppress some of the worst bugs
 (becoming MV after usage) as well as make it work better with Clang’s emit-functionality.<o:p></o:p></span></i></b></p>
<p class="MsoNormal"><br>
 <o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">  I perhaps wonder if this is part of the reason GCC only supports it in C++ mode... </span><o:p></o:p></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><br>
Yeah... could be.<br>
<br>
I mean I suppose using linkonce isn't making multiversioning any worse in C than it already is in C++ inline functions (which is where it's pretty easy to misuse, as I understand it - two files, one compiled with a CPU feature, one without, linkonce functions
 get linked together & the linker picks one - then code built without the feature calls code that uses the feature - but, I mean, that can happen even witohut multiversioning, if you compile some source files with a feature and some without) - I guess the main
 risk would be if it confuses users by making multiversioned C inline functions end up behaving too differently from non-multiversioned ones... <span style="color:#1F497D"><o:p></o:p></span></p>
<p class="MsoNormal"><b><i><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">[Keane, Erich] I suspect that multiversioning is such a sharp edged feature, that a change like this makes it a touch more sane.  Since the individual versions
 are independently mangled, you don’t have to worry about merging different versions.  The only real issue comes from merging the resolver functions if the visible list of declarations is different, but we treat that as an ODR violation.<o:p></o:p></span></i></b></p>
<p class="MsoNormal"><br>
<br>
- Dave<br>
 <o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><a name="m_-2818023329972350043__MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"> </span></a><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><a name="m_-2818023329972350043______replyseparat"></a><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">
 David Blaikie [mailto:<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>]
<br>
<b>Sent:</b> Monday, October 29, 2018 11:25 AM<br>
<b>To:</b> Keane, Erich <<a href="mailto:erich.keane@intel.com" target="_blank">erich.keane@intel.com</a>>; Eric Christopher <<a href="mailto:echristo@gmail.com" target="_blank">echristo@gmail.com</a>><br>
<b>Cc:</b> <a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<b>Subject:</b> Re: r344957 - Give Multiversion-inline functions linkonce linkage</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:12.0pt">Does this match GCC's approach here?<br>
<br>
(I ask this sort of as throwaway/conversation starter - because the linkage/behavior around multiversion functions and their inlining is full of sharp corners/risks of code moving out of the areas appropriately restricted based on the cpu features)<o:p></o:p></p>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">On Mon, Oct 22, 2018 at 2:22 PM Erich Keane via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Author: erichkeane<br>
Date: Mon Oct 22 14:20:45 2018<br>
New Revision: 344957<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=344957&view=rev" target="_blank">
http://llvm.org/viewvc/llvm-project?rev=344957&view=rev</a><br>
Log:<br>
Give Multiversion-inline functions linkonce linkage<br>
<br>
Since multiversion variant functions can be inline, in C they become<br>
available-externally linkage.  This ends up causing the variants to not<br>
be emitted, and not available to the linker.<br>
<br>
The solution is to make sure that multiversion functions are always<br>
emitted by marking them linkonce.<br>
<br>
Change-Id: I897aa37c7cbba0c1eb2c57ee881d5000a2113b75<br>
<br>
Modified:<br>
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
    cfe/trunk/test/CodeGen/attr-target-mv.c<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=344957&r1=344956&r2=344957&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=344957&r1=344956&r2=344957&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Oct 22 14:20:45 2018<br>
@@ -3669,6 +3669,10 @@ llvm::GlobalValue::LinkageTypes CodeGenM<br>
       return llvm::GlobalVariable::WeakAnyLinkage;<br>
   }<br>
<br>
+  if (const auto *FD = D->getAsFunction())<br>
+    if (FD->isMultiVersion() && Linkage == GVA_AvailableExternally)<br>
+      return llvm::GlobalVariable::LinkOnceAnyLinkage;<br>
+<br>
   // We are guaranteed to have a strong definition somewhere else,<br>
   // so we can use available_externally linkage.<br>
   if (Linkage == GVA_AvailableExternally)<br>
<br>
Modified: cfe/trunk/test/CodeGen/attr-target-mv.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/attr-target-mv.c?rev=344957&r1=344956&r2=344957&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/attr-target-mv.c?rev=344957&r1=344956&r2=344957&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/attr-target-mv.c (original)<br>
+++ cfe/trunk/test/CodeGen/attr-target-mv.c Mon Oct 22 14:20:45 2018<br>
@@ -88,19 +88,19 @@ void bar4() {<br>
<br>
 // CHECK: declare i32 @foo.arch_sandybridge()<br>
<br>
-// CHECK: define available_externally i32 @foo_inline.sse4.2()<br>
+// CHECK: define linkonce i32 @foo_inline.sse4.2()<br>
 // CHECK: ret i32 0<br>
<br>
 // CHECK: declare i32 @foo_inline.arch_sandybridge()<br>
 //<br>
-// CHECK: define available_externally i32 @foo_inline.arch_ivybridge()<br>
+// CHECK: define linkonce i32 @foo_inline.arch_ivybridge()<br>
 // CHECK: ret i32 1<br>
-// CHECK: define available_externally i32 @foo_inline()<br>
+// CHECK: define linkonce i32 @foo_inline()<br>
 // CHECK: ret i32 2<br>
<br>
-// CHECK: define available_externally void @foo_decls()<br>
-// CHECK: define available_externally void @foo_decls.sse4.2()<br>
+// CHECK: define linkonce void @foo_decls()<br>
+// CHECK: define linkonce void @foo_decls.sse4.2()<br>
<br>
-// CHECK: define available_externally void @foo_multi.avx_sse4.2()<br>
-// CHECK: define available_externally void @foo_multi.fma4_sse4.2()<br>
-// CHECK: define available_externally void @foo_multi.arch_ivybridge_fma4_sse4.2()<br>
+// CHECK: define linkonce void @foo_multi.avx_sse4.2()<br>
+// CHECK: define linkonce void @foo_multi.fma4_sse4.2()<br>
+// CHECK: define linkonce void @foo_multi.arch_ivybridge_fma4_sse4.2()<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" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><o:p></o:p></p>
</blockquote>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</body>
</html>