[Bug c++/17972] [3.4 Regression] const/pure functions result in bad asm
--- Additional Comments From mostrows at watson dot ibm dot com 2005-02-24 14:18 --- New test case exhibits same problem. struct demo { int s; }; extern struct demo * const *xd; static inline struct demo *fn1(void) __attribute__((pure)); static inline struct demo *fn1(void) { struct demo { int s; }; extern struct demo * const *xd; static inline struct demo *fn1(void) __attribute__((pure)); static inline struct demo *fn1(void) { struct demo **d; return *xd; } unsigned long foo() { unsigned long old = 0; old = (fn1()->s) & (((1UL << (8))-1) << 0); (fn1()->s) -= old; return old; } Here's how the generated code looks like, note the branch to self. [EMAIL PROTECTED]:/tmp$ /opt/crosstool/bin/powerpc64-linux-gcc -x c++ -O -c /tmp/bug.C -S -o - .file "bug.C" .section".text" .align 2 .globl _Z3foov .section".opd","aw" .align 3 _Z3foov: .quad ._Z3foov,[EMAIL PROTECTED],0 .previous .size _Z3foov,24 .type ._Z3foov,@function .globl ._Z3foov ._Z3foov: .LFB3: .L3: b .L3 .long 0 .byte 0,9,0,0,0,0,0,0 .LFE3: .size ._Z3foov,.-._Z3foov .section.note.GNU-stack,"",@progbits .ident "GCC: (GNU) 3.4.4 20050211 (prerelease)" Specifying language as "C" instead of C++ results in correct code generation. -- What|Removed |Added Status|RESOLVED|REOPENED Resolution|FIXED | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17972
[Bug c++/17972] New: const/pure functions result in bad asm
Snippet of shell session demonstrates how compiler generates bad asm (compare to result of compilation without -DBUG). Toolchain built using latest "crosstool" scripts. Sample code attached below. [EMAIL PROTECTED]:~/tools.k42/powerpc/partDeb/os$ powerpc64-linux-g++-c -o workqueue.o wq.C -O1 -DBUG [EMAIL PROTECTED]:~/tools.k42/powerpc/partDeb/os$ powerpc64-linux-objdump -d workqueue.o workqueue.o: file format elf64-powerpc Disassembly of section .text: <._Z10queue_workP16workqueue_structP11work_struct>: 0: 7c 08 02 a6 mflrr0 4: f8 01 00 10 std r0,16(r1) 8: f8 21 ff 91 stdur1,-112(r1) c: 7d a9 6b 78 mr r9,r13 10: e9 29 00 00 ld r9,0(r9) 14: 88 09 00 03 lbz r0,3(r9) 18: 2f a0 00 00 cmpdi cr7,r0,0 1c: 40 be 00 10 bne+cr7,2c <._Z10queue_workP16workqueue_structP11work_struct+0x2c> 20: 48 00 00 01 bl 20 <._Z10queue_workP16workqueue_structP11work_struct+0x20> 24: 60 00 00 00 nop 28: 48 00 00 00 b 28 <._Z10queue_workP16workqueue_structP11work_struct+0x28> 2c: 48 00 00 00 b 2c <._Z10queue_workP16workqueue_structP11work_struct+0x2c> 30: 00 00 00 00 .long 0x0 34: 00 09 00 01 .long 0x90001 38: 80 00 00 00 lwz r0,0(0) [EMAIL PROTECTED]:~/tools.k42/powerpc/partDeb/os$ powerpc64-linux-g++ -v Reading specs from /opt/crosstool/powerpc64-linux/gcc-3.4.2-glibc-2.3.3/lib/gcc/powerpc64-linux/3.4.2/specs Configured with: /home/mostrows/tools/crosstool-0.28-rc37/build/powerpc64-linux/gcc-3.4.2-glibc-2.3.3/gcc-3.4.2/configure --target=powerpc64-linux --host=powerpc64-host_unknown-linux-gnu --prefix=/opt/crosstool/powerpc64-linux/gcc-3.4.2-glibc-2.3.3 --disable-multilib --with-sysroot=/opt/crosstool/powerpc64-linux/gcc-3.4.2-glibc-2.3.3/powerpc64-linux/sys-root --with-local-prefix=/opt/crosstool/powerpc64-linux/gcc-3.4.2-glibc-2.3.3/powerpc64-linux/sys-root --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atexit --enable-languages=c,c++ --enable-shared --enable-c99 --enable-long-long Thread model: posix gcc version 3.4.2 struct LinuxVPInfo_s { unsigned long physProc; }; typedef struct LinuxVPInfo_s LinuxVPInfo; extern LinuxVPInfo linuxVPInfo; struct cpu_workqueue_struct { int x; }; struct workqueue_struct { struct cpu_workqueue_struct cpu_wq[32]; }; struct work_struct { unsigned long pending; void (*func)(void *); void *data; void *wq_data; }; extern void __k42_spin_lock_irqsave(struct cpu_workqueue_struct* c, unsigned long *x); struct thread_info { int preempt_count; }; extern int test_and_set_bit(int x, unsigned long *y); #ifdef BUG static inline struct thread_info *current_thread_info(void) __attribute__((const)); static int smp_processor_id(void) __attribute__((pure)); #else static int smp_processor_id(void); static inline struct thread_info *current_thread_info(void); #endif static __inline__ int smp_processor_id(void) { return linuxVPInfo.physProc; } static inline struct thread_info *current_thread_info(void) { struct thread_info **ti; __asm__("mr %0,13" : "=r"(ti)); return *ti; } #define cti current_thread_info extern void lkBreakpoint(int line, const char* file, const char* fn); extern void __k42disable_preempt(); extern void __k42enable_preempt(); int queue_work(struct workqueue_struct *wq, struct work_struct *work) { unsigned long flags; int ret = 0; int cpu = ({ do { do { if (((cti()->preempt_count) & (((1UL << (8))-1) << 0))==0) { __k42disable_preempt(); (cti()->preempt_count)++; } else (cti()->preempt_count)++; } while (0); __asm__ __volatile__("": : :"memory"); } while (0); smp_processor_id(); }); struct cpu_workqueue_struct *cwq = wq->cpu_wq + cpu; if (!test_and_set_bit(0, &work->pending)) { do { if ((!work->wq_data)) { lkBreakpoint(103,"workqueue.C",(__func__)); } } while (0); work->wq_data = cwq; __k42_spin_lock_irqsave(cwq, &flags); ret = 1; } do { do { __asm__ __volatile__("": : :"memory"); do { if (((cti()->preempt_count) & (((1UL << (8))-1) << 0))==1) { (cti()->preempt_count)--; __k42enable_preempt(); } else (cti()->preempt_count)--; } while (0); } while (0); } while (0); return ret; } -- Summary: const/pure functions result in bad asm Product: gcc Version: 3.4.2 Status: UNCONFIRMED
[Bug rtl-optimization/17972] const/pure functions result in bad asm
--- Additional Comments From mostrows at watson dot ibm dot com 2004-10-13 21:45 --- Subject: Re: const/pure functions result in bad asm For starters, when compiling without -DBUG, the resulting assembly is much longer (correct assembly, with -DBUG below, that is without pure/const). Basically, most of the assembly code one would expect is missing. Further more, of the assembly output in my last mail, execution of that code leads to one of several infinite loops, all of which take the form of a branch instruction targeting itself. I expect that pure/const functions to not be called more than once, the problem is that the sample assembly in my original mail shows that the body of the function being compiler is pretty much all gone. On Wed, 2004-10-13 at 14:51 +, pinskia at gcc dot gnu dot org wrote: > --- Additional Comments From pinskia at gcc dot gnu dot org 2004-10-13 14:51 > --- > What do you think is wrong, attach the difference. Also const/pure functions can > changed so that they > are only called once. And since they are pure (or is it const) is known not to > access memory, the > barrier: > __asm__ __volatile__("": : :"memory"); > > does not make a difference. > -- Michal Ostrowski <[EMAIL PROTECTED]> 0: 7c 08 02 a6 mflrr0 4: fb 81 ff e0 std r28,-32(r1) 8: fb a1 ff e8 std r29,-24(r1) c: fb c1 ff f0 std r30,-16(r1) 10: fb e1 ff f8 std r31,-8(r1) 14: f8 01 00 10 std r0,16(r1) 18: f8 21 ff 61 stdur1,-160(r1) 1c: 7c 7d 1b 78 mr r29,r3 20: 7c 9e 23 78 mr r30,r4 24: 3b 80 00 00 li r28,0 28: 7d bf 6b 78 mr r31,r13 2c: e9 3f 00 00 ld r9,0(r31) 30: 88 09 00 03 lbz r0,3(r9) 34: 2f a0 00 00 cmpdi cr7,r0,0 38: 40 be 00 20 bne+cr7,58 <._Z10queue_workP16workqueue_structP11work_struct+0x58> 3c: 48 00 00 01 bl 3c <._Z10queue_workP16workqueue_structP11work_struct+0x3c> 40: 60 00 00 00 nop 44: e9 7f 00 00 ld r11,0(r31) 48: 81 2b 00 00 lwz r9,0(r11) 4c: 39 29 00 01 addir9,r9,1 50: 91 2b 00 00 stw r9,0(r11) 54: 48 00 00 18 b 6c <._Z10queue_workP16workqueue_structP11work_struct+0x6c> 58: 7d a9 6b 78 mr r9,r13 5c: e9 69 00 00 ld r11,0(r9) 60: 81 2b 00 00 lwz r9,0(r11) 64: 39 29 00 01 addir9,r9,1 68: 91 2b 00 00 stw r9,0(r11) 6c: e9 22 00 00 ld r9,0(r2) 70: eb e9 00 06 lwa r31,4(r9) 74: 7b e0 17 64 rldicr r0,r31,2,61 78: 7f e0 ea 14 add r31,r0,r29 7c: 38 60 00 00 li r3,0 80: 7f c4 f3 78 mr r4,r30 84: 48 00 00 01 bl 84 <._Z10queue_workP16workqueue_structP11work_struct+0x84> 88: 60 00 00 00 nop 8c: 2f a3 00 00 cmpdi cr7,r3,0 90: 40 9e 00 3c bne-cr7,cc <._Z10queue_workP16workqueue_structP11work_struct+0xcc> 94: e8 1e 00 18 ld r0,24(r30) 98: 2f a0 00 00 cmpdi cr7,r0,0 9c: 40 be 00 18 bne+cr7,b4 <._Z10queue_workP16workqueue_structP11work_struct+0xb4> a0: 38 60 00 67 li r3,103 a4: e8 82 00 08 ld r4,8(r2) a8: e8 a2 00 10 ld r5,16(r2) ac: 48 00 00 01 bl ac <._Z10queue_workP16workqueue_structP11work_struct+0xac> b0: 60 00 00 00 nop b4: fb fe 00 18 std r31,24(r30) b8: 7f e3 fb 78 mr r3,r31 bc: 38 81 00 70 addir4,r1,112 c0: 48 00 00 01 bl c0 <._Z10queue_workP16workqueue_structP11work_struct+0xc0> c4: 60 00 00 00 nop c8: 3b 80 00 01 li r28,1 cc: 7d a9 6b 78 mr r9,r13 d0: e9 29 00 00 ld r9,0(r9) d4: 81 69 00 00 lwz r11,0(r9) d8: 79 60 06 20 clrldi r0,r11,56 dc: 2f a0 00 01 cmpdi cr7,r0,1 e0: 40 be 00 18 bne+cr7,f8 <._Z10queue_workP16workqueue_structP11work_struct+0xf8> e4: 38 0b ff ff addir0,r11,-1 e8: 90 09 00 00 stw r0,0(r9) ec: 48 00 00 01 bl ec <._Z10queue_workP16workqueue_structP11work_struct+0xec> f0: 60 00 00 00 nop f4: 48 00 00 18 b 10c <._Z10queue_workP16workqueue_structP11work_struct+0x10c> f8: 7d a9 6b 78 mr r9,r13 fc: e9 69 00 00 ld r11,0(r9) 100: 81 2b 00 00 lwz r9,0(r11) 104: 39 29 ff ff addir9,r9,-1 108: 91 2b 00 00 stw r9,0(r11) 10c: 7f 83 e3 78 mr r3,r28 110: 38 21 00 a0 addir1,r1,160 114: e8 01 00 10 ld r0,16(r1) 118: 7c 08 03 a6 mtlrr0 11c: eb 81 ff e0 ld r28,-32(r1) 120: eb a1 ff e8 ld r29,-24(r1) 124: eb c1 ff f0 ld r30,-16(r1) 128: eb e1 ff f8 ld
[Bug rtl-optimization/17972] const/pure functions result in bad asm
--- Additional Comments From mostrows at watson dot ibm dot com 2004-10-13 23:11 --- Subject: Re: const/pure functions result in bad asm Here is simpler code that demonstrates the problem. Note, no loops involved. Further below is compilation and objdump with and without DBUG. struct thread_info { int preempt_count; }; #ifdef BUG static inline struct thread_info *cti(void) __attribute__((pure)); #else static inline struct thread_info *cti(void); #endif static inline struct thread_info *cti(void) { struct thread_info **ti; __asm__("mr %0,13" : "=r"(ti)); return *ti; } int fn() { int ret = 0; cti()->preempt_count++; ret = cti()->preempt_count++; return ret; } [EMAIL PROTECTED]:~/tools.k42/powerpc/partDeb/os$ powerpc64-linux-g++- c -o workqueue.o wq.C -O1 [EMAIL PROTECTED]:~/tools.k42/powerpc/partDeb/os$ powerpc64-linux-objdump -d workqueue.o workqueue.o: file format elf64-powerpc Disassembly of section .text: <._Z2fnv>: 0: 7d aa 6b 78 mr r10,r13 4: e9 6a 00 00 ld r11,0(r10) 8: 81 2b 00 00 lwz r9,0(r11) c: 39 29 00 01 addir9,r9,1 10: 91 2b 00 00 stw r9,0(r11) 14: e9 6a 00 00 ld r11,0(r10) 18: 81 2b 00 00 lwz r9,0(r11) 1c: 7d 23 07 b4 extsw r3,r9 20: 39 29 00 01 addir9,r9,1 24: 91 2b 00 00 stw r9,0(r11) 28: 4e 80 00 20 blr 2c: 00 00 00 00 .long 0x0 30: 00 09 00 00 .long 0x9 34: 00 00 00 00 .long 0x0 [EMAIL PROTECTED]:~/tools.k42/powerpc/partDeb/os$ powerpc64-linux-g++- c -o workqueue.o wq.C -O1 -DBUG [EMAIL PROTECTED]:~/tools.k42/powerpc/partDeb/os$ powerpc64-linux-objdump -d workqueue.o workqueue.o: file format elf64-powerpc Disassembly of section .text: <._Z2fnv>: 0: 48 00 00 00 b 0 <._Z2fnv> 4: 00 00 00 00 .long 0x0 8: 00 09 00 00 .long 0x9 c: 00 00 00 00 .long 0x0 -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17972