https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112645
Bug ID: 112645
Summary: missed-optimization: cswitch optimization missed in
nested if-statement
Product: gcc
Version: 13.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: goon.pri.low at gmail dot com
Target Milestone: ---
These two functions should theoretically generate the same code, though the
second one uses a constant array.
int a(int v) {
switch (v & 2) {
case 0: //0x
switch(v & 1) {
case 0: //00
return 643;
case 1: //01
return 223;
}
case 2: //1x
switch (v & 1) {
case 0: //10
return 444;
case 1: //11
return 532;
}
}
}
a:
test dil, 2
je .L7
and edi, 1
cmp edi, 1
sbb eax, eax
and eax, -88
add eax, 532
ret
.L7:
and edi, 1
cmp edi, 1
sbb eax, eax
and eax, 420
add eax, 223
ret
int b(int v) {
switch (v & 3) {
case 0: //00
return 643;
case 1: //01
return 223;
case 2: //10
return 444;
case 3: //11
return 532;
}
}
b:
and edi, 3
mov eax, 643
sub edi, 1
cmp edi, 2
ja .L8
mov eax, DWORD PTR CSWTCH.2[0+rdi*4]
.L8:
ret
CSWTCH.2:
.long 223
.long 444
.long 532
Additionally while testing this, I found this function which should just use a
simple binary and
int c(int v) {
switch (v & 3) {
case 0:
return 0;
case 1:
return 1;
case 2:
return 2;
case 3:
return 3;
}
}
c:
mov eax, edi
and eax, 3
lea edx, [rax-1]
cmp edx, 3
mov edx, 0
cmovnb eax, edx
ret
though has an unnecessary comparison and conditional move?