From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10626 invoked by alias); 25 Dec 2004 20:21:41 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 10591 invoked by uid 48); 25 Dec 2004 20:21:34 -0000 Date: Sat, 25 Dec 2004 20:21:00 -0000 From: "schlie at comcast dot net" To: gcc-bugs@gcc.gnu.org Message-ID: <20041225202132.19154.schlie@comcast.net> Reply-To: gcc-bugzilla@gcc.gnu.org Subject: [Bug c/19154] New: miss-optimization of (x & pow2C) avr conditionals returning bool equivalent values X-Bugzilla-Reason: CC X-SW-Source: 2004-12/txt/msg03527.txt.bz2 List-Id: /* 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 da: 83 e0 ldi r24, 0x03 ; 3 dc: 01 c0 rjmp .+2 ; 0xe0 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 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 c = 3; fa: 83 e0 ldi r24, 0x03 ; 3 fc: 01 c0 rjmp .+2 ; 0x100 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 c = 1; 108: 81 e0 ldi r24, 0x01 ; 1 10a: 89 83 std Y+1, r24 ; 0x01 10c: 01 c0 rjmp .+2 ; 0x110 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 124: 83 e0 ldi r24, 0x03 ; 3 126: 90 e0 ldi r25, 0x00 ; 0 128: 02 c0 rjmp .+4 ; 0x12e 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 i = 3; 150: 83 e0 ldi r24, 0x03 ; 3 152: 90 e0 ldi r25, 0x00 ; 0 154: 02 c0 rjmp .+4 ; 0x15a 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 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 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 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 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 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 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 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 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 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