<html><head><style type='text/css'>p { margin: 0; }</style></head><body><div style='font-family: arial,helvetica,sans-serif; font-size: 10pt; color: #000000'><br><hr id="zwchr"><blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px; color: rgb(0, 0, 0); font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><b>From: </b>"Sanjay Patel" <spatel@rotateright.com><br><b>To: </b>"llvm-dev" <llvm-dev@lists.llvm.org><br><b>Cc: </b>"Eli Friedman" <efriedma@codeaurora.org>, "David Majnemer" <david.majnemer@gmail.com>, "Michael Kuperstein" <mkuper@google.com>, "Philip Reames" <listmail@philipreames.com>, "Hal Finkel" <hfinkel@anl.gov><br><b>Sent: </b>Wednesday, September 28, 2016 5:39:38 PM<br><b>Subject: </b>IR canonicalization: select or bool math?<br><br><div dir="ltr"><div id="DWT10008"><div><div>I have another round of questions about IR select canonicalizations. For the purity of this quiz, please disregard prior knowledge of how this is handled by instcombine or how this is lowered by your favorite target...of course we'll fix it. :) Some answers in the links below if you do want to know.<br></div></div><div><br></div>Which, if any, of these is canonical?<br></div></div></blockquote>I think that we should prefer the single-IR-instruction forms as canonical. zext/sext, when it is all that is needed, and the select otherwise. I suspect that will be better for analysis and follow-on optimizations, at least most of the time. For lowering, OTOH, I'd prefer the forms with zext/sext combined with xor/add/sub.<br><br> -Hal<br><blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px; color: rgb(0, 0, 0); font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><div dir="ltr"><div> <br></div><div><span style="font-family: monospace,monospace;">1. Is a zext simpler than a select?<br></span></div><div><span style="font-family: monospace,monospace;">a. define i32 @sel_1_or_0(i1 %a) {<br> %b = select i1 %a, i32 1, i32 0<br> ret i32 %b<br>}<br><br></span></div><span style="font-family: monospace,monospace;">b. define i32 @sel_1_or_0(i1 %a) {<br></span><div><span style="font-family: monospace,monospace;"> %b = zext i1 %a to i32<br> ret i32 %b<br>}<br><br></span></div><div><span style="font-family: monospace,monospace;">2. What if we have to 'not' the bool?<br></span></div><div><span style="font-family: monospace,monospace;">a. define i32 @sel_0_or_1(i1 %a) {<br> %b = select i1 %a, i32 0, i32 1<br> ret i32 %b<br>}<br><br></span></div><div><span style="font-family: monospace,monospace;">b. define i32 @sel_0_or_1(i1 %a) {<br> %not.a = xor i1 %a, true<br> %b = zext i1 %not.a to i32<br> ret i32 %b<br>}<br><br></span></div><div><span style="font-family: monospace,monospace;">3. Is sext handled differently?<br></span></div><div><span style="font-family: monospace,monospace;">a. define i32 @sel_-1_or_0(i1 %a) {<br> %b = select i1 %a, i32 -1, i32 0<br> ret i32 %b<br>}<br><br></span></div><div><span style="font-family: monospace,monospace;">b. define i32 @sel_-1_or_0(i1 %a) {<br> %b = sext i1 %a to i32<br> ret i32 %b<br>}<br><br>4. What if the sext needs a 'not'?<br>a. define i32 @sel_0_or_-1(i1 %a) {<br> %b = select i1 %a, i32 0, i32 -1<br> ret i32 %b<br>}<br><br></span></div><div><span style="font-family: monospace,monospace;">b. define i32 @sel_0_or_-1(i1 %a) {<br> %not.a = xor i1 %a, true<br> %b = sext i1 %not.a to i32<br> ret i32 %b<br>}<br><br></span></div><div><span style="font-family: monospace,monospace;">5. What if both constants are non-zero? Ie, the implicit add/sub of the earlier cases can't be eliminated.<br></span></div><div><span style="font-family: monospace,monospace;">a. define i32 @sel_2_or_1(i1 %a) {<br> %b = select i1 %a, i32 2, i32 1<br> ret i32 %b<br>}<br><br></span></div><div><span style="font-family: monospace,monospace;">b. define i32 @sel_2_or_1(i1 %a) {<br> %b = zext i1 to i32 %a<br></span></div><div><span style="font-family: monospace,monospace;"> %c = add i32 %b, 1<br></span></div><div><span style="font-family: monospace,monospace;"> ret i32 %b<br>}<br><br></span></div><div><span style="font-family: monospace,monospace;">6. Does 'sub' make a difference?<br></span></div><div><span style="font-family: monospace,monospace;">a. define i32 @sel_1_or_2(i1 %a) {<br> %b = select i1 %a, i32 1, i32 2<br> ret i32 %b<br>}<br><br></span></div><div><span style="font-family: monospace,monospace;">b. define i32 @sel_1_or_2(i1 %a) {<br> %b = zext i1 %a to i32<br></span></div><div><span style="font-family: monospace,monospace;"> %c = sub i32 2, %b<br></span></div><div><span style="font-family: monospace,monospace;"> ret i32 %c<br></span></div><div><span style="font-family: monospace,monospace;">}<br><br></span></div><div><span style="font-family: monospace,monospace;">7. Choose between integers that are not consecutive?<br></span><div><span style="font-family: monospace,monospace;">a. define i32 @sel_0_or_2(i1 %a) {<br></span></div><div><span style="font-family: monospace,monospace;"> %sel = select i1 %a, i32 2, i32 0<br></span></div><div><span style="font-family: monospace,monospace;"> ret i32 %sel2<br>}<br><br></span></div><div><span style="font-family: monospace,monospace;">b. define i32 @sel_0_or_2(i1 %a) {<br></span><div><span style="font-family: monospace,monospace;"> %zexta = zext i1 %a to i32<br></span></div><div><span style="font-family: monospace,monospace;"> %add = add i32 %zexta, %zexta<br></span></div><span style="font-family: monospace,monospace;"> ret i32 %add<br>}<br><br></span></div></div><div><span style="font-family: monospace,monospace;">8. Choose {0,1,2} based on 2 bools?<br></span></div><div><span style="font-family: monospace,monospace;">a. define i32 @sel_sel(i1 %a, i1 %b) {<br></span></div><div><span style="font-family: monospace,monospace;"> %zexta = zext i1 %a to i32<br></span></div><div><span style="font-family: monospace,monospace;"> %sel1 = select i1 %a, i32 2, i32 1<br></span></div><div><span style="font-family: monospace,monospace;"> %sel2 = select i1 %b, i32 %sel1, %zexta<br></span></div><div><span style="font-family: monospace,monospace;"> ret i32 %sel2<br>}<br><br></span></div><div><span style="font-family: monospace,monospace;">b. define i32 @sel_sel(i1 %a, i1 %b) {<br></span><div><span style="font-family: monospace,monospace;"> %zexta = zext i1 %a to i32<br></span></div><div><span style="font-family: monospace,monospace;"> %zextb = zext i1 %b to i32<br></span></div><div><span style="font-family: monospace,monospace;"> %add = add i32 %zexta, %zextb<br></span></div><span style="font-family: monospace,monospace;"> ret i32 %add<br>}<br><br></span></div><div><span style="font-family: monospace,monospace;">Links for reference:<br><a href="https://llvm.org/bugs/show_bug.cgi?id=30273" target="_blank">https://llvm.org/bugs/show_bug.cgi?id=30273</a><br><a href="https://llvm.org/bugs/show_bug.cgi?id=30327" target="_blank">https://llvm.org/bugs/show_bug.cgi?id=30327</a><br><a href="https://reviews.llvm.org/D24480" target="_blank">https://reviews.llvm.org/D24480</a><br></span><br></div><div><pre id="gmail-comment_text_0" class="gmail-bz_comment_text"></pre></div></div>
</blockquote><br><br><br>-- <br><div><span name="x"></span>Hal Finkel<br>Lead, Compiler Technology and Programming Languages<br>Leadership Computing Facility<br>Argonne National Laboratory<span name="x"></span><br></div></div></body></html>