[Bug tree-optimization/103429] Optimization of Auto-generated condition chain is not giving good lookup tables.

ed at edwardrosten dot com gcc-bugzilla@gcc.gnu.org
Thu Nov 25 15:50:35 GMT 2021


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103429

--- Comment #2 from Edward Rosten <ed at edwardrosten dot com> ---
It is doing if-to-switch, but only really with N=5, and only if force-inline is
set. I think this are two problems, one is that you need to force-inline in
order to trigger if-to-switch.

The other problem is that the if-to-switch conversion triggered only works well
for exactly 5 conditions, otherwise it uses a mix of converted and unconverted.
It doesn't appear to be doing binary tree generation, more like linear search
Here's the asm for N=7:

run(int):
        ret
run_inline(int):
        test    edi, edi
        je      .L13
        cmp     edi, 1
        je      .L14
        cmp     edi, 6
        ja      .L3
        mov     edi, edi
        jmp     [QWORD PTR .L8[0+rdi*8]]
.L8:
        .quad   .L3
        .quad   .L3
        .quad   .L12
        .quad   .L11
        .quad   .L10
        .quad   .L9
        .quad   .L7
.L13:
        jmp     void f<0>()
.L7:
        jmp     void f<6>()
.L12:
        jmp     void f<2>()
.L11:
        jmp     void f<3>()
.L10:
        jmp     void f<4>()
.L9:
        jmp     void f<5>()
.L14:
        jmp     void f<1>()
.L3:
        ret

Note, it's essentially doing:

if(i==0)
    f<0>();
else if(i==1)
    f<1>();
else if(i > 6)
    return;
else switch(i){
    case 0:
    case 1:   
        return;
    case 2: f<2>(); return;
    case 3: f<3>(); return;
    case 4: f<4>(); return;
    case 5: f<5>(); return;
    case 6: f<6>(); return;
}

It's not doing binary searches. For, e.g. N%5 == 1, the structure is more like:

if(i==0)
    f<0>();
else if(i > 5){
    if(i-5 > 4){
        if(i-11>4){
            if(i-16 > 4){ 
                 // and so on, linearly
            }
            else switch(i-16){
                 //...
            }
        }
        else switch(i-11){
           //...
        }
    }
    else switch(i-6){
      //...
    }

}
else switch(i){
    case 0:
        return;
    case 1: f<1>(); return;  
    case 2: f<2>(); return;
    case 3: f<3>(); return;
    case 4: f<4>(); return;
    case 5: f<5>(); return;
}


More information about the Gcc-bugs mailing list