https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122534
Bug ID: 122534
Summary: cmpelim does not try to remove unused part when
merging insn
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: pinskia at gcc dot gnu.org
Target Milestone: ---
Take:
```
int
test(unsigned long long p[6], int index)
{
__SIZE_TYPE__ i;
for (i = 0; i < 6; i++)
if (p[i] & (1ULL << index))
return i;
return 0;
}
```
cmpelim combines:
```
(insn 12 45 13 3 (parallel [
(set (reg:DI 1 dx [orig:106 shifttmp_13 ] [106])
(and:DI (reg:DI 1 dx [orig:106 shifttmp_13 ] [106])
(mem:DI (plus:DI (mult:DI (reg/v:DI 0 ax [orig:100 i ]
[100])
(const_int 8 [0x8]))
(reg/f:DI 5 di [orig:108 p ] [108])) [1 MEM[(long
long unsigned int *)p_8(D) + i_14 * 8]+0 S8 A64])))
(clobber (reg:CC 17 flags))
]) "/app/example.cpp":7:12 710 {*anddi_1}
(nil))
(insn 13 12 14 3 (set (reg:CCZ 17 flags)
(compare:CCZ (reg:DI 1 dx [orig:106 shifttmp_13 ] [106])
(const_int 0 [0]))) "/app/example.cpp":7:12 12 {*cmpdi_ccno_1}
(nil))
```
Into:
```
(insn 12 45 14 3 (parallel [
(set (reg:CCZ 17 flags)
(compare:CCZ (and:DI (reg:DI 1 dx [orig:106 shifttmp_13 ]
[106])
(mem:DI (plus:DI (mult:DI (reg/v:DI 0 ax [orig:100 i ]
[100])
(const_int 8 [0x8]))
(reg/f:DI 5 di [orig:108 p ] [108])) [1
MEM[(long long unsigned int *)p_8(D) + i_14 * 8]+0 S8 A64]))
(const_int 0 [0])))
(set (reg:DI 1 dx [orig:106 shifttmp_13 ] [106])
(and:DI (reg:DI 1 dx [orig:106 shifttmp_13 ] [106])
(mem:DI (plus:DI (mult:DI (reg/v:DI 0 ax [orig:100 i ]
[100])
(const_int 8 [0x8]))
(reg/f:DI 5 di [orig:108 p ] [108])) [1 MEM[(long
long unsigned int *)p_8(D) + i_14 * 8]+0 S8 A64])))
]) "/app/example.cpp":7:12 753 {*anddi_2}
(nil))
```
But dx was really REG_DEAD after `insn 13` as later on REG_UNUSED is added to
`insn 12`:
```
(insn 12 45 14 3 (parallel [
(set (reg:CCZ 17 flags)
(compare:CCZ (and:DI (reg:DI 1 dx [orig:106 shifttmp_13 ]
[106])
(mem:DI (plus:DI (mult:DI (reg/v:DI 0 ax [orig:100 i ]
[100])
(const_int 8 [0x8]))
(reg/f:DI 5 di [orig:108 p ] [108])) [1
MEM[(long long unsigned int *)p_8(D) + i_14 * 8]+0 S8 A64]))
(const_int 0 [0])))
(set (reg:DI 1 dx [orig:106 shifttmp_13 ] [106])
(and:DI (reg:DI 1 dx [orig:106 shifttmp_13 ] [106])
(mem:DI (plus:DI (mult:DI (reg/v:DI 0 ax [orig:100 i ]
[100])
(const_int 8 [0x8]))
(reg/f:DI 5 di [orig:108 p ] [108])) [1 MEM[(long
long unsigned int *)p_8(D) + i_14 * 8]+0 S8 A64])))
]) "/app/example.cpp":7:12 753 {*anddi_2}
(expr_list:REG_UNUSED (reg:DI 1 dx [orig:106 shifttmp_13 ] [106])
(nil)))
```
Now if we merged this during combine it would have worked.
Combine tries to combine them but we get:
```
Trying 12 -> 13:
12: {r106:DI=r99:DI&[r100:DI*0x8+r103:DI];clobber flags:CC;}
REG_UNUSED flags:CC
13: flags:CCZ=cmp(r106:DI,0)
REG_DEAD r106:DI
Failed to match this instruction:
(set (reg:CCZ 17 flags)
(compare:CCZ (and:DI (reg:DI 99 [ shifttmp_6 ])
(mem:DI (plus:DI (mult:DI (reg/v:DI 100 [ i ])
(const_int 8 [0x8]))
(reg/v/f:DI 103 [ p ])) [1 MEM[(long long unsigned int
*)p_8(D) + i_14 * 8]+0 S8 A64]))
(const_int 0 [0])))
```