<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">To add on to what Danny and Krzysztof have said, this proposal doesn’t make a lot of sense to me.  You want this intrinsic to inhibit (some) optimizations, but you simultaneously want it not to have a performance impact.  Those are contradictory goals.  Worse, the proposal doesn’t specify what optimizations should/should not be allowed for this intrinsic, since apparently you want at least some applied.  Is CSE allowed? DCE?  PRE?<div class=""><br class=""></div><div class="">—Owen<br class=""><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Nov 2, 2015, at 3:57 PM, Richard Diamond via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="">Hey all,<br class=""></div><div class=""><br class=""></div><div class="">I'd like to propose a new intrinsic for use in preventing optimizations from deleting IR due to constant propagation, dead code elimination, etc.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><font size="4" class=""># Background/</font><span style="font-size:large" class="">Motivation</span></div><div class=""><br class=""></div><div class="">In Rust we have a crate called `test` which provides a function, `black_box`, which is designed to be a no-op function that prevents constprop, die, etc from interfering with tests/benchmarks but otherwise doesn't negatively affect resulting machine code quality. `test` currently implements this function by using inline asm, which marks a pointer to the argument as used by the assembly. </div><div class=""><br class=""></div><div class="">At the IR level, this creates an alloca, stores it's argument to it, calls the no-op inline asm with the alloca pointer, and then returns a load of the alloca. Obviously, `mem2reg` would normally optimize this sort of pattern away, however the deliberate use of the no-op asm prevents other desirable optimizations (such as the aforementioned `mem2reg` pass) a little too well.</div><div class=""><br class=""></div><div class="">Existing and upcoming virtual ISA targets also don't have this luxury (PNaCl/JS and WebAssembly, respectively). For these kind of targets, Rust's `test` currently forbids inlining of `black_box`, which crudely achieves the same effect. This is undesirable for any target because of the associated call overhead.</div><div class=""><br class=""></div><div class="">The IR for `test::black_box::<i32>` is currently (it gets inlined, as desired, so I've omitted the function signature):</div><div class=""><br class=""></div><div class="">````llvm</div><div class="">  %dummy.i = alloca i32, align 4<br class=""></div><div class="">  %2 = bitcast i32* %dummy.i to i8*<br class=""></div><div class=""><div class="">  call void @llvm.lifetime.start(i64 4, i8* %2) #1</div><div class="">; Here, the value operand was the original argument to `test::black_box::<i32>`</div><div class="">  store i32 2, i32* %dummy.i, align 4</div><div class="">  call void asm "", "r,~{dirflag},~{fpsr},~{flags}"(i32* %dummy.i) #1, !srcloc !0</div><div class="">  %3 = load i32, i32* %dummy.i, align 4</div><div class="">  call void @llvm.lifetime.end(i64 4, i8* %2) #1</div></div><div class="">````</div><div class=""><br class=""></div><div class="">This could be better.</div><div class=""><br class=""></div><div class=""><font size="4" class=""># Solution</font></div><div class=""><br class=""></div><div class="">Add a new intrinsic, called `llvm.blackbox`, which accepts a value of any type and returns a value of the same type. As with many other intrinsics, this intrinsic shall remain unknown to all optimizations, before and during codegen. Specifically, this intrinsic should prevent all optimizations which operate by assuming properties of the value passed to the intrinsic. Once the last optimization pass (of any kind) is finished, all calls can be RAUW its argument.</div><div class=""><br class=""></div><div class="">Table-gen def:</div><div class=""><br class=""></div><div class="">```tablegen</div><div class="">def int_blackbox : Intrinsic<[llvm_any_ty], [LLVMMatchType<0>]>;<br class=""></div><div class="">```</div><div class=""><br class=""></div><div class="">Thus, using the previous example, `%3` would become:</div><div class="">```llvm</div><div class="">  %3 = call i32 @llvm.blackbox.i32(i32 2)</div><div class=""><br class=""></div><div class="">```</div><div class=""><br class=""></div><div class=""># </div><div class=""><br class=""></div><div class="">Thoughts and suggestions welcome.</div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Richard Diamond</div></div>
_______________________________________________<br class="">LLVM Developers mailing list<br class=""><a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev<br class=""></div></blockquote></div><br class=""></div></div></body></html>