<div>This thread is getting into a broader discussion about target specific intrincsics as user prims vs compiler generated. </div><div><br></div><div>@ben - ed is talking about stuff like a function call that's using a specific avx2 intrinsic, not the parameterized vector abstraction. LLvm shouldn't be lowering those. ... or clang has issues :/</div><div><br><div class="gmail_quote"><div>On Tue, Mar 14, 2017 at 4:33 PM Geoffrey Mainland <<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 03/14/2017 04:02 PM, Ben Gamari wrote:<br class="gmail_msg">
> Edward Kmett <<a href="mailto:ekmett@gmail.com" class="gmail_msg" target="_blank">ekmett@gmail.com</a>> writes:<br class="gmail_msg">
><br class="gmail_msg">
>> Hrmm. In C/C++ I can tell individual functions to turn on additional ISA<br class="gmail_msg">
>> feature sets with compiler-specific __attribute__((target("avx2"))) tricks.<br class="gmail_msg">
>> This avoids complains from the compiler when I call builtins that aren't<br class="gmail_msg">
>> available at my current compilation feature level. Perhaps pragmas for the<br class="gmail_msg">
>> codegen along those lines is what we'd ultimately need? Alternately, if we<br class="gmail_msg">
>> simply distinguish between what the ghc codegen produces with one set of<br class="gmail_msg">
>> options and what we're allowed to ask for explicitly with another then<br class="gmail_msg">
>> user-land tricks like I employ would remain sound.<br class="gmail_msg">
>><br class="gmail_msg">
> I'm actually not sure that simply distinguishing between the user- and<br class="gmail_msg">
> codegen-allowed ISA extensions is quite sufficient. Afterall, AFAIK LLVM<br class="gmail_msg">
> doesn't make such a distinction itself: AFAIK if you write a vector<br class="gmail_msg">
> primitive and compile for a target that doesn't have an appropriate<br class="gmail_msg">
> instruction the code-generator will lower it with software emulation.<br class="gmail_msg">
<br class="gmail_msg">
This would mean that Haskell libraries compiled with different flags<br class="gmail_msg">
would not be ABI compatible.<br class="gmail_msg">
<br class="gmail_msg">
Our original paper exposed a Multi type class that was meant to be the<br class="gmail_msg">
programmer interface to the primops. A Multi a would be the widest<br class="gmail_msg">
vector type supported on the current architecture, so code that used a<br class="gmail_msg">
Multi Double would always be guaranteed to work at the widest vector<br class="gmail_msg">
type available for Double's.<br class="gmail_msg">
<br class="gmail_msg">
The Multi approach explicitly eschewed lowering, but I would argue that<br class="gmail_msg">
if performance is the goal, then automatic lowering is not what you<br class="gmail_msg">
want. I would rather have the system pick the correct vector width for<br class="gmail_msg">
me based on the current architecture.<br class="gmail_msg">
<br class="gmail_msg">
This does nothing to solved the problem of ABI compatibility, which is<br class="gmail_msg">
one reason I didn't push to get this upstreamed.<br class="gmail_msg">
<br class="gmail_msg">
Is the Multi approach desirable? I think it would be nice to be able to<br class="gmail_msg">
at least provide such a solution even if it isn't some sort of default.<br class="gmail_msg">
Do we really want lowering of wider vector types?<br class="gmail_msg">
<br class="gmail_msg">
Geoff<br class="gmail_msg">
<br class="gmail_msg">
> However, adding a pragma to allow per-function target annotations seems<br class="gmail_msg">
> quite reasonable and easily doable. Moreover, contrary to my previous<br class="gmail_msg">
> assertion, it shouldn't require any splitting of compilation units. I<br class="gmail_msg">
> ran a quick experiment, compiling this program,<br class="gmail_msg">
><br class="gmail_msg">
> __attribute__((target("sse2"))) int hello() {<br class="gmail_msg">
> return 1;<br class="gmail_msg">
> }<br class="gmail_msg">
><br class="gmail_msg">
> With clang. It produced something like,<br class="gmail_msg">
><br class="gmail_msg">
> define i32 @hello() #0 {<br class="gmail_msg">
> ret i32 1<br class="gmail_msg">
> }<br class="gmail_msg">
><br class="gmail_msg">
> attributes #0 = { "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" ... }<br class="gmail_msg">
><br class="gmail_msg">
> So it seems LLVM is perfectly capable of expressing this; in hindsight<br class="gmail_msg">
> I'm not sure why I ever doubted this.<br class="gmail_msg">
><br class="gmail_msg">
> There are a number of details that would need to be worked out regarding<br class="gmail_msg">
> how such a pragma should behave. Does the general direction sound<br class="gmail_msg">
> reasonable? I've opened #13427 [1] to track this idea.<br class="gmail_msg">
><br class="gmail_msg">
> Cheers,<br class="gmail_msg">
><br class="gmail_msg">
> - Ben<br class="gmail_msg">
><br class="gmail_msg">
><br class="gmail_msg">
> [1] <a href="https://ghc.haskell.org/trac/ghc/ticket/13427" rel="noreferrer" class="gmail_msg" target="_blank">https://ghc.haskell.org/trac/ghc/ticket/13427</a><br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
_______________________________________________<br class="gmail_msg">
ghc-devs mailing list<br class="gmail_msg">
<a href="mailto:ghc-devs@haskell.org" class="gmail_msg" target="_blank">ghc-devs@haskell.org</a><br class="gmail_msg">
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" class="gmail_msg" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs</a><br class="gmail_msg">
</blockquote></div></div>