------- Comment #5 from rguenth at gcc dot gnu dot org 2007-04-20 15:33 -------
Note that this does fix the loop invariant motion only in the case of two
ifs can be merged (because that re-instantiates the A & (1 << B) form). The
following parts are still not resolved:
void quantum_cnot(int control, int target, unsigned long *state, int size)
{
int i;
for(i=0; i<size; i++)
{
if (state[i] & ((unsigned long) 1 << control))
state[i] ^= ((unsigned long) 1 << target);
}
}
(and more similar loops in libquantum). It would be nice if rtl loop-invariant
motion could detect this form:
(insn 23 22 24 4 (parallel [
(set (reg:DI 67)
(lshiftrt:DI (reg:DI 62 [ D.1992 ])
(subreg:QI (reg/v:SI 63 [ control ]) 0)))
(clobber (reg:CC 17 flags))
]) 470 {*lshrdi3_1_rex64} (nil)
(nil))
(insn 24 23 25 4 (parallel [
(set (reg:SI 68)
(and:SI (subreg:SI (reg:DI 67) 0)
(const_int 1 [0x1])))
(clobber (reg:CC 17 flags))
]) 301 {*andsi_1} (nil)
(nil))
and move the invariant (1 << control). It does move the (1 << target) which
looks like
(insn 30 28 31 5 (set (reg:DI 70)
(const_int 1 [0x1])) 82 {*movdi_1_rex64} (nil)
(nil))
(insn 31 30 32 5 (parallel [
(set (reg:DI 69)
(ashift:DI (reg:DI 70)
(subreg:QI (reg/v:SI 64 [ target ]) 0)))
(clobber (reg:CC 17 flags))
]) 411 {*ashldi3_1_rex64} (nil)
(expr_list:REG_EQUAL (ashift:DI (const_int 1 [0x1])
(subreg:QI (reg/v:SI 64 [ target ]) 0))
(nil)))
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29789