<div dir="ltr"><div class="markdown-here-wrapper" style=""><p style="margin:0px 0px 1.2em!important">Hey all,</p>
<p style="margin:0px 0px 1.2em!important">I apologize for my delay with my reply to you all (two tests last week, with three more coming this week).</p>
<p style="margin:0px 0px 1.2em!important">I appreciate all of your inputs. Based on the discussion, I’ve refined the scope and purpose of <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)">llvm.blackbox</code>, at least as it pertains to Rust’s desired use case. Previously, I left the intrinsic only vaguely specified, and based on the resulting comments, I’ve arrived at a more well defined intrinsic.</p>
<p style="margin:0px 0px 1.2em!important">Specifically:</p>
<ul style="margin:1.2em 0px;padding-left:2em">
<li style="margin:0.5em 0px">Calls to the intrinsic must not be removed;</li>
<li style="margin:0.5em 0px">Calls may be duplicated;</li>
<li style="margin:0.5em 0px">No assumptions about the return value may be made from its argument (including pointer arguments, meaning the returned pointer is a may alias for all queries);</li>
<li style="margin:0.5em 0px">It must be assumed that every byte of the pointer element type of the argument will be read (if the argument is a pointer); and</li>
<li style="margin:0.5em 0px">These rules must be maintained all the way to machine code emission, at which point the first rule must be violated.</li>
</ul>
<p style="margin:0px 0px 1.2em!important">All other optimizations are fair game.</p>
<p style="margin:0px 0px 1.2em!important">The above is a bit involved to be sure, and seeing how this intrinsic isn’t critical, I’m fine with leaving it at the worse case (ie read/write mem + other side effects) for now.</p>
<h1 id="why-" style="margin:1.3em 0px 1em;padding:0px;font-weight:bold;font-size:1.6em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(221,221,221)">Why?</h1>
<p style="margin:0px 0px 1.2em!important">Alex summed it up best: “[..] it’s about <em>simulating the existence</em> of a “perfectly efficient” external world.” This intrinsic would serve as an aid for benchmarking, ensuring benchmark code is still relevant after optimizations are performed on it, and is an attempt to create a dedicated escape hatch to be used in place of the alternatives I’ve listed below. </p>
<h1 id="alternatives" style="margin:1.3em 0px 1em;padding:0px;font-weight:bold;font-size:1.6em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(221,221,221)">Alternatives</h1>
<p style="margin:0px 0px 1.2em!important">In no particular order:</p>
<ul style="margin:1.2em 0px;padding-left:2em">
<li style="margin:0.5em 0px">Volatile stores</li>
</ul>
<p style="margin:0px 0px 1.2em!important">Not ideal for benchmarking (isn’t guaranteed to cache), nonetheless I made an attempt to measure the effects on Rustc’s set of benchmarks. However, I found an issue with <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)">rustc</code> which blocks attempts to measure the effect: <a href="https://github.com/rust-lang/rust/issues/29663">https://github.com/rust-lang/rust/issues/29663</a>.</p>
<ul style="margin:1.2em 0px;padding-left:2em">
<li style="margin:0.5em 0px">Inline asm which “uses” a pointer to the value</li>
</ul>
<p style="margin:0px 0px 1.2em!important">Rust’s current solution. Needs stack space.</p>
<ul style="margin:1.2em 0px;padding-left:2em">
<li style="margin:0.5em 0px">Inline asm which returns the value</li>
</ul>
<p style="margin:0px 0px 1.2em!important">Won’t work for any type which is bigger than a register; at least not without creating a <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)">rustc</code> intrinsic anyway to make the asm operate piecewise on the register native component types of the type if need be. And how is <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)">rustc</code> to know exactly which are the register sized or smaller types? <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)">rustc</code> mostly leaves such knowledge to LLVM.</p>
<p style="margin:0px 0px 1.2em!important">Good idea, but the needed logistics would make it ugly.</p>
<ul style="margin:1.2em 0px;padding-left:2em">
<li style="margin:0.5em 0px">Mark <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)">test::black_box</code> as <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)">noinline</code></li>
</ul>
<p style="margin:0px 0px 1.2em!important">Also not ideal because of the mandatory function call overhead.</p>
<ul style="margin:1.2em 0px;padding-left:2em">
<li style="margin:0.5em 0px">External function</li>
</ul>
<p style="margin:0px 0px 1.2em!important">Impossible for Rust; generics are monomorphised into the crate in which it is used (ie the resulting function in IR won’t ever be external to the module using it), thus making this an impossible solution for Rust. Also, Rust doesn’t allow function overloading, so C++ style explicit specialization is also out. Also suffers from the same aforementioned call overhead.</p>
<p style="margin:0px 0px 1.2em!important">Again, comments are welcome.<br>Richard Diamond</p>
<div title="MDH:SGV5IGFsbCw8ZGl2Pjxicj48L2Rpdj48ZGl2PkkgYXBvbG9naXplIGZvciBteSBkZWxheSB3aXRo
IG15IHJlcGx5IHRvIHlvdSBhbGwgKHR3byB0ZXN0cyBsYXN0IHdlZWssIHdpdGggdGhyZWUgbW9y
ZSBjb21pbmcgdGhpcyB3ZWVrKS48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PkkgYXBwcmVjaWF0
ZSBhbGwgb2YgeW91ciBpbnB1dHMuIEJhc2VkIG9uIHRoZSBkaXNjdXNzaW9uLCBJJ3ZlIHJlZmlu
ZWQgdGhlIHNjb3BlIGFuZCBwdXJwb3NlIG9mIGBsbHZtLmJsYWNrYm94YCwgYXQgbGVhc3QgYXMg
aXQgcGVydGFpbnMgdG8gUnVzdCdzIGRlc2lyZWQgdXNlIGNhc2UuIFByZXZpb3VzbHksIEkgbGVm
dCB0aGUgaW50cmluc2ljIG9ubHkgdmFndWVseSBzcGVjaWZpZWQsIGFuZCBiYXNlZCBvbiB0aGUg
cmVzdWx0aW5nIGNvbW1lbnRzLCBJJ3ZlIGFycml2ZWQgYXQgYSBtb3JlIHdlbGwgZGVmaW5lZCBp
bnRyaW5zaWMuPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5TcGVjaWZpY2FsbHk6PC9kaXY+PGRp
dj48YnI+PC9kaXY+PGRpdj4qIENhbGxzIHRvIHRoZSBpbnRyaW5zaWMgbXVzdCBub3QgYmUgcmVt
b3ZlZDs8L2Rpdj48ZGl2PiogQ2FsbHMgbWF5IGJlIGR1cGxpY2F0ZWQ7PC9kaXY+PGRpdj4qIE5v
IGFzc3VtcHRpb25zIGFib3V0IHRoZSByZXR1cm4gdmFsdWUgbWF5IGJlIG1hZGUgZnJvbSBpdHMg
YXJndW1lbnQgKGluY2x1ZGluZyBwb2ludGVyIGFyZ3VtZW50cywgbWVhbmluZyB0aGUgcmV0dXJu
ZWQgcG9pbnRlciBpcyBhIG1heSBhbGlhcyBmb3IgYWxsIHF1ZXJpZXMpOzwvZGl2PjxkaXY+KiBJ
dCBtdXN0IGJlIGFzc3VtZWQgdGhhdCBldmVyeSBieXRlIG9mIHRoZSBwb2ludGVyIGVsZW1lbnQg
dHlwZSBvZiB0aGUgYXJndW1lbnQgd2lsbCBiZSByZWFkIChpZiB0aGUgYXJndW1lbnQgaXMgYSBw
b2ludGVyKTsgYW5kPC9kaXY+PGRpdj4qIFRoZXNlIHJ1bGVzIG11c3QgYmUgbWFpbnRhaW5lZCBh
bGwgdGhlIHdheSB0byBtYWNoaW5lIGNvZGUgZW1pc3Npb24sIGF0IHdoaWNoIHBvaW50IHRoZSBm
aXJzdCBydWxlIG11c3QgYmUgdmlvbGF0ZWQuPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5BbGwg
b3RoZXIgb3B0aW1pemF0aW9ucyBhcmUgZmFpciBnYW1lLjwvZGl2PjxkaXY+PGJyPjwvZGl2Pjxk
aXY+VGhlIGFib3ZlIGlzIGEgYml0IGludm9sdmVkIHRvIGJlIHN1cmUsIGFuZCBzZWVpbmcgaG93
IHRoaXMgaW50cmluc2ljIGlzbid0IGNyaXRpY2FsLCBJJ20gZmluZSB3aXRoIGxlYXZpbmcgaXQg
YXQgdGhlIHdvcnNlIGNhc2UgKGllIHJlYWQvd3JpdGUgbWVtICsgb3RoZXIgc2lkZSBlZmZlY3Rz
KSBmb3Igbm93LjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+IyBXaHk/PC9kaXY+PGRpdj48YnI+
PC9kaXY+PGRpdj5BbGV4IHN1bW1lZCBpdCB1cCBiZXN0OiAiWy4uXSZuYnNwOzxzcGFuIHN0eWxl
PSJmb250LXNpemU6MTIuOHB4Ij5pdCdzIGFib3V0ICpzaW11bGF0aW5nIHRoZSZuYnNwOzwvc3Bh
bj48c3BhbiBzdHlsZT0iZm9udC1zaXplOiAxMi44cHg7Ij5leGlzdGVuY2UqIG9mIGEgInBlcmZl
Y3RseSBlZmZpY2llbnQiIGV4dGVybmFsIHdvcmxkLiIgVGhpcyBpbnRyaW5zaWMgd291bGQgc2Vy
dmUgYXMgYW4gYWlkIGZvciBiZW5jaG1hcmtpbmcsIGVuc3VyaW5nIGJlbmNobWFyayBjb2RlIGlz
IHN0aWxsJm5ic3A7cmVsZXZhbnQmbmJzcDthZnRlciBvcHRpbWl6YXRpb25zIGFyZSBwZXJmb3Jt
ZWQgb24gaXQsIGFuZCBpcyBhbiBhdHRlbXB0IHRvIGNyZWF0ZSBhJm5ic3A7ZGVkaWNhdGVkIGVz
Y2FwZSBoYXRjaCB0byBiZSB1c2VkIGluIHBsYWNlIG9mIHRoZSBhbHRlcm5hdGl2ZXMgSSd2ZSBs
aXN0ZWQgYmVsb3cuJm5ic3A7PC9zcGFuPjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+IyBBbHRl
cm5hdGl2ZXM8L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PkluIG5vIHBhcnRpY3VsYXIgb3JkZXI6
PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj4qIFZvbGF0aWxlIHN0b3JlczwvZGl2PjxkaXY+PGJy
PjwvZGl2PjxkaXY+Tm90IGlkZWFsIGZvciBiZW5jaG1hcmtpbmcgKGlzbid0IGd1YXJhbnRlZWQg
dG8gY2FjaGUpLCBub25ldGhlbGVzcyBJIG1hZGUgYW4gYXR0ZW1wdCB0byBtZWFzdXJlIHRoZSBl
ZmZlY3RzIG9uIFJ1c3RjJ3Mgc2V0IG9mIGJlbmNobWFya3MuIEhvd2V2ZXIsIEkgZm91bmQgYW4g
aXNzdWUgd2l0aCBgcnVzdGNgIHdoaWNoIGJsb2NrcyBhdHRlbXB0cyB0byBtZWFzdXJlIHRoZSBl
ZmZlY3Q6Jm5ic3A7PGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9ydXN0L2lz
c3Vlcy8yOTY2MyIgdGFyZ2V0PSJfYmxhbmsiPmh0dHBzOi8vZ2l0aHViLmNvbS88d2JyPnJ1c3Qt
bGFuZy9ydXN0L2lzc3Vlcy8yOTY2MzwvYT4uPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj4qIElu
bGluZSBhc20gd2hpY2ggInVzZXMiIGEgcG9pbnRlciB0byB0aGUgdmFsdWU8L2Rpdj48ZGl2Pjxi
cj48L2Rpdj48ZGl2PlJ1c3QncyBjdXJyZW50IHNvbHV0aW9uLiBOZWVkcyBzdGFjayBzcGFjZS48
L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PiogSW5saW5lIGFzbSB3aGljaCByZXR1cm5zIHRoZSB2
YWx1ZTwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+V29uJ3Qgd29yayBmb3IgYW55IHR5cGUgd2hp
Y2ggaXMgYmlnZ2VyIHRoYW4gYSByZWdpc3RlcjsgYXQgbGVhc3Qgbm90IHdpdGhvdXQgY3JlYXRp
bmcgYSBgcnVzdGNgIGludHJpbnNpYyBhbnl3YXkgdG8gbWFrZSB0aGUgYXNtIG9wZXJhdGUgcGll
Y2V3aXNlIG9uIHRoZSByZWdpc3RlciBuYXRpdmUgY29tcG9uZW50IHR5cGVzIG9mIHRoZSB0eXBl
IGlmIG5lZWQgYmUuIEFuZCBob3cgaXMgYHJ1c3RjYCB0byBrbm93IGV4YWN0bHkgd2hpY2ggYXJl
IHRoZSByZWdpc3RlciBzaXplZCBvciBzbWFsbGVyIHR5cGVzPyBgcnVzdGNgIG1vc3RseSBsZWF2
ZXMgc3VjaCBrbm93bGVkZ2UgdG8gTExWTS48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2Pkdvb2Qg
aWRlYSwgYnV0IHRoZSBuZWVkZWQgbG9naXN0aWNzIHdvdWxkIG1ha2UgaXQgdWdseS48L2Rpdj48
ZGl2Pjxicj48L2Rpdj48ZGl2PiogTWFyayBgdGVzdDo6YmxhY2tfYm94YCBhcyBgbm9pbmxpbmVg
PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5BbHNvIG5vdCBpZGVhbCBiZWNhdXNlIG9mIHRoZSBt
YW5kYXRvcnkgZnVuY3Rpb24gY2FsbCBvdmVyaGVhZC48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2
PiogRXh0ZXJuYWwgZnVuY3Rpb248L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PkltcG9zc2libGUg
Zm9yIFJ1c3Q7IGdlbmVyaWNzIGFyZSBtb25vbW9ycGhpc2VkIGludG8gdGhlIGNyYXRlIGluIHdo
aWNoIGl0IGlzIHVzZWQgKGllIHRoZSByZXN1bHRpbmcgZnVuY3Rpb24gaW4gSVIgd29uJ3QgZXZl
ciBiZSBleHRlcm5hbCB0byB0aGUgbW9kdWxlIHVzaW5nIGl0KSwgdGh1cyBtYWtpbmcgdGhpcyBh
biBpbXBvc3NpYmxlIHNvbHV0aW9uIGZvciBSdXN0LiBBbHNvLCBSdXN0IGRvZXNuJ3QgYWxsb3cg
ZnVuY3Rpb24gb3ZlcmxvYWRpbmcsIHNvIEMrKyBzdHlsZSBleHBsaWNpdCBzcGVjaWFsaXphdGlv
biBpcyBhbHNvIG91dC48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PkFsc28gc3VmZmVycyBmcm9t
IHRoZSBzYW1lIGFmb3JlbWVudGlvbmVkIGNhbGwgb3ZlcmhlYWQuPC9kaXY+PGRpdj48YnI+PC9k
aXY+PGRpdj48YnI+PC9kaXY+PGRpdj5BZ2FpbiwgY29tbWVudHMgYXJlIHdlbGNvbWUuPC9kaXY+
PGRpdj5SaWNoYXJkIERpYW1vbmQ8L2Rpdj4=" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0">​</div></div></div>