https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49263
Alexander Klepikov <klepikov.alex+bugs at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |klepikov.alex+bugs at gmail dot co | |m --- Comment #31 from Alexander Klepikov <klepikov.alex+bugs at gmail dot com> --- I've found new cases for SH2 and SH2E CPUs only: #define FLAG 0x40 unsigned int f(char v){ return (v & FLAG) == FLAG; } For both big and little endian translates to dynamic shift call: -O -m2 (or -m2e) _f: sts.l pr,@-r15 mov.l .L3,r1 jsr @r1 exts.b r4,r4 mov r4,r0 and #1,r0 lds.l @r15+,pr rts nop .L3: .long ___ashiftrt_r4_6 And #define FLAG 0x40 #define ADDR 0xFFFF0000 #define P ((unsigned char *)ADDR) unsigned int f(void){ return (*P & FLAG) == FLAG; } Translates to _f: sts.l pr,@-r15 mov.l .L3,r1 mov.b @r1,r4 mov.l .L4,r1 jsr @r1 nop mov r4,r0 and #1,r0 lds.l @r15+,pr rts nop .L3: .long -65536 .L4: .long ___ashiftrt_r4_6 Assembler output does not depend on ADDR value, but depends on variable (or pointer) type. When type is integer, assembler code uses 'tst' for all options '-m4', '-m2', '-m2e': #define FLAG 0x40 unsigned int f(unsigned int v){ return (v & FLAG) == FLAG; } translates to _f: mov r4,r0 tst #64,r0 mov #-1,r0 rts negc r0,r0 and #define FLAG 0x40 #define ADDR 0xFFFF0000 #define P ((unsigned int *)ADDR) unsigned int f(void){ return (*P & FLAG) == FLAG; } translates to _f: mov.l .L2,r1 mov.l @r1,r0 tst #64,r0 mov #-1,r0 rts negc r0,r0 .L2: .long -65536 Interesting that when '-m4' flag is specified, later GCC always translates to code with 'tst' instruction. I played with godbolt and that's what I found. GCC ver 4 uses dynamic shift 'shad' with '-m4' option and library call with '-m2' or '-m2e' options. GCC 9.5 and later uses 'tst' with '-m4' and library call with both '-m2' and '-m2e' when FLAG==0x40 and 'shll' instruction with both '-m2' and '-m2e' when FLAG==0x80. I remind you that this is happening when char type used only. Maybe SH4 solution can be extended to support SH2/SH2E?