<div dir="ltr"><div>Hi, </div><div><br></div><div>I have some WIP that leverages @llvm.assume in some optimization passes other than InstCombine. However, it doesn't work yet because InstCombine removes @llvm.assume calls that are useful for later optimizations. For example, given</div><div><br></div><div><div>define i32 @foo(i32 %a, i32 %b) {</div><div>  %sum = add i32 %a, %b</div><div>  %1 = icmp sge i32 %sum, 0</div><div>  call void @llvm.assume(i1 %1)</div><div>  ret i32 %sum</div><div>}</div><div><br></div></div><div>"opt -instcombine" emits</div><div><br></div><div><div>define i32 @foo(i32 %a, i32 %b) {</div><div>  %sum = add i32 %a, %b</div><div>  ret i32 %sum</div><div>}</div></div><div><br></div><div>removing the @llvm.assume call so later optimizations won't know sum is non-negative any more. (Note that the opt I use here is with <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D10283&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=Mfk2qtn1LTDThVkh6-oGglNfMADXfJdty4_bhmuhMHA&m=3G44egvXZ6BzEp3YWKCZnCeqsr91Yh3D5ZJUJnb7MWQ&s=UXLLS4sYtXihXpTYBhOb1kM-HHJyT8CRoa31p-bWAtg&e=">http://reviews.llvm.org/D10283</a> patched. This patch fixes a bug in ValueTracking). </div><div><br></div><div>The reasons that InstCombine removes this assume call are: </div><div>1) SimplifyICmpInst proves %1 is true based on the assume call. </div><div>2) then, InstCombine (<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_docs_doxygen_html_InstCombineCompares-5F8cpp-5Fsource.html-23l02649&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=Mfk2qtn1LTDThVkh6-oGglNfMADXfJdty4_bhmuhMHA&m=3G44egvXZ6BzEp3YWKCZnCeqsr91Yh3D5ZJUJnb7MWQ&s=cLS0ioCv6-c9P41D_XjIfxb7JPngIPBIUM2MgV5WKrM&e=">http://llvm.org/docs/doxygen/html/InstCombineCompares_8cpp_source.html#l02649</a>) replaces all uses of %1 with true including the use in the assume call. </div><div>3) Somewhere later, llvm.assume(true) is considered trivially dead and thus removed from the IR. </div><div><br></div><div>Step 2 looks particularly problematic to me. Removing @llvm.assume essentially throws away the base of the proof so we won't be able to make the same proof any more. </div><div><br></div><div><div>How can we fix this issue? One heavy-handed approach is, instead of RAUW the icmp, we only replace the uses that are not by @llvm.assume. But I have two concerns. </div><div><br></div><div>1) what if the icmp is not directly used by an @llvm.assume? e.g., if we proved a >= 0 and that condition is used in assume(a >= 0 || b >= 0), should we keep (a >= 0) in case later passes use them? If yes, we would probably have to recursively traverse def-use chains. If no, some assumption is again lost after instcombine. </div><div><br></div><div>2) what if the kept assumes are not leveraged later at all? These assumes bump up values' refcounts and could potentially hurt optimizations. This looks like a problem for adding @llvm.assume in general. Maybe users should be aware of these trade-offs when adding __builtin_assumes in their source code. </div><div><br></div><div>Thoughts? </div><div><br></div><div>Thanks, </div><div>Jingyue</div></div></div>