# [llvm-dev] IR canonicalization: select or bool math?

Mehdi Amini via llvm-dev llvm-dev at lists.llvm.org
Wed Sep 28 21:15:14 PDT 2016

```Thanks for sharing this! Quite interesting questions indeed :)

I regret that we don’t have any documentation (on the same level as LangRef) that would record and describe the canonicalization of the IR and the motivation for each case.

—
Mehdi

> On Sep 28, 2016, at 3:39 PM, Sanjay Patel via llvm-dev <llvm-dev at lists.llvm.org> wrote:
>
> 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.
>
> Which, if any, of these is canonical?
>
> 1. Is a zext simpler than a select?
> a. define i32 @sel_1_or_0(i1 %a) {
>   %b = select i1 %a, i32 1, i32 0
>   ret i32 %b
> }
>
> b. define i32 @sel_1_or_0(i1 %a) {
>   %b = zext i1 %a to i32
>   ret i32 %b
> }
>
> 2. What if we have to 'not' the bool?
> a. define i32 @sel_0_or_1(i1 %a) {
>   %b = select i1 %a, i32 0, i32 1
>   ret i32 %b
> }
>
> b. define i32 @sel_0_or_1(i1 %a) {
>   %not.a = xor i1 %a, true
>   %b = zext i1 %not.a to i32
>   ret i32 %b
> }
>
> 3. Is sext handled differently?
> a. define i32 @sel_-1_or_0(i1 %a) {
>   %b = select i1 %a, i32 -1, i32 0
>   ret i32 %b
> }
>
> b. define i32 @sel_-1_or_0(i1 %a) {
>   %b = sext i1 %a to i32
>   ret i32 %b
> }
>
> 4. What if the sext needs a 'not'?
> a. define i32 @sel_0_or_-1(i1 %a) {
>   %b = select i1 %a, i32 0, i32 -1
>   ret i32 %b
> }
>
> b. define i32 @sel_0_or_-1(i1 %a) {
>   %not.a = xor i1 %a, true
>   %b = sext i1 %not.a to i32
>   ret i32 %b
> }
>
> 5. What if both constants are non-zero? Ie, the implicit add/sub of the earlier cases can't be eliminated.
> a. define i32 @sel_2_or_1(i1 %a) {
>   %b = select i1 %a, i32 2, i32 1
>   ret i32 %b
> }
>
> b. define i32 @sel_2_or_1(i1 %a) {
>   %b = zext i1 to i32 %a
>   %c = add i32 %b, 1
>   ret i32 %b
> }
>
> 6. Does 'sub' make a difference?
> a. define i32 @sel_1_or_2(i1 %a) {
>   %b = select i1 %a, i32 1, i32 2
>   ret i32 %b
> }
>
> b. define i32 @sel_1_or_2(i1 %a) {
>   %b = zext i1 %a to i32
>   %c = sub i32 2, %b
>   ret i32 %c
> }
>
> 7. Choose between integers that are not consecutive?
> a. define i32 @sel_0_or_2(i1 %a) {
>   %sel = select i1 %a, i32 2, i32 0
>   ret i32 %sel2
> }
>
> b. define i32 @sel_0_or_2(i1 %a) {
>   %zexta = zext i1 %a to i32
> }
>
> 8. Choose {0,1,2} based on 2 bools?
> a. define i32 @sel_sel(i1 %a, i1 %b) {
>   %zexta = zext i1 %a to i32
>   %sel1 = select i1 %a, i32 2, i32 1
>   %sel2 = select i1 %b, i32 %sel1, %zexta
>   ret i32 %sel2
> }
>
> b. define i32 @sel_sel(i1 %a, i1 %b) {
>   %zexta = zext i1 %a to i32
>   %zextb = zext i1 %b to i32
> }
>
> https://llvm.org/bugs/show_bug.cgi?id=30273 <https://llvm.org/bugs/show_bug.cgi?id=30273>
> https://llvm.org/bugs/show_bug.cgi?id=30327 <https://llvm.org/bugs/show_bug.cgi?id=30327>
> https://reviews.llvm.org/D24480 <https://reviews.llvm.org/D24480>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160928/aacc363d/attachment.html>
```