This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/19154] New: miss-optimization of (x & pow2C) avr conditionals returning bool equivalent values
- From: "schlie at comcast dot net" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 25 Dec 2004 20:21:34 -0000
- Subject: [Bug c/19154] New: miss-optimization of (x & pow2C) avr conditionals returning bool equivalent values
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
/* miss-optimization of (x & pow2C) conditionals returning bool equivalent values.
Conditional expressions returning/assigning bool equivalent values tend to
produce less efficient generic code than those returning arbitrary values;
GCC 3.3.3 produces the more effecient form of the results consistently. */
int main (void){
volatile char c;
volatile int i;
volatile long l;
/* char tests */
c = (c & (1 << 3)); // ok: ((char)c & C).
c = (c & (1 << 3)) ? 3 : 5; // ok: if((char)c & C) -> avr's bit-test&skip.
c = (c & (1 << 3)) ? 1 : 0; // poor: if((char)c & C) -> if(((int)c >> C') & 1), w/unnessisary (int)c
promotion.
if (c & (1 << 3)) // ok: if((char)c & C) -> avr's bit-test&skip.
c = 3;
else c = 5;
if (c & (1 << 3)) // ok: if((char)c & C) -> avr's bit-test&skip.
c = 1;
else c = 0;
/* int tests */
i = i & (1 << 11); // ok: ((int)i & C)
i = (i & (1 << 11)) ? 3 : 5; // ok: if((int)i & C) -> avr's bit-test&skip.
i = (i & (1 << 11)) ? 1 : 0; // poor: if((int)i & C) -> if(((int)i >> C') & 1).
if (i & (1 << 11)) // ok: if((int)i & C) -> avr's bit-test&skip.
i = 3;
else i = 5;
if (i & (1 << 11)) // poor: if((int)i & C) -> avr's bit-test&skip, but w/ineffecient return value.
i = 1;
else i = 0;
/* long tests */
l = (l & ((long)1 << 27)); // ok: ((long)l & C)
l = (l & ((long)1 << 27)) ? 3 : 5; // ok: if((long)l & C) -> avr's bit-test&skip.
l = (l & ((long)1 << 27)) ? 1 : 0; // poor: if((long)l & C) -> if(((long)l >> C') & 1).
if (l & ((long)1 << 27)) // ok: if((long)l & C) -> avr's bit-test&skip.
l = 3;
else l = 5;
if (l & ((long)1 << 27)) // poor: if((long)l & C) -> avr's bit-test&skip, but w/ineffecient return value.
l = 1;
else l = 0;
return 0;
}
Produces:
int main (void){
c6: c8 ef ldi r28, 0xF8 ; 248
c8: d0 e1 ldi r29, 0x10 ; 16
ca: de bf out 0x3e, r29 ; 62
cc: cd bf out 0x3d, r28 ; 61
volatile char c;
volatile int i;
volatile long l;
/* char tests */
c = (c & (1 << 3)); // ok: ((char)c & C).
ce: 89 81 ldd r24, Y+1 ; 0x01
d0: 88 70 andi r24, 0x08 ; 8
d2: 89 83 std Y+1, r24 ; 0x01
c = (c & (1 << 3)) ? 3 : 5; // ok: if((char)c & C) -> avr's bit-test&skip.
d4: 89 81 ldd r24, Y+1 ; 0x01
d6: 83 ff sbrs r24, 3
d8: 02 c0 rjmp .+4 ; 0xde <main+0x18>
da: 83 e0 ldi r24, 0x03 ; 3
dc: 01 c0 rjmp .+2 ; 0xe0 <main+0x1a>
de: 85 e0 ldi r24, 0x05 ; 5
e0: 89 83 std Y+1, r24 ; 0x01
c = (c & (1 << 3)) ? 1 : 0; // poor: if((char)c & C) -> if(((int)c >> C') & 1), w/unnessisary (int)c
promotion.
e2: 89 81 ldd r24, Y+1 ; 0x01
e4: 99 27 eor r25, r25
e6: 43 e0 ldi r20, 0x03 ; 3
e8: 96 95 lsr r25
ea: 87 95 ror r24
ec: 4a 95 dec r20
ee: e1 f7 brne .-8 ; 0xe8 <main+0x22>
f0: 81 70 andi r24, 0x01 ; 1
f2: 89 83 std Y+1, r24 ; 0x01
if (c & (1 << 3)) // ok: if((char)c & C) -> avr's bit-test&skip.
f4: 89 81 ldd r24, Y+1 ; 0x01
f6: 83 ff sbrs r24, 3
f8: 02 c0 rjmp .+4 ; 0xfe <main+0x38>
c = 3;
fa: 83 e0 ldi r24, 0x03 ; 3
fc: 01 c0 rjmp .+2 ; 0x100 <main+0x3a>
else c = 5;
fe: 85 e0 ldi r24, 0x05 ; 5
100: 89 83 std Y+1, r24 ; 0x01
if (c & (1 << 3)) // ok: if((char)c & C) -> avr's bit-test&skip.
102: 89 81 ldd r24, Y+1 ; 0x01
104: 83 ff sbrs r24, 3
106: 03 c0 rjmp .+6 ; 0x10e <main+0x48>
c = 1;
108: 81 e0 ldi r24, 0x01 ; 1
10a: 89 83 std Y+1, r24 ; 0x01
10c: 01 c0 rjmp .+2 ; 0x110 <main+0x4a>
else c = 0;
10e: 19 82 std Y+1, r1 ; 0x01
/* int tests */
i = i & (1 << 11); // ok: ((int)i & C)
110: 8a 81 ldd r24, Y+2 ; 0x02
112: 9b 81 ldd r25, Y+3 ; 0x03
114: 80 70 andi r24, 0x00 ; 0
116: 98 70 andi r25, 0x08 ; 8
118: 8a 83 std Y+2, r24 ; 0x02
11a: 9b 83 std Y+3, r25 ; 0x03
i = (i & (1 << 11)) ? 3 : 5; // ok: if((int)i & C) -> avr's bit-test&skip.
11c: 8a 81 ldd r24, Y+2 ; 0x02
11e: 9b 81 ldd r25, Y+3 ; 0x03
120: 93 ff sbrs r25, 3
122: 03 c0 rjmp .+6 ; 0x12a <main+0x64>
124: 83 e0 ldi r24, 0x03 ; 3
126: 90 e0 ldi r25, 0x00 ; 0
128: 02 c0 rjmp .+4 ; 0x12e <main+0x68>
12a: 85 e0 ldi r24, 0x05 ; 5
12c: 90 e0 ldi r25, 0x00 ; 0
12e: 8a 83 std Y+2, r24 ; 0x02
130: 9b 83 std Y+3, r25 ; 0x03
i = (i & (1 << 11)) ? 1 : 0; // poor: if((int)i & C) -> if(((int)i >> C') & 1).
132: 8a 81 ldd r24, Y+2 ; 0x02
134: 9b 81 ldd r25, Y+3 ; 0x03
136: 89 2f mov r24, r25
138: 99 27 eor r25, r25
13a: 86 95 lsr r24
13c: 86 95 lsr r24
13e: 86 95 lsr r24
140: 81 70 andi r24, 0x01 ; 1
142: 90 70 andi r25, 0x00 ; 0
144: 8a 83 std Y+2, r24 ; 0x02
146: 9b 83 std Y+3, r25 ; 0x03
if (i & (1 << 11)) // ok: if((int)i & C) -> avr's bit-test&skip.
148: 8a 81 ldd r24, Y+2 ; 0x02
14a: 9b 81 ldd r25, Y+3 ; 0x03
14c: 93 ff sbrs r25, 3
14e: 03 c0 rjmp .+6 ; 0x156 <main+0x90>
i = 3;
150: 83 e0 ldi r24, 0x03 ; 3
152: 90 e0 ldi r25, 0x00 ; 0
154: 02 c0 rjmp .+4 ; 0x15a <main+0x94>
else i = 5;
156: 85 e0 ldi r24, 0x05 ; 5
158: 90 e0 ldi r25, 0x00 ; 0
15a: 8a 83 std Y+2, r24 ; 0x02
15c: 9b 83 std Y+3, r25 ; 0x03
if (i & (1 << 11)) // poor: if((int)i & C) -> avr's bit-test&skip, but w/ineffecient return value.
15e: 8a 81 ldd r24, Y+2 ; 0x02
160: 9b 81 ldd r25, Y+3 ; 0x03
162: 9c 01 movw r18, r24
164: 20 70 andi r18, 0x00 ; 0
166: 38 70 andi r19, 0x08 ; 8
168: 93 ff sbrs r25, 3
16a: 05 c0 rjmp .+10 ; 0x176 <main+0xb0>
i = 1;
16c: 81 e0 ldi r24, 0x01 ; 1
16e: 90 e0 ldi r25, 0x00 ; 0
170: 8a 83 std Y+2, r24 ; 0x02
172: 9b 83 std Y+3, r25 ; 0x03
174: 02 c0 rjmp .+4 ; 0x17a <main+0xb4>
else i = 0;
176: 2a 83 std Y+2, r18 ; 0x02
178: 3b 83 std Y+3, r19 ; 0x03
/* long tests */
l = (l & ((long)1 << 27)); // ok: ((long)l & C)
17a: 8c 81 ldd r24, Y+4 ; 0x04
17c: 9d 81 ldd r25, Y+5 ; 0x05
17e: ae 81 ldd r26, Y+6 ; 0x06
180: bf 81 ldd r27, Y+7 ; 0x07
182: 80 70 andi r24, 0x00 ; 0
184: 90 70 andi r25, 0x00 ; 0
186: a0 70 andi r26, 0x00 ; 0
188: b8 70 andi r27, 0x08 ; 8
18a: 8c 83 std Y+4, r24 ; 0x04
18c: 9d 83 std Y+5, r25 ; 0x05
18e: ae 83 std Y+6, r26 ; 0x06
190: bf 83 std Y+7, r27 ; 0x07
l = (l & ((long)1 << 27)) ? 3 : 5; // ok: if((long)l & C) -> avr's bit-test&skip.
192: 8c 81 ldd r24, Y+4 ; 0x04
194: 9d 81 ldd r25, Y+5 ; 0x05
196: ae 81 ldd r26, Y+6 ; 0x06
198: bf 81 ldd r27, Y+7 ; 0x07
19a: b3 ff sbrs r27, 3
19c: 05 c0 rjmp .+10 ; 0x1a8 <main+0xe2>
19e: 83 e0 ldi r24, 0x03 ; 3
1a0: 90 e0 ldi r25, 0x00 ; 0
1a2: a0 e0 ldi r26, 0x00 ; 0
1a4: b0 e0 ldi r27, 0x00 ; 0
1a6: 04 c0 rjmp .+8 ; 0x1b0 <main+0xea>
1a8: 85 e0 ldi r24, 0x05 ; 5
1aa: 90 e0 ldi r25, 0x00 ; 0
1ac: a0 e0 ldi r26, 0x00 ; 0
1ae: b0 e0 ldi r27, 0x00 ; 0
1b0: 8c 83 std Y+4, r24 ; 0x04
1b2: 9d 83 std Y+5, r25 ; 0x05
1b4: ae 83 std Y+6, r26 ; 0x06
1b6: bf 83 std Y+7, r27 ; 0x07
l = (l & ((long)1 << 27)) ? 1 : 0; // poor: if((long)l & C) -> if(((long)l >> C') & 1).
1b8: 8c 81 ldd r24, Y+4 ; 0x04
1ba: 9d 81 ldd r25, Y+5 ; 0x05
1bc: ae 81 ldd r26, Y+6 ; 0x06
1be: bf 81 ldd r27, Y+7 ; 0x07
1c0: 2b e1 ldi r18, 0x1B ; 27
1c2: b6 95 lsr r27
1c4: a7 95 ror r26
1c6: 97 95 ror r25
1c8: 87 95 ror r24
1ca: 2a 95 dec r18
1cc: d1 f7 brne .-12 ; 0x1c2 <main+0xfc>
1ce: aa 27 eor r26, r26
1d0: 97 fd sbrc r25, 7
1d2: a0 95 com r26
1d4: ba 2f mov r27, r26
1d6: 81 70 andi r24, 0x01 ; 1
1d8: 90 70 andi r25, 0x00 ; 0
1da: a0 70 andi r26, 0x00 ; 0
1dc: b0 70 andi r27, 0x00 ; 0
1de: 8c 83 std Y+4, r24 ; 0x04
1e0: 9d 83 std Y+5, r25 ; 0x05
1e2: ae 83 std Y+6, r26 ; 0x06
1e4: bf 83 std Y+7, r27 ; 0x07
if (l & ((long)1 << 27)) // ok: if((long)l & C) -> avr's bit-test&skip.
1e6: 8c 81 ldd r24, Y+4 ; 0x04
1e8: 9d 81 ldd r25, Y+5 ; 0x05
1ea: ae 81 ldd r26, Y+6 ; 0x06
1ec: bf 81 ldd r27, Y+7 ; 0x07
1ee: b3 ff sbrs r27, 3
1f0: 05 c0 rjmp .+10 ; 0x1fc <main+0x136>
l = 3;
1f2: 83 e0 ldi r24, 0x03 ; 3
1f4: 90 e0 ldi r25, 0x00 ; 0
1f6: a0 e0 ldi r26, 0x00 ; 0
1f8: b0 e0 ldi r27, 0x00 ; 0
1fa: 04 c0 rjmp .+8 ; 0x204 <main+0x13e>
else l = 5;
1fc: 85 e0 ldi r24, 0x05 ; 5
1fe: 90 e0 ldi r25, 0x00 ; 0
200: a0 e0 ldi r26, 0x00 ; 0
202: b0 e0 ldi r27, 0x00 ; 0
204: 8c 83 std Y+4, r24 ; 0x04
206: 9d 83 std Y+5, r25 ; 0x05
208: ae 83 std Y+6, r26 ; 0x06
20a: bf 83 std Y+7, r27 ; 0x07
if (l & ((long)1 << 27)) // poor: if((long)l & C) -> avr's bit-test&skip, but w/ineffecient return value.
20c: 8c 81 ldd r24, Y+4 ; 0x04
20e: 9d 81 ldd r25, Y+5 ; 0x05
210: ae 81 ldd r26, Y+6 ; 0x06
212: bf 81 ldd r27, Y+7 ; 0x07
214: 9c 01 movw r18, r24
216: ad 01 movw r20, r26
218: 20 70 andi r18, 0x00 ; 0
21a: 30 70 andi r19, 0x00 ; 0
21c: 40 70 andi r20, 0x00 ; 0
21e: 58 70 andi r21, 0x08 ; 8
220: b3 ff sbrs r27, 3
222: 09 c0 rjmp .+18 ; 0x236 <main+0x170>
l = 1;
224: 81 e0 ldi r24, 0x01 ; 1
226: 90 e0 ldi r25, 0x00 ; 0
228: a0 e0 ldi r26, 0x00 ; 0
22a: b0 e0 ldi r27, 0x00 ; 0
22c: 8c 83 std Y+4, r24 ; 0x04
22e: 9d 83 std Y+5, r25 ; 0x05
230: ae 83 std Y+6, r26 ; 0x06
232: bf 83 std Y+7, r27 ; 0x07
234: 04 c0 rjmp .+8 ; 0x23e <main+0x178>
else l = 0;
236: 2c 83 std Y+4, r18 ; 0x04
238: 3d 83 std Y+5, r19 ; 0x05
23a: 4e 83 std Y+6, r20 ; 0x06
23c: 5f 83 std Y+7, r21 ; 0x07
return 0;
}
--
Summary: miss-optimization of (x & pow2C) avr conditionals
returning bool equivalent values
Product: gcc
Version: 4.0.0
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: schlie at comcast dot net
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: avr-unknown-none
GCC host triplet: powerpc-apple-darwin7.7.0
GCC target triplet: powerpc-apple-darwin7.7.0
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19154