This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/25111] New: [m68k] bset is not used for A = 1 << (B & 31) on ColdFire
- From: "kazu at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 27 Nov 2005 00:48:56 -0000
- Subject: [Bug target/25111] New: [m68k] bset is not used for A = 1 << (B & 31) on ColdFire
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
Consider:
int bar (void);
int
foo (int b)
{
int a = bar ();
return a | (1 << (b & 31));
}
./cc1 -quiet -O2 -m5200 -fomit-frame-pointer generates
foo:
move.l %d2,-(%sp)
move.l 8(%sp),%d2
jbsr bar
moveq #31,%d1
and.l %d1,%d2
move.b #1,%d1
lsl.l %d2,%d1
or.l %d1,%d0
move.l (%sp)+,%d2
rts
Note that bset could be used in place of the five instructions between
moveq and or.l, inclusive.
Of course, the five instructions are too many for the combiner, but
the combiner already suggests an intermediate insn like so
(set (reg:SI 36)
(ashift:SI (reg:SI 37)
(and:SI (reg/v:SI 32 [ b ])
(const_int 31 [0x1f]))))
which we can implement using clr and bset.
Once this combination is established, going to
(set (reg:SI)
(ior:SI (reg:SI)
(ashift:SI (const_int 1)
(and:SI (reg:SI)
(const_int 31)))))
shouldn't be difficult.
Interestingly, if we feed A as an argument instead of a return value,
the combiner does not produce the ashift insn mentioned above.
--
Summary: [m68k] bset is not used for A = 1 << (B & 31) on
ColdFire
Product: gcc
Version: 4.1.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: enhancement
Priority: P3
Component: target
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: kazu at gcc dot gnu dot org
GCC target triplet: m68k-elf
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25111