<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="">Hi all,<div class=""><br class=""></div><div class="">For my custom architecture, I want to relax the CFG simplification pass, and other passes replacing conditional branches.</div><div class=""><br class=""></div><div class="">I found that the replacement of conditional jumps by “select" or other instructions is often too aggressive, and this causes inefficient code for my target, because in most cases a branch would just be cheaper.</div><div class=""><br class=""></div><div class="">For example, considering the following c code:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">long</span> test (<span style="color: #ba2da2" class="">long</span> a, <span style="color: #ba2da2" class="">long</span> b)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">{</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">  <span style="color: #ba2da2" class="">int</span> neg = <span style="color: #272ad8" class="">0</span>;</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">  <span style="color: #ba2da2" class="">long</span> res;</div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">  <span style="color: #ba2da2" class="">if</span> (a < <span style="color: #272ad8" class="">0</span>) </div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">  {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">    a = -a; </div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">    neg = <span style="color: #272ad8" class="">1</span>;</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">  }</div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class="">  res = a*b;</span></div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">  <span style="color: #ba2da2" class="">if</span> (neg)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">    res = -res;</div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">  <span style="color: #ba2da2" class="">return</span> res;</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class="">}</div></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">This code can be obviously simplified in c, but please just consider it as an example to show the point.</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">The code above gets compiled like this (-Oz flag):</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Monaco; background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255);" class=""><div style="margin: 0px; line-height: normal;" class=""><div style="font-family: Monaco; font-size: 11px; margin: 0px; line-height: normal;" class="">; Function Attrs: minsize norecurse nounwind optsize readnone</div><div style="font-family: Monaco; font-size: 11px; margin: 0px; line-height: normal;" class="">define dso_local i32 @test(i32 %a, i32 %b) local_unnamed_addr #0 {</div><div style="font-family: Monaco; font-size: 11px; margin: 0px; line-height: normal;" class="">entry:</div><div style="font-family: Monaco; font-size: 11px; margin: 0px; line-height: normal;" class="">  %cmp = icmp slt i32 %a, 0</div><div style="font-family: Monaco; font-size: 11px; margin: 0px; line-height: normal;" class="">  %sub = sub nsw i32 0, %a</div><div style="font-family: Monaco; font-size: 11px; margin: 0px; line-height: normal;" class="">  %a.addr.0 = select i1 %cmp, i32 %sub, i32 %a</div><div style="font-family: Monaco; font-size: 11px; margin: 0px; line-height: normal;" class="">  %mul = mul nsw i32 %a.addr.0, %b</div><div style="font-family: Monaco; font-size: 11px; margin: 0px; line-height: normal;" class="">  %sub2 = sub nsw i32 0, %mul</div><div style="font-family: Monaco; font-size: 11px; margin: 0px; line-height: normal;" class="">  %res.0 = select i1 %cmp, i32 %sub2, i32 %mul</div><div style="font-family: Monaco; font-size: 11px; margin: 0px; line-height: normal;" class="">  ret i32 %res.0</div><div style="font-family: Monaco; font-size: 11px; margin: 0px; line-height: normal;" class="">}</div><div style="font-family: Monaco; font-size: 11px; margin: 0px; line-height: normal;" class=""><br class=""></div><div style="font-family: Monaco; font-size: 11px; margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">All branching was removed and replaced by ‘select’ instructions. Unfortunately, 32 bit operations are expensive on my architecture and in most cases it would be desirable to just keep the original branches, which are relatively cheap. The case above could be converted back to branching by the backend, but for the general case, this is not always practical and misses other optimisation opportunities.</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">I tried to set 'phi-node-folding-threshold’ to 1 or even 0, and this definitely improves the situation in many cases, but Clang still creates instances of ‘select’ instructions, which are detrimental to my target. I am unsure about where are they created, as I believe that the simplifycfg pass does not longer create them. </div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">So the question is: Are there any other hooks in clang, or custom code that I can implement, to relax the creation of ’select’ instructions as opposed to preserving branches in the original c code?</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">Thanks,</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">John</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div></div></div></body></html>