[Bug rtl-optimization/23726] Missed optimizations for divmod
--- Comment #8 from bjoern dot m dot haase at web dot de 2007-12-12 18:14 --- Created an attachment (id=14738) -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=14738action=view) patch My new analysis leads me to the result that the key problem of this missed optimization is a target problem: Presently we expand a divmod4 pattern that implements the support funciton calls directly. This pattern refers directly to hard registers. The resulting RTL is too complex for CSE and we don't identify this optimization. The attached patch uses the same RTL for the support function calls. Only this RTL is now generated only after combine by a define_insn_and_split pattern. The insn part of this pattern is valid only for pseudos so that until split. In order to assure this, I have added a new predicate. I have tested the patch against the atmega128 simulation target without regressions. 2007-12-11 Bjoern Haase [EMAIL PROTECTED] PR target/23726 * config/avr/predicates.md (pseudo_register_operand): Add new predicate for pseudos * config/avr/avr.md (divmodqi4,udivmodqi4): replace define_expand by define_insn_and_split, delay expansion of call patterns to split pass. (divmodhi4,udivmodhi4,divmodsi4,udivmodsi4): likewise. -- bjoern dot m dot haase at web dot de changed: What|Removed |Added Attachment #9665 is|0 |1 obsolete|| http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23726
[Bug middle-end/21990] Wrong code for 4.0 and head: Reload clobbers the frame pointer by using it as spill register without recognizing the clobbering
--- Comment #13 from bjoern dot m dot haase at web dot de 2006-09-19 20:16 --- Hello Eric, IIRC, the bug never was really resolved. The true place to fix the issue was, IMO, the most dreaded source file of the entire GCC source tree: reload. My now quite old patch tried to fix the immediate problem without touching reload and it used a fairly crude method by denying gcc to make use of Y in many situations. My test case generated code that was very difficult to handle by the register allocator. This code triggered the bug. Later on some change in some of the passes just before the 4.0.0 release removed the immediate problem. With 4.0 and afterwards I no longer succeeded to reproduce the bug: The reason might be, that the original reload bug was fixed. The reason might as well be that the reload bug is still there, but that it's no longer exposed due to some other modification in the compiler. The message is: There stand good chances that this bug is resolved, but I cannot prove it. In any case, I'd like to suggest *NOT* to make use of my old crude patch. IMO it's better to just hope that the problem is fixed. Until now, I never again stepped over this bug, so I have good confidence. HTH, Bjoern -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21990
[Bug c++/28718] Call to -lgcc added prior to user libraries
--- Comment #6 from bjoern dot m dot haase at web dot de 2006-09-06 16:51 --- To clear up the issues. 1.) libgcc provides a fp emulation based on compiled c functions that is to my very best knowledge untested for avr and extremely inefficient. 2.) avr-libc provides fp emulation that is hand-tuned assembly and on a less restrictive license than GPL. IIRC, the person who wrote them is no longer active in the field. 3.) the functions supplied by avr-libc are as basic as single float add 3, single float multiply 3, single float convert to integer 2 ... 4.) the hand-tuned assembly routines should really replace the libgcc ones, but that's not easily feasible. Partly due to licensing issues (modified free bsd for avr-libc), partly because it is very very difficult for us developers to get code integrated into mainline gcc. 5.) the externally supplied functions in libm need the hand-tuned assembly versions in order to operate properly and will failed with the untested libgcc variants. 5.) There is only one single libc and libm implementation available for avr that cooperates with gcc: avr-libc. The suggestion of Joerg Wunsch is, thus, in line with the needs of gcc users for the avr target. Bjoern. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28718
[Bug c++/4131] The C++ compiler don't place a const class object to .rodata section with non trivial constructor
--- Comment #17 from bjoern dot m dot haase at web dot de 2006-08-17 14:36 --- I have made a superficial analysis of the issue and would like to discuss at the end of this post a possible approach for resolving PR4131. The first observation is, that when one is having a code segment like /* Start */ #include complex using namespace std; typedef complexint ci; ci fa [3] = {ci(1,2), ci(-1,-2), ci(-42,+42)}; /* End */ the gimple optimizers will yield a very simple code sequence like /* Start of gimple code */ void __static_initialization_and_destruction_0(int, int) (__initialize_p, __priority) { bb 2: if (__initialize_p == 1) goto L0; else goto L2; L0:; if (__priority == 65535) goto L1; else goto L2; L1:; fa[0]._M_real = 1; fa[0]._M_imag = 2; fa[1]._M_real = -1; fa[1]._M_imag = -2; fa[2]._M_real = -42; fa[2]._M_imag = 42; L2:; return; } /* End of gimple code */ for the constructor function. Namely, I think that there is hope that one would grep the most important cases if one would try to replace some_direct_address_in_data_member = const_immediate_integer; expressions in the constructors by storing the value in the .data initializers. Namely, one would be placing the values in the initialization memory region and one would be deleting the assignment expressions. If at the end of this process, the constructor function would no longer contain references to the data structure, const qualified VAR_DECL could even be placed in .rodata. Thus, for fixing PR4131 I'd like to suggest to 1.) change the definition of the VAR_DECL so that DECL_INITIAL always points to a memory region holding initialization data. I.e. also for the case that we are having constructor code. Initially the memory region would be initialized to 0. 2.) In order to do this, one would need to replace the tests DECL_INITIAL(decl) == error_mark_node by tests against one of the unused flags in tree_decl_common that would be assigned a new meaning. E.g., one might take decl_flag_0 which seems to be unused so far for VAR_DECL.? 3.) One would then add a new tree optimiation pass that is located somewhere close to the end of tree optimization. There one would be looking for expressions like static_direct_address = const_immediate_value like in the sample gimple code above. One wold be inserting the values in the DECL_INITIAL(decl) memory region delete the corresponding expression statements in the constructor function. After making all the possible replacements, one would be re-visiting the code of the constructor function. If within the constructor code more complex references to the VAR_DECL remain, that could not be removed easily, one would set one second flag in tree_decl_common that states that the VAR_DECL needs to reside in ram, even if it's a const object. 4.) In var_asm.c one would be checking if DECL_INITIAL(decl) is completely zero. In this case it would go into .bss. If the initialization memory region is not zero altogether, one would place the object in .data . If it's a const object without the flag needs_to_reside_in_ram_even_if_const it would be placed into .rodata. IMO, the most complicated part of it would be the new tree pass 3.). Namely, one would need to find the approriate branch in void __static_initialization_and_destruction_0(int, int) (__initialize_p, __priority); , look for direct_address_expression = immediate_integer_value; type expression statements that are not residing inside loops or other complicated structures and delete them if possible. Then one would be looking if there is any reference to some VAR_DECL remaining in the FUNCTION_DECL of the constructor function. If there is still a reference, one would be setting the needs_to_reside_in_ram_even_if_const flag. Otherwise one would clear it. I would be willing to start with implementing 1,2 and 4, but I am quite sure that I would need help for 3. Bjoern. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4131
[Bug c++/4131] The C++ compiler don't place a const class object to .rodata section with non trival constructor
--- Comment #14 from bjoern dot m dot haase at web dot de 2006-08-10 19:33 --- I had already a look at the code in the cp directory. Unfortunately the documentation of the c++ front-end seems to be still worse than the docs on the back-ends (i.e. RTL). Either it is virtually inexisting or, I didn't find any hint on where to find it. Meanwhile I had a look at the tree dumps. Unfortunately, I didn't succeed in finding the initialization data for global plain old built-in type variables in the tree dumps. I have so far only seen the constructor code for initialization of class objects. AI'd at least like to have an idea of the complexity of the task. I have the impression that it might be way to difficult for me myself. But at least I'd like to try my very best to fix it before giving up. So any hint on a starting point for code reading and analysis would be appreciated. Bjoern. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4131
[Bug other/25035] [4.1/4.2 regression] libssp causes a failure with cross compilers
--- Comment #7 from bjoern dot m dot haase at web dot de 2006-05-15 17:25 --- Subject: Re: [4.1/4.2 regression] libssp causes a failure with cross compilers mmitchel at gcc dot gnu dot org wrote on Montag, 15. Mai 2006 00:26 : --- Comment #6 from mmitchel at gcc dot gnu dot org 2006-05-14 22:26 --- Where is the patch referenced in Comment #3? Here it is. It seems that Bugzilla does not permit me to add more comments. Bjoern. PATCH: libssp, fix AVR bootstrap failure for gcc From: Björn Haase [EMAIL PROTECTED] To: [EMAIL PROTECTED] Date: 30.12.2005 04:01 The code in /libssp/ssp.c implicitly assumes that the define symbols O_RDONLY and O_WRONLY exist. For the AVR target those are not defined in the header files included by ssp.c. Also the code does not work as expected for embedded targets that do not have files with the usual meaning. All of this causes a bootstrap failure for the AVR target. The patch adds #ifdefs as guards that first check for existing definitions of O_RDONLY and O_WRONLY before actually using them. After applying this change, bootstrap again succeeds. Bjoern. 2005-12-30  Bjoern Haase  [EMAIL PROTECTED]     * ssp.c: add #ifdef protections for symbols O_RDONLY and O_WRONLY Index: ssp.c === --- ssp.c       (revision 109170) +++ ssp.c       (working copy) @@ -67,6 +67,8 @@   if (__stack_chk_guard != 0)    return;  +#ifdef O_RDONLY +   fd = open (/dev/urandom, O_RDONLY);   if (fd != -1)    { @@ -77,6 +79,8 @@      return;    }  +#endif +   /* If a random generator can't be used, the protector switches the guard    to the terminator canary.  */   p = (unsigned char *) __stack_chk_guard; @@ -97,6 +101,8 @@    /* Print error message directly to the tty.  This avoids Bad Things    happening if stderr is redirected.  */ + +#ifdef O_WRONLY   fd = open (_PATH_TTY, O_WRONLY);   if (fd != -1)    { @@ -124,6 +130,7 @@      }     close (fd);    } +#endif   #ifdef HAVE_SYSLOG_H   /* Only send the error to syslog if there was no tty available.  */ -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25035
[Bug other/25035] [4.1/4.2 regression] Building an avr cross compiler fails (libssp)
--- Comment #3 from bjoern dot m dot haase at web dot de 2006-01-03 15:33 --- A patch for this issue is posted at the gcc-patches list and waits for review. The difficulty is that libssp silently assumes that unix-style stdio is available :-( which is not the case for embedded targets. Bjoern -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25035
[Bug inline-asm/24165] New: asm volatile instructions incorrectly scheduled.?
This bug report refers to the discussion on [bug #14616] definition of sei() in interrupts.h is faulty http://savannah.nongnu.org/bugs/?func=detailitemitem_id=14616 and the according discussion thread on [avr-libc-dev] http://lists.nongnu.org/mailman/listinfo/avr-libc-dev/ The issue is the question if for the following test case gcc is allowed to schedule or not allowed to schedule an asm volatile instruction (the text of this comment continues after the test case). For clarity the actual asm instructions have been replaced by comments illustrating the meaning: /* Start of test case */ typedef unsigned char uint8_t; typedef unsigned short int uint16_t; class class_with_volatile_data_structures { public: void __attribute__ ((always_inline)) wait_for_event (uint16_t event) { while (getval_protected () != event) ; }; private: uint16_t getval_protected (void) { uint16_t result; asm volatile (/* disable irq in cpu status */ : : ); result = class_local_data; asm volatile (/* enable irq */ : : ); return result; } volatile uint16_t class_local_data; }; class_with_volatile_data_structures object; void wait_for_42 (void) { object.wait_for_event (42); } /* End of test case */ Compiler output reads for (buggy ?) avr-g++ (GCC) 4.0.0 _Z11wait_for_42v: .L2: /* #APP */ /* disable irq in cpu status */ /* enable irq */ /* #NOAPP */ lds r24,object lds r25,(object)+1 sbiw r24,42 brne .L2 ret and for avr-g++ (GCC) 4.0.1 20050624 (prerelease) _Z11wait_for_42v: .L2: /* #APP */ /* disable irq in cpu status */ /* #NOAPP */ lds r24,object lds r25,(object)+1 /* #APP */ /* enable irq */ /* #NOAPP */ sbiw r24,42 brne .L2 ret . So for the more recent version the acess to the variable is protected and for the original first 4.0.0 release not. If asm volatile (/* disable irq in cpu status */ : : : memory); is used, the variable access was protected for both compiler versions. The important question for the avr-libc header files is now: According the specification, what is guaranteed by gcc concerning volatile asm statements? According to the spec The `volatile' keyword indicates that the instruction has important side-effects. GCC will not delete a volatile `asm' if it is reachable. (The instruction can still be deleted if GCC can prove that control-flow will never reach the location of the instruction.) In addition, GCC will not reschedule instructions across a volatile `asm' instruction. , I'd like to assume that the memory clobbers should not be required.? Bjoern -- Summary: asm volatile instructions incorrectly scheduled.? Product: gcc Version: 4.0.0 Status: UNCONFIRMED Severity: normal Priority: P1 Component: inline-asm AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bjoern dot m dot haase at web dot de CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: present on i586-linux, x86_64-linux and i586 cygwin GCC host triplet: present on i586-linux, x86_64-linux and i586 cygwin GCC target triplet: avr-*-* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24165
[Bug inline-asm/24165] asm volatile instructions incorrectly scheduled.?
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-10-01 18:46 --- The question merely is to find out if this is a bug / a bug of the documentation or no bug at all. After the fix for PR22000 the actual issue I had stepped over originally is indeed fixed: The protection of volatile *variables* now indeed works. The question that is still open, however, is: Is gcc generally allowed to schedule statements across asm volatile statements? E.g. look at an hypothetical example where someone would, e.g. like to disable irqs for speed reasons. asm volatile (/* disable irq */ : : );// 1 for (i=0; i 1000; i++)// 2 { a [i] *= 3; } asm volatile (/* enable irq */ : : ); // 3 After reading the specs In addition, GCC will not reschedule instructions across a volatile `asm' instruction., I still think that we either 1) still have a bug or 2) have a documentation that caused at least some people to understand it differently from than it was meant to be understood (saying this in order to avoid the terminus documentation bug). In case that scheduling is meant to be allowed if no volatile variable access is concerned, we probably would need to change the present implementation of irq disabling in the avr-libc's header files. Bjoern -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24165
[Bug rtl-optimization/23726] Missed optimizations for divmod
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-09-06 07:52 --- Do you know of any doc on how libcall block RTL is supposed to look like (except from e.g. code reading optabs.c)? -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23726
[Bug rtl-optimization/23726] Missed optimizations for divmod
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-09-06 12:59 --- I have done some code reading now and come to the following conclusion: When having an expanded sequence that provides one single result, libcall blocks are an appropriate method for making sure that a single-set insn that carries a REG_EQUAL note is *not* deleted too early. Libcall notes, however, do not provide a method so far for dealing with library calls or expanded sequences that yield *two* results. E.g. they are no solution for both, divmod4 on the one hand and arithmetic expanders doing subreg lowering and also yielding a CC on the other hand. In order to keep changes as small as possible, my suggestion is to change static void rest_of_handle_jump2 (void) such that it no longer calls delete_trivially_dead_insns () at it's very beginning. (I'd have posted a patch, if savannah.gnu.org is down right now.) IIUC that the trivially dead insn are in first line a performance issue because they need memory and handling that would otherwise not be necessary, my suggested change would not be too serious. delete_trivially_dead_insns () would be among the first things that is called in the pass that immediately follows jump2: The first cse pass. I'd appreciate comments on whether such trivially dead insn could prevent jump2 from realizing important optimization steps. Bjoern. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23726
[Bug rtl-optimization/23726] Missed optimizations for divmod
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-09-05 06:59 --- IMO, one would not be able to handle the issue by changing CSE. E.g. I presently don't see how to avoid using register notes for the following situation. Imagine a target not having DImode operations so that DImode arithmetic needs to be lowered to a sequence of SImode operations. Imagine further that after the sequence the condition code contains useful information that we want to re-use. E.g a minus:DI operation would be expanded into two parallels like (parallel[ (set (subreg:SI (reg:DI operand0) 0) minus:SI ((subreg:SI (reg:DI operand1) 0) (subreg:SI (reg:DI operand2) 0 (set (reg:CCmode CC) (generate borrow))]) (parallel[ (set (subreg:SI (reg:DI operand0) 4) minus:SI ( (extract_borrow:SI (reg:CCmode CC)) (minus:SI ((subreg:SI (reg:DI operand1) 4) (subreg:SI (reg:DI operand2) 4) (set (reg:CCmode CC) (generate condition code))]) In order to describe what information is written to the CC register in the second parallel, one needs to refer to both, input parameters of the parallel for the lower 4 bytes and input parameters for the higher 4 bytes. E.g. the information that CC contains the result of a compare of operand1 and operand2 could therefore not be expressed in the RTL! One could add, however, a third instruction to the expanded sequence reading (set (reg:CCmode CC) (reg:CCmode CC)) - WITH ATTACHED REGISTER NOTE is equal to compare:DI (operand1) (operand2) where the REG_EQUAL note gives the required information. IMO this is a general issue relevant for all targets that are aiming to do subreg lowering of arithmetic and logic operations at expand and that wish to recycle the condition codes generated. Of course 8 bit targets like AVR that need to use subreg lowering for almost everything will benefit most :-). I agree that generally register notes are kind of ugly. But for this kind of information, I think that they could be useful. Yours, Bjoern -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23726
[Bug middle-end/21990] Wrong code for 4.0 and head: Reload clobbers the frame pointer by using it as spill register without recognizing the clobbering
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-09-04 10:35 --- Indeed IMHO the problem stems from the patch: +2005-01-22 Roger Sayle [EMAIL PROTECTED] + + PR middle-end/19378 + * config/avr/avr.c (avr_hard_regno_mode_ok): Rewrite. + IMO the problem stems from the change - /* Reload can use r28:r29 for reload register and for frame pointer - in one insn. It's wrong. We must disable it. */ - if (mode != Pmode reload_in_progress frame_pointer_required_p () - regno = REG_Y (regno + GET_MODE_SIZE (mode)) = (REG_Y + 1)) + /* Otherwise disallow all regno/mode combinations that span r28:r29. */ + if (regno = (REG_Y + 1) (regno + GET_MODE_SIZE (mode)) = (REG_Y + 1)) return 0; Denis Chertykov's older version using frame_pointer_required_p () has now vanished. A problem during register allocation has been removed by Roger Sayle's patch. However, the old frame pointer bug has been re-introduced. My suggestion is to use the following implementation. (according patch to today's head attached) This patch has passed regression tests on head without new regressions on head on the c-testsuite for compilation and simulator excecution for the atmega128. I also verified on an old snapshot that had exposed PR21990 that this patch resolves PR21990. I'll post this message also on gcc-patches. Yours, Bjoern -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21990
[Bug middle-end/21990] Wrong code for 4.0 and head: Reload clobbers the frame pointer by using it as spill register without recognizing the clobbering
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-09-04 11:28 --- I just realized that the patch posted here had just posted had a = where should have been a for two comparisons. The patch on [EMAIL PROTECTED] is already correct. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21990
[Bug rtl-optimization/23726] New: Missed optimizations for divmod
Prologue: Purpose of this enhancement request is not only to resolve a missed optimization issue for the avr port. It aims to show up ways for resolving a general difficulty for the RTL optimizers that we are presently having for double-set insn: A difficulty that shows up when dealing with side effects of double-set RTL insns that produce unexpected useful results. IMO this is a general issue that will not only show up for the divmod4 patterns but will probably also be very important for the efficiency of code generated after the CCmode transition for targets where 1.) arithmetic or logic operations leave the CC register with useful information and 2.) arithmetic operations on SImode or DImode objects need to be lowered to a sequence of subreg operations. At the end of this bug report I'm about to ask for an early CSE pass or a small change of the jump2 pass. Text body: When having a function like uint32_t d,m; void foo (uint32_t z, uint32_t n) { d = z / n; m = z % n; } the avr port presently does not recognize that it needs to call the udivmodsi function only once. Assembly code generated reads, thus, movw r14,r22 movw r16,r24 movw r10,r18 movw r12,r20 call __udivmodsi4 sts d,r18 sts (d)+1,r19 sts (d)+2,r20 sts (d)+3,r21 movw r24,r16 movw r22,r14 movw r20,r12 movw r18,r10 call __udivmodsi4 sts m,r22 sts (m)+1,r23 sts (m)+2,r24 sts (m)+3,r25 (function prologue/epilogue stripped). The issue is that the CSE passes presently are not able to realize that the same result is calculated twice. The optimizers do, thus, not recognize that the first divmod4 call had a useful side-effect (the one that it calculates as well the mod). This could be fixed by attaching appropriate REG_EQUAL register notes to the insns that copy the results from the library call that reside in hard regs to target pseudos. The present implementation of the avr port does not generate such notes since it generates the calls explicitly and not by optabs.c (because the implementation knows exactly which registers will be clobbered by the library call). I will attach a patch that adds these required REG_EQUAL notes. The important issue is, that the REG_EQUAL note needs to refer to the original pseudos that were used as input parameters for the library call. Otherwise CSE will not realize the optimization opportunity. When using the attached patch, i.e. when adding the appropriate REG_EQUAL notes to the RTL, I veryfied that CSE is able to realize the optimization opportunity. I.e. one ends up with assembly output reading call __udivmodsi4 sts d,r18 sts (d)+1,r19 sts (d)+2,r20 sts (d)+3,r21 sts m,r22 sts (m)+1,r23 sts (m)+2,r24 sts (m)+3,r25 . The only difficulty is, that with the present optimization setup, the jump2 pass removes the insn that contain the useful REG_EQUAL notes for the unexpected useful side-effect because it correctly recognizes that it is trivially dead. For this reason, I had to place the first CSE pass before the jump2 pass in passes.c in order to get above results. I.e. my passes.c excerpt reads NEXT_PASS (pass_instantiate_virtual_regs); NEXT_PASS (pass_cse); NEXT_PASS (pass_jump2); instead of NEXT_PASS (pass_instantiate_virtual_regs); NEXT_PASS (pass_jump2); NEXT_PASS (pass_cse); . Epilogue: For this reason the attached patch could only resolve this issue IMO only if one of the following solutions is realized: 1.) the jump2 pass is changed such that it refrains from deleting trivially dead insn if they are containing REG_EQUAL notes because possibly it could be necessary to make them being seen at least once by a CSE pass. 2.) an earlier CSE pass is added to the optimizer flow. Possibly controlled by using a target-dependent flag. Yours, Bjoern -- Summary: Missed optimizations for divmod Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: enhancement Priority: P1 Component: rtl-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bjoern dot m dot haase at web dot de CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: unknown-x86_64-linux GCC host triplet: unknown-x86_64-linux GCC target triplet: avr-*-* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23726
[Bug rtl-optimization/23726] Missed optimizations for divmod
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-09-04 22:02 --- Created an attachment (id=9665) -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=9665action=view) Patch adding REG_EQUAL notes to the divmod4 expanders -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23726
[Bug middle-end/21990] Wrong code for 4.0 and head: Reload clobbers the frame pointer by using it as spill register without recognizing the clobbering
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-09-03 14:25 --- Hi, I now think that the true origin of this PR is related to the fact that for AVR we need *two* registers for holding the frame pointer: Recently, I have played around with modifying avr-gcc by choosing different registers for the frame pointer and the stack pointer. Namely I have experimented with the calling convention used by the IAR system (use two seperate stacks for the return addresses and data). It turned out that the stack pointer and frame pointer register number during my experiments that was used by gcc was not 28 but 29! Possibly one would have to re-investigate avr_hard_regno_mode_ok(REGNO, MODE) function in avr.c that implements the HARD_REGNO_MODE_OK target macro. IIUC, there have been a couple of problems in the past with similar results: clobbered frame pointer. Maybe the fact that this bug does not show up frequently has to do with that the constraints for the Y register implemented in avr_hard_regno_mode_ok are fairly restrictive right now, so that the register allocator and reload almost never are tempted to use it. Important information would be wether avr_hard_regno_mode_ok is evaluated dynamically for each function. In this case one could probably prevent clobbering of the frame pointer by denying any mode in regs 28 and 29 in case that a frame pointer is needed. This way one possibly could also lift the present restriction that only pointers (Pmode objects) may be held in the y register. So I think that we are right now having a hidden problem in avr-gcc that shows up only in very rare occasions. Most probably it's also present in the 3.4.4 series. Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21990
[Bug middle-end/21990] Wrong code for 4.0 and head: Reload clobbers the frame pointer by using it as spill register without recognizing the clobbering
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-08-20 13:49 --- I have re-investigated this bug today and observed that it no longer appears in mainline. It is also absent in today's cvs state of the 4.0 branch. Dunno whether the original problem has been fixed or whether something else has changed such that the bug is no longer exposed: Since the register allocator now seems to be smarter on both branches than it used to be, the function exposing the bug no longer needs the frame pointer. Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21990
[Bug middle-end/21990] Wrong code for 4.0 and head: Reload clobbers the frame pointer by using it as spill register without recognizing the clobbering
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-07-29 20:06 --- Hi, a couple of weeks after identifying this issue, I have continued working with 4.0.0. I never observed a similar failure in our production code. The issue seems to be strongly linked to the constraint requiring simultaneously two operands with the + modifier. The back-end, itself never generates such a constraint pattern right now. It seems to me that the real problem has to do with register constraint matching. I personally do not have sufficient knowledge so that I would consider to start thinking about daring to eventually touch reload.c and comrades. On the other hand, I still feel uneasy about this bug. For this reason I am thinking about a workaround solely within the back-end. While refraining from requiring that code that contains the mentioned difficult constraits compiles, I presently think that one might already be better of with a situation where it triggers an ICE instead of generating wrong code. IMO, a possible workaround might be to simply disable within the machine description the move patterns that meet the two following two conditions 1.) the move uses a memory reference stored in Y 2.) the move target is the Y register itself My hope is that in absence of this move pattern, reload will no longer attempt to use the frame pointer register Y as spill register. This workaround certainly would be far from ideal, but better than nothing. I'd appreciate comments on this issue. Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21990
[Bug target/19885] [4.0/4.1 Regression] avr dwarf-2 support is broken for head 4.0/4.1
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-07-27 06:18 --- What's the plan? I'd like to see it in CVS. The patch I posted on gcc-patches in may 05 is already approved (it's a straight-forward change) by Richard Henderson. Unfortunately, I don't have write access to CVS. So, IIUC, the patch presently still waits to be committed. Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19885
[Bug target/19885] [4.0/4.1 Regression] avr dwarf-2 support is broken for head 4.0/4.1
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-07-27 06:21 --- Sorry: Let me correct myself. I just see that You have been refering to an earlier revision of the patch that I had posted on this bugzilla entry. This is not the current state of the patch. The approved fix for this PR is posted in gcc-patches and not here! Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19885
[Bug target/19885] [4.0/4.1 Regression] avr dwarf-2 support is broken for head 4.0/4.1
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-07-27 18:30 --- Bjorn, do you have a copyright assignment filed with the FSF? Yes. It took quite a while but since a couple of weeks the paperwork is finished. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19885
[Bug target/19885] [4.0/4.1 Regression] avr dwarf-2 support is broken for head 4.0/4.1
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-06-27 17:09 --- Subject: Re: [4.0/4.1 Regression] avr dwarf-2 support is broken for head 4.0/4.1 Hi Andrew, One question about gcc policy: There exists a patch resolving 19885 since a couple of weeks. The latest revision had been approved by Richard Henderson. Could you tell me what to do in order to get such a patch integrated into gcc? The present maintainers of the AVR port seem to be very busy at the moment. Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19885
[Bug middle-end/21990] New: Wrong code for 4.0 and head: Reload clobbers the frame pointer by using it as spill register without recognizing the clobbering
Hi, I have observed a wrong code bug that I judge to be so serious that IMHO one should discourage use of the avr port for 4.x.x until it is resolved. Unfortunately the bug showed up in a deeply embedded code segment of *really* confidential code owned by my employer. I unfortunately cannot pass the test case I am having to the public. I am working hard for reproducing the bug in a non-confidential stripped file. Meanwhile, I have the following diagnosis: ( I, know that this will be difficult, but maybe someone could never the less give me an indication already on this base.) 1.) Background info for those not too familiar with the AVR port: AVR uses the hard reg 28 (also called Y-Register) as frame pointer, when necessary. If a pseudo happens to end up on a stack slot and needs to be loaded into a register of class POINTER_REG (one of the hard regs 26 (reg X), 28 (reg Y) or 30(reg Z)), reload sometimes generates code where the frame pointer 28 (reg Y) itself is used as spill register. GCC, however, still uses the Y register as frame pointer and does not recognize that it no longer points to the stack. 2.) Description of the bug: Excerpt from the debugging dump originating from the reload pass for my testcase (test.c.23.greg): Reload 0: reload_in (HI) = (reg/v/f:HI 65 [ pointer_to_next_C ]) reload_out (HI) = (reg/v/f:HI 65 [ pointer_to_next_C ]) POINTER_REGS, RELOAD_OTHER (opnum = 1) reload_in_reg: (reg/v/f:HI 65 [ pointer_to_next_C ]) reload_out_reg: (reg/v/f:HI 65 [ pointer_to_next_C ]) reload_reg_rtx: (reg:HI 28 r28) The corresponding asm output reads (Problem case plus part of the prologue for illustration. descriptive comments added by me): ;; Section of the prologue allocating space on the stack for a HImode ;; variable. in r28,__SP_L__ in r29,__SP_H__ sbiw r28,2 in __tmp_reg__,__SREG__ cli out __SP_H__,r29 out __SREG__,__tmp_reg__ out __SP_L__,r28 ;; Stack pointer and frame pointer r28:r29 are now increased by 2 for ;; making place for a pointer variable. Y+1 and Y+2 point to the ;; lsb and the msb of this pointer variable. ... some complicated code ... ;; Now the variable on the stack slot is needed in a spill register ;; of class pointer registers (i.e. r26-r31). ;; GCC chooses to use the Frame pointer r28 as spill register. ;; r28 is overwritten by the value of the variable on the stack ;; (GCC uses special pattern for loading Y from an address Y is ;; pointing to by use of the tmp reg. ldd __tmp_reg__,Y+1 ldd r29,Y+2 mov r28,__tmp_reg__ ; Now the frame pointer no longer points to the stack! ; Use Y for accessing the memory the pointer variable on the stack ; points to. ld r18,Y+ ld r19,Y+ ld r20,Y+ ld r21,Y+ ;; GCC now assumes that it could write Y back to the stack ;; by the following two commands. BUG!!! Also all of the subsequent ;; Accesses to the stack by the frame pointer will fail. std Y+2,r29 std Y+1,r28 The bug exists already in January 05 and in today's head 4.1. It was present in all of the intermediate snapshots I have analyzed so far. I was able to reproduce the problem identically on a cygwin-woe200 host, an i386-linux host and an amd64-linux host. I am working hard to reduce the test case so that it will be possible for me to post it here. Meanwhile, I'd appreciate very much any advice on where to look for the origin. Yours, Björn -- Summary: Wrong code for 4.0 and head: Reload clobbers the frame pointer by using it as spill register without recognizing the clobbering Product: gcc Version: 4.0.0 Status: UNCONFIRMED Severity: critical Priority: P2 Component: middle-end AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bjoern dot m dot haase at web dot de CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: cygwin-x86 and linux-x86 GCC host triplet: cygwin-x86 and linux-x86 GCC target triplet: avr-*-* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21990
[Bug middle-end/21990] Wrong code for 4.0 and head: Reload clobbers the frame pointer by using it as spill register without recognizing the clobbering
-- What|Removed |Added CC||ericw at evcohs dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21990
[Bug target/19087] Overflowed address in dwarf debug line information
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-05-30 21:16 --- Hi, as a step towards resolving PR19885: After looking a bit into the code of other ports, I found out, that switching avr-gcc to the 4-byte dwarf convention should not be complicated at all. It seems that the only thing to be done is add the lines #undef DWARF2_ADDR_SIZE #define DWARF2_ADDR_SIZE 4 to avr.h . This is how it works for HC12, ip2k and other ports that override the default definition of 2 for these targets. For AVR, most probably, one should then expect the occurence of trailing 0x80 bytes indicating the memory space. Torleif has already prepared a new parser dll for avrstudio that is supposed to run with 4-Byte dwarf debugging info. Quote (Torleif Sandes): My dwarf parser is composed of several dlls. The one governing low-level dwarf access (such as the size of pointers), is called libdwarf.dll and is a windows port of an LGPL licensed library. I have built this library with the required change and put it at http://www.atmel.no/beta_ware/as4/elfdwarfparser/libdwarf.dll; I will unfortunately not have time to look into details during the next two weeks. So in case that someone else volunteers (best would be someone who has access to a atmega128 board). Before implementing such a change, in case that it passes tests of course, one should probably carefully think about how to manage the transition: There is possibly quite a couple of object code out there that still has 2-Byte dwarf information included. I am mainly thinking about the WOE users working with avrstudio and Eric's precompiled winavr toolchain. Maybe one should do implement a simultaneous change of type For avrstudio 3.4.1 always use winavr 6.2.8 or later. Possibly one should consider to implement the 2-Byte - 4-Byte switching at the next 4.0 revision.? Yours, Bjoern -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19087
[Bug target/19087] Overflowed address in dwarf debug line information
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-05-30 21:40 --- OK, sorry for this, but I just realized that Darcy Watkins has made a couple of almost exactly identical observations. Did not review all of the more recent comments. In case that the only remaining problem turns out to be the trailing 0x80 that indicate the memory space, one way to handle it could be to change the way the asm output is generated. I.e. there is a quite easy method for forcing gcc to generate .long ((lable_referenced_within_the_dwarf_section) 0x0001) instead of .long lable_referenced_within_the_dwarf_section . This way, when assemling one could mask out leading bits that possibly could irritate avrstudio. However, IMO, the better way would be to teach avrstudio simply to ignore the bits that are known to be not relevant. Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19087
[Bug debug/19885] [4.0/4.1 Regression] avr dwarf-2 support is broken for head 4.0/4.1
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-05-06 07:44 --- It seems that when disabling two sanity checks, one again gets head to compile also with dwarf2 support. The following patch might be a workaround until the problem is solved by addressing it's roots. Yours, Björn Index: simplify-rtx.c === RCS file: /cvsroot/gcc/gcc/gcc/simplify-rtx.c,v retrieving revision 1.237 diff -u -r1.237 simplify-rtx.c --- simplify-rtx.c 13 Apr 2005 19:47:28 - 1.237 +++ simplify-rtx.c 6 May 2005 07:41:08 - @@ -3737,8 +3737,8 @@ gcc_assert (innermode != BLKmode); gcc_assert (outermode != BLKmode); - gcc_assert (GET_MODE (op) == innermode - || GET_MODE (op) == VOIDmode); +// gcc_assert (GET_MODE (op) == innermode +// || GET_MODE (op) == VOIDmode); gcc_assert ((byte % GET_MODE_SIZE (outermode)) == 0); gcc_assert (byte GET_MODE_SIZE (innermode)); Index: varasm.c === RCS file: /cvsroot/gcc/gcc/gcc/varasm.c,v retrieving revision 1.498 diff -u -r1.498 varasm.c --- varasm.c13 Apr 2005 14:34:13 - 1.498 +++ varasm.c6 May 2005 07:41:17 - @@ -2212,7 +2212,7 @@ gcc_assert (!i); } - gcc_assert (!force); + //gcc_assert (!force); return false; } -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19885
[Bug target/17994] avr-gcc does not output a dwarf2 .debug_frame section
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-05-06 13:59 --- Hi, I have been reviewing PR19885 and come to the following conclusions: 1.) As expected, Torleif is right: I can confirm that the problem exists, 2.) it should, however, probably be called rather a request for enhancement than a bug: Beside call stack information the debugging info should be ok in principle. 3.) There seems to be only one little part missing in order to add the call stack information as well: The back-end needs to provide the information at which memory address the debugger could localize the return address. This would require to implement the target hook INCOMING_RETURN_ADDR_RTX and use the RTX_FRAME_RELATED_P predicate for all of the prologue/epilogue insn. I think the best way to address this issue would be to resolve this issue simultaneously when switching from asm-prologue/epilogue to RTL-prologue/epilogue. Since Andy Hutchinson is just working on this issue, we might soon have a solution. Hopefully :-). Would be very helpfull to have call stack info in avrstudio. Yours, Bjoern P.S.: I hope you will not be flaming me for adding you on the CC list. :-) Just thought that you might be interrested since I know you are working on the prologue/epilogue issue. -- What|Removed |Added CC||hutchinsonandy at netscape ||dot net http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17994
[Bug target/19087] Overflowed address in dwarf debug line information
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-05-06 14:12 --- Hi Torleif, I have just had a look at PR19885 and I am having one additional question: IIUC, the lable references, that eventually cause the overflow problems refer to memory in form of byte addresses and not word addresses: I.e. the offsets and address information you are finding in the elf files all are byte addresses. Am I right? In the asm outputs I have investigated so far, I realized that for the lable references in the dwarf sections avr-gcc is allocating two bytes only. So in case that these two bytes are filled with byte addresses instead of word addresses, it is obvious that an overflow could not be avoided. The cleanest solution then would be to redefine the debugging format such that within the debugging sections for the dwarf symbols, gcc allocates four bytes for the pointers. I fear, however, that this would be a major challenge since one would probably need to rewrite a considerable portion of the dwarf-output-genenerator in a target-specific fashion. If I'm not too wrong, we probably won't have a short term solution for this PR. Anyway, I think that this bug should be marked as NEW. Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19087
[Bug c/21077] New: Missed optimization
When reworking the testsuite setup for AVR, I have stepped of the following missed optimization: The avr target does fail for the following test case (gcc.c-torture/execute/20020720-1.c) with reporting a link error: Question: After filing this bug report should I post a patch marking the test case as xfail ? /* Copyright (C) 2002 Free Software Foundation. Ensure that fabs(x) 0.0 optimization is working. Written by Roger Sayle, 20th July 2002. */ extern void abort (void); extern double fabs (double); extern void link_error (void); void foo (double x) { double p, q; p = fabs (x); q = 0.0; if (p q) link_error (); } int main() { foo (1.0); return 0; } #ifndef __OPTIMIZE__ void link_error () { abort (); } #endif -- Summary: Missed optimization Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bjoern dot m dot haase at web dot de CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: i686-linux GCC host triplet: i686-linux GCC target triplet: avr-*-* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21077
[Bug c/21078] New: Testsuite reports excecution failure for gcc.c-torture/excecute/20010122.c for some optimization levels
Test case gcc.c-torture/excecute/20010122-1.c fails the execution tests for optimization levels -O1, -O2, -O3-g and -Os while passing for -O0. Tests were run with simulavr for the atmega128. I do not have a clear opinion about what is going wrong. The fact that the test passes for -O0 is reason for being suspicious, however. Yours, Björn -- Summary: Testsuite reports excecution failure for gcc.c- torture/excecute/20010122.c for some optimization levels Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bjoern dot m dot haase at web dot de CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: i586-linux GCC host triplet: i586-linux GCC target triplet: avr-*-* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21078
[Bug c/21079] New: avr-gcc lacks support for builtin ffs function
tests gcc.c-torture/excecute/ffs-1 and -2 fail since neither libgcc nor libgcc2 provide support for the excpected builtin function ffs. -- Summary: avr-gcc lacks support for builtin ffs function Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bjoern dot m dot haase at web dot de CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: i586-linux GCC host triplet: i586-linux GCC target triplet: avr-*-* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21079
[Bug c/21080] New: Excecution test failure for avr for pr17377 test case.
Excecution of gcc.c-torture/excecute/pr17377.c fails for optimization level -O0 and passes for other optimizer switches: Somewhat suspicious. -- Summary: Excecution test failure for avr for pr17377 test case. Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bjoern dot m dot haase at web dot de CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: i586-linux GCC host triplet: i586-linux GCC target triplet: avr-*-* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21080
[Bug target/21079] avr-gcc lacks support for builtin ffs function
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-04-17 23:07 --- So probably the best thing to do now would probably be to 1.) mark the test cases as xfail and 2.) write an enhancement request for avr-libc.? -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21079
[Bug c/20738] New: bootstrap failure for avr on head 4.1
Hi, when checking out the gcc tree this morning for a clean rebuild and regular testsuite run, I observed that bootstrap failed. It seems that it is related to some preprocessor issue: 1.) Problem occures when assembling the libgcc library. First failing operation is /home/bmh/gnucvs/head/build/./gcc/xgcc -B/home/bmh/gnucvs/head/build/./gcc/ -B/usr/local/avr/bin/ -B/usr/local/avr/lib/ -isystem /usr/local/avr/include -isystem /usr/local/avr/sys-include -O2 -DIN_GCC -DCROSS_COMPILE -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -DDF=SF -Dinhibit_libc -mcall-prologues -g -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED -Dinhibit_libc -I. -I. -I../../gcc/gcc -I../../gcc/gcc/. -I../../gcc/gcc/../include -I../../gcc/gcc/../libcpp/include -DL_mulqi3 -xassembler-with-cpp -c ../../gcc/gcc/config/avr/libgcc.S -c libgcc/./_mulqi3.o and the error message reads ../../gcc/gcc/config/avr/libgcc.S: Assembler messages: ../../gcc/gcc/config/avr/libgcc.S:72: Error: suffix or operands invalid for `clr' ../../gcc/gcc/config/avr/libgcc.S:72: Error: no such instruction: `clear result' ../../gcc/gcc/config/avr/libgcc.S:74: Error: no such instruction: `sbrc r24,0' ../../gcc/gcc/config/avr/libgcc.S:75: Error: too many memory references for `add' ../../gcc/gcc/config/avr/libgcc.S:76: Error: too many memory references for `add' ../../gcc/gcc/config/avr/libgcc.S:76: Error: no such instruction: `shift multiplicand' ../../gcc/gcc/config/avr/libgcc.S:77: Error: no such instruction: `breq __mulqi3_exit' ../../gcc/gcc/config/avr/libgcc.S:77: Error: no such instruction: `while multiplicand!=0' ../../gcc/gcc/config/avr/libgcc.S:78: Error: no such instruction: `lsr r24' ../../gcc/gcc/config/avr/libgcc.S:79: Error: no such instruction: `brne __mulqi3_loop' ../../gcc/gcc/config/avr/libgcc.S:79: Error: no such instruction: `exit if multiplier=0' ../../gcc/gcc/config/avr/libgcc.S:81: Error: too many memory references for `mov' ../../gcc/gcc/config/avr/libgcc.S:81: Error: no such instruction: `result to return register' make[2]: *** [libgcc/./_mulqi3.o] Fehler 1 make[1]: *** [stmp-multilib] Fehler 2 make: *** [all-gcc] Fehler 2 2.) My impression is that the problem is possibly related to some preprocessor issue because when executing /home/bmh/gnucvs/head/build/./gcc/xgcc -B/home/bmh/gnucvs/head/build/./gcc/ -B/usr/local/avr/bin/ -B/usr/local/avr/lib/ -isystem /usr/local/avr/include -isystem /usr/local/avr/sys-include -O2 -DIN_GCC -DCROSS_COMPILE -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -DDF=SF -Dinhibit_libc -mcall-prologues -g -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED -Dinhibit_libc -I. -I. -I../../gcc/gcc -I../../gcc/gcc/. -I../../gcc/gcc/../include -I../../gcc/gcc/../libcpp/include -DL_mulqi3 -xassembler-with-cpp -c ../../gcc/gcc/config/avr/libgcc.S -c libgcc/./_mulqi3.s in order to have a look at the assembly output, no file _mulqi3.s is generated. Instead the output of the preprocessor is written to stdout. Yours, Björn -- Summary: bootstrap failure for avr on head 4.1 Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: critical Priority: P2 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bjoern dot m dot haase at web dot de CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: linux-i686 GCC target triplet: avr-unkown-none http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20738
[Bug target/20738] bootstrap failure for avr on head 4.1
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-04-03 14:04 --- Hi, I have so far found out, that the problem I have observed comes from the configure process. For a reason, I have not figured out so far, my newly built xgcc did try to pipe the asm sources through the host-as instead of the target-as. So I am now almost convinced that it is not a real bug but a local problem on my machine. I'll be going to try the same thing on another machine tomorrow morning. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20738
[Bug target/20288] AVR assignment of a value through a 16 bit pointer generates out of order code
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-03-04 19:38 --- In reply to comment #10. I agree with you Jörg, it is not a dramatic loss if you have a bit less efficient use of volatile pointers :-) and IMHO anybody in the avr community could live with it. I think it's possibly rather a question of style. I'd like to suggest that the explicit use of a macro while sticking to the standard convention for use of the volatile keyword might make it more transparent *why* and *that* an explicit treatment is required for 16 bit registers. Imagine the case of a person who is reading code written by someone else. Just seeing the volatile keyword would not make the possible danger clear. Maybe the volatile solution makes it easier for some programers and I agree with anybody that using macros tends to turn the code uglier. Possibly, however, there is the danger that one makes things easier than they are in fact: With either approach, the user will be required to be avare of the possible problem and would have to handle the code accordingly. My personal opinion is: If there is a pitfall with 16 bit registers, write code that names it by it's real name. Anyway I could also live with a solution that patches the compiler. Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20288
[Bug target/20288] AVR assignment of a value through a 16 bit pointer generates out of order code
-- What|Removed |Added CC||bjoern dot m dot haase at ||web dot de http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20288
[Bug target/20296] Speeding up small interrupts on avr
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-03-04 19:51 --- Hi, IMHO everyone working on the avr back-end is aware of this problem. The difficulty is, that the present architecture of the avr back-end does not easily permit to improve this case: Every instruction pattern (like multiply two 16 bit integers or sign-extend a 16 bit variable to 32 bits) presently is free to assume that may overwrite or change r0 and r1 unless it leaves the __zero_reg__ with 0 after finishing it's task. Resolving this issue, IMHO, would require a major refactoring of the back-end. ... IIUC the keyword is replace all of the more complex instruction patterns by RTL expressions. I suggest to mark this bug as desired enhancement. Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20296
[Bug c/20222] [AVR] Double load of volatile operand
-- What|Removed |Added CC||bjoern dot m dot haase at ||web dot de http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20222
[Bug target/20288] AVR assignment of a value through a 16 bit pointer generates out of order code
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-03-03 22:21 --- Hi, in order to completely resolve this issue, IIUC, one would have to sacrifice the post-increment addressing modes. In case of the X-Register, forcing the high-byte first rule allways would result in much less efficient code. For this reason, I think that enforcing the high-byte first rule always is not a good solution. There has been the suggestion to 1.) distinguish between pointer variables that are marked volatile and pointer variables that are not declared volatile and 2.) disable all post increment operations for such variables. In my opinion, this would not really be a clean solution, since IIUC, volatile uint16_t pointer is meant to be used for a pointer that, e.g. could be altered by an IRQ function, and the key-word volatile not meant to be used for classifying the variable the pointer is refering to. In fact, in the specific case no one would require the pointer no to be hold in a register variable. I also disagree that accessing IO-Memory by use of pointers is a very common case. Possibly it is a useful solution if one does not know at compile time which register will actually be in use. But I'd like to suggest, that this is sufficiently infrequently used to justify to require that sw developers use a special solution for this case, like the following: In order to enforce the byte-ordering, one could define an inline-asm instruction like #define WRITE_WORD_TO_MEMORY_MSB_FIRST(pointer_to_iom,value_to_be_stored) \ asm volatile (/* Storing %A1:%B1 to the memory address %A0:%B0 is pointing to, high byte first */\n\t \ st z+1,%B1 \n\t \ st z,%A1 \n\t \ : \ : z (pointer_to_iom), \ r (value_to_be_stored) ); \ Such an inline directive could be defined in one of the header files of avr-libc. Anybody that *really* could not avoid to access IOM-Space by pointers then would have the opportunity to make use of this makro. Summing up, my suggestion is not to change the compiler in order to avoid code-size and performace regressions. Instead, I consider it to be best to clearly document the issue and to provide a suitable macro definition in one of the avr-libc headers. Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20288
[Bug middle-end/18887] [4.0/4.1 Regression] libgcc2.h Improperly determines required built-in function size requirements.
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-02-28 21:49 --- Hi, since this bug has been fixed by a patch of Roger Sayles a couple of weeks ago, I suggest to mark it as fixed. Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18887
[Bug target/20243] static initialization .data redundantly copied to ram prior to use.
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-02-28 21:58 --- I think the key problem is, that C language permits you to pass pointers to your static const data structures to other functions. Possibly functions that are not located within the same source file. While functions whithin the source file that defines the const data structures could in principle know that these data should be located in program memory and that they should be accessed by using lpm instructions, I do not see how to pass this knowledge to externally defined functions. Only solution in my opinion would be to define different classes of pointers. Yours, Björn. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20243
[Bug middle-end/19920] [4.0 Regression] build broken on several targets due to recent 'DC' type update to libgcc2
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-02-15 23:24 --- FYI: I have just tested the patch posted in http://gcc.gnu.org/ml/gcc-patches/2005-02/msg00858.html After applying this patch, the build for the avr target again succeeds. Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19920
[Bug middle-end/19920] [4.0 Regression] build broken on several targets due to recent 'DC' type update to libgcc2
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-02-14 22:21 --- FYI, I have just posted a RFC on gcc@gcc.gnu.org concerning implementation of a target-specific mode-substitution convention. Hopefully someone competent will answer. Yours, Björn. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19920
[Bug target/19920] avr target build broken by recent 'DC' type update to libgcc2
-- What|Removed |Added CC||bjoern dot m dot haase at ||web dot de http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19920
[Bug target/19920] [4.0 Regression] avr target build broken by recent 'DC' type update to libgcc2
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-02-12 20:15 --- I can confirm that the bug is present also for an intel-based linux system. In my opinion it is absolutely not useful to define a DF mode type on the AVR platform. Both excecution time and memory footprint would probably so large that they will not be of any relevance. What one could possibly consider IMHO is the implementation of a 3-Byte floating-point type with a 16 bit mantissa. Is there any know workaround so far? Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19920
[Bug target/19920] [4.0 Regression] avr target build broken by recent 'DC' type update to libgcc2
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-02-12 21:08 --- After changing line #96 in libgcc2.h from typedef _Complex float DCtype __atribute__ ((mode (DC))); to typedef _Complex float DCtype __atribute__ ((mode (SC))); it is again possible to build the avr port. In my opinion the best method for dealing with this problem would be to make sure some way that the #define symbols from the target header file are already known when compiling libgcc2 prior to including libgcc2.h. Then one would have the possibility to bracked line #96 within #ifndef #endif statements. Yours, Björn. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19920
[Bug debug/19885] [4.0 Regression] avr dwarf-2 support is broken for head 4.0
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-02-11 19:00 --- I have tried to trace back the date when dwarf2 support startet to fail. So far I have found out that it was broken already at december 5th 2004. Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19885
[Bug debug/19885] [4.0 Regression] avr dwarf-2 support is broken for head 4.0
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-02-11 19:04 --- Subject: Re: [4.0 Regression] avr dwarf-2 support is broken for head 4.0 Am Freitag, 11. Februar 2005 00:36 schrieb ericw at evcohs dot com: --- Additional Comments From ericw at evcohs dot com 2005-02-10 23:36 --- As an aside, DWARF2 is about to become the default debugging information used in WinAVR, for both Atmel's AVR Studio and for use with avr-gdb/avr-insight. So this one is crucial for having a successful 4.0.0 release for the avr target. Hi Eric, brief question: As far as I know you have monitored Thorleif Sandes attempts of getting the dwarf support working for avr-studio. Do you remember that it was necessary at the time to implement bug-fixes for getting it functional for gcc 3.4. ? Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19885
[Bug c/19885] New: dwarf-2 support is broken for head 4.0.0
I have just been checking out the entire gcc tree (head 4.0.0) and run a clean rebuild: cd build_directory rm -r * ../gcc/configure --target=avr --prefix=/home/bmh --disable-nls --with-dwarf2 --enable-languages=c make all (Note that I have used --with-dwarf2!) What I am getting is :-( : ../../gcc/gcc/libgcc2.c:535: internal compiler error: in simplify_subreg, at simplify-rtx.c:3671 Please submit a full bug report, with preprocessed source if appropriate. See URL:http://gcc.gnu.org/bugs.html for instructions. make[2]: *** [libgcc/./_muldi3.o] Fehler 1 make[2]: Leaving directory `/home/bmh/gnucvs/head/build/gcc' make[1]: *** [stmp-multilib] Fehler 2 make[1]: Leaving directory `/home/bmh/gnucvs/head/build/gcc' make: *** [all-gcc] Fehler 2 When building head 4.0.0 without --with-dwarf2, the build succeeds. I have made the same observation with last week's snapshot on another build system. Unfortunate thing is: dwarf-2 is the main debugging format for all the windows users that use the Atmel debugger (avr-gdb is so slow under cygwin that it is almost not useful to use it). Yours, Björn -- Summary: dwarf-2 support is broken for head 4.0.0 Product: gcc Version: 4.0.0 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bjoern dot m dot haase at web dot de CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: i686-linux GCC host triplet: i686-linux GCC target triplet: avr-unknown-none http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19885
[Bug middle-end/19885] [4.0 Regression] avr dwarf-2 support is broken for head 4.0
-- What|Removed |Added CC||ericw at evcohs dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19885
[Bug middle-end/19885] [4.0 Regression] avr dwarf-2 support is broken for head 4.0
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-02-10 23:45 --- Created an attachment (id=8167) -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=8167action=view) Preprocessed source of the libgcc functions This is the command I have used for generating the attached preprocessed file: /home/bmh/gnucvs/head/build_dwarf/gcc/xgcc -B/home/bmh/gnucvs/head/build_dwarf/gcc/ -B/home/bmh/avr/bin/ -B/home/bmh/avr/lib/ -isystem /home/bmh/avr/include -isystem /home/bmh/avr/sys-include -O2 -DIN_GCC -DCROSS_COMPILE -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -DDF=SF -Dinhibit_libc -mcall-prologues -g -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED -Dinhibit_libc -I. -I.-I../../gcc/gcc -I../../gcc/gcc/. -I../../gcc/gcc/../include -I../../gcc/gcc/../libcpp/include -DL_muldi3 -E ../../gcc/gcc/libgcc2.c -o failure.E -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19885
[Bug middle-end/19885] [4.0 Regression] avr dwarf-2 support is broken for head 4.0
-- What|Removed |Added CC||schlie at comcast dot net http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19885
[Bug target/18251] unable to find a register to spill in class `POINTER_REGS'
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-02-09 20:27 --- The bug seems still to be present in head 4.0.0. The failing example could be stripped down a little bit further: // Begin of sample code unsigned long semaphore_create (unsigned long name, unsigned long count, unsigned long attribute_set, unsigned long *id ); struct termios { unsigned int c_iflag; unsigned int c_oflag; unsigned int c_cflag; unsigned int c_lflag; unsigned char c_cc[19]; }; typedef struct termios_callbacks { int (*firstOpen) (int major, int minor, void *arg); int (*lastClose) (int major, int minor, void *arg); int (*pollRead) (int minor); } termios_callbacks; void *calloc (unsigned int __nmemb, unsigned int __size); struct termios_rawbuf { char *theBuf; int Head; int Tail; int Size; int Semaphore; }; struct termios_tty { struct termios_tty *forw; struct termios_tty *back; unsigned long major; unsigned long minor; unsigned long isem; unsigned long osem; char *cbuf; int ccount; int cindex; int column; int read_start_column; struct termios termios; struct termios_rawbuf rawInBuf; struct termios_rawbuf rawOutBuf; termios_callbacks device; unsigned int flow_ctrl; unsigned int lowwater, highwater; unsigned int rxTaskId; unsigned int txTaskId; int tty_rcvwakeup; }; unsigned long termios_open (unsigned long major, unsigned long minor, struct termios_tty *tty, const termios_callbacks * callbacks) { unsigned long sc; { tty = calloc (1,0); if (tty == ((void *) 0)) return 0; tty-rawInBuf.Size = 128; tty-minor = minor; tty-major = major; sc = semaphore_create (0, 1, 0, 0 ); tty-device = *callbacks; tty-lowwater = tty-rawInBuf.Size * 1 / 2; } } // End of sample code -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18251
[Bug target/18251] unable to find a register to spill in class `POINTER_REGS'
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-02-09 23:14 --- Maybe this will help to localize the origin of the bug a bit better: I have made the observation that the presence of the bug strongly depends on the size of the memory footprint of the structs. Maybe there is a problem when the stack frame starts to grow beyond the 128 Byte boundary. Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18251
[Bug target/19293] avr-gcc crashes when using shifts with negative shift count
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-01-19 21:25 --- Hi, here is the changed patch for avr.c . I hope that it is now compliant to the gcc coding standards. I however did not understand what you have meant with this hunk adds spurious whitespace. Yours, Björn Index: avr.c === RCS file: /cvsroot/gcc/gcc/gcc/config/avr/avr.c,v retrieving revision 1.108.4.3 diff -U10 -r1.108.4.3 avr.c --- avr.c 28 Sep 2004 01:13:55 - 1.108.4.3 +++ avr.c 19 Jan 2005 21:19:49 - @@ -3288,20 +3288,27 @@ const char * ashrqi3_out (rtx insn, rtx operands[], int *len) { if (GET_CODE (operands[2]) == CONST_INT) { int k; if (!len) len = k; + /* Test for illegal or strange shift count. */ + if ( (INTVAL (operands[2]) = 0 ) || ( INTVAL (operands[2]) 7) ) + { + *len = 0; + return ; + } + switch (INTVAL (operands[2])) { case 1: *len = 1; return AS1 (asr,%0); case 2: *len = 2; return (AS1 (asr,%0) CR_TAB AS1 (asr,%0)); @@ -3357,20 +3364,27 @@ { if (GET_CODE (operands[2]) == CONST_INT) { int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL); int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]); int k; int *t = len; if (!len) len = k; + + /* Test for illegal or strange shift count. */ + if ( (INTVAL (operands[2]) = 0) || (INTVAL (operands[2]) 15) ) +{ + *len = 0; + return ; +} switch (INTVAL (operands[2])) { case 4: case 5: /* XXX try to optimize this too? */ break; case 6: if (optimize_size) @@ -3517,21 +3531,27 @@ const char * ashrsi3_out (rtx insn, rtx operands[], int *len) { if (GET_CODE (operands[2]) == CONST_INT) { int k; int *t = len; if (!len) len = k; - + + /* Test for illegal or strange shift count. */ + if ((INTVAL (operands[2]) = 0) || (INTVAL (operands[2])31)) +{ + *len = 0; + return ; +} switch (INTVAL (operands[2])) { case 8: { int reg0 = true_regnum (operands[0]); int reg1 = true_regnum (operands[1]); *len=6; if (reg0 = reg1) return (AS2 (mov,%A0,%B1) CR_TAB AS2 (mov,%B0,%C1) CR_TAB @@ -3633,20 +3653,27 @@ const char * lshrqi3_out (rtx insn, rtx operands[], int *len) { if (GET_CODE (operands[2]) == CONST_INT) { int k; if (!len) len = k; + /* Test for illegal or not useful shift count. */ + if ( (INTVAL (operands[2]) = 0) | (INTVAL (operands[2]) 7) ) +{ + *len = 0; + return ; +} + switch (INTVAL (operands[2])) { default: *len = 1; return AS1 (clr,%0); case 1: *len = 1; return AS1 (lsr,%0); @@ -3719,29 +3746,36 @@ insn, operands, len, 1); return ; } /* 16bit logic shift right ((unsigned short)x i) */ const char * lshrhi3_out (rtx insn, rtx operands[], int *len) { if (GET_CODE (operands[2]) == CONST_INT) -{ +{ int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL); int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]); int k; int *t = len; if (!len) len = k; + /* Test for illegal or not useful shift count. */ + if ((INTVAL (operands[2]) = 0) || (INTVAL (operands[2]) 15)) + { + *len = 0; + return ; + } + switch (INTVAL (operands[2])) { case 4: if (optimize_size scratch) break; /* 5 */ if (ldi_ok) { *len = 6; return (AS1 (swap,%B0) CR_TAB AS1 (swap,%A0) CR_TAB @@ -3977,20 +4011,27 @@ const char * lshrsi3_out (rtx insn, rtx operands[], int *len) { if (GET_CODE (operands[2]) == CONST_INT) { int k; int *t = len; if (!len) len = k; + + /* Test for illegal or not useful shift counts. */ + if ((INTVAL (operands[2]) = 0) || (INTVAL (operands[2]) 31)) +{ + *len = 0; + return ; +}; switch (INTVAL (operands[2])) { case 8: { int reg0 = true_regnum (operands[0]); int reg1 = true_regnum (operands[1]); *len = 4
[Bug middle-end/18887] [4.0 Regression] libgcc2.h Improperly determines required built-in function size requirements.
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-01-18 21:40 --- Indeed the problem seems to be related to a problem during the reload pass. I now think, that I have found a solution for the original problem that needs a tiny change in the back-end. DJ Delorie wrote me: avr bug - GENERAL_REGS allows $r24 to contain a DImode, but you cannot access the 5th byte of it via a subreg, because HARD_REGNO_MODE_OK doesn't permit QImodes in $r29. This disqualifies GENERAL_REGS. Since anyway any useful function using long longs will require the frame pointer, there is (in my opinion) no use for DI objects in the upper register range. The following patch restricts DI objects to registers with smaller indices. When using this patch, I succeed in building the gcc-4.0.0 snapshot dating from the 12th of december 04 without problems. This snapshot previously did not compile with the symptoms mentioned above. For a later head revision, unfortunately something else and independent seems to be broken. I'll check today's head this evening and report on this, as soon as I have analyzed this more in detail. Patch that needs to be applied to /gcc/config/avr/avr.c Reported differences are differences against the 4.0.0-20041212 snapshot. --- avr.c.old 2005-01-18 22:24:44.942273520 +0100 +++ avr.c.new 2005-01-18 22:19:19.0 +0100 @@ -5116,40 +5116,47 @@ register number REGNO. On the enhanced core, anything larger than 1 byte must start in even numbered register for movw to work (this way we don't have to check for odd registers everywhere). */ int avr_hard_regno_mode_ok (int regno, enum machine_mode mode) { /* Bug workaround: recog.c (peep2_find_free_register) and probably a few other places assume that the frame pointer is a single hard register, so r29 may be allocated and overwrite the high byte of the frame pointer. Do not allow any value to start in r29. */ if (regno == REG_Y + 1) return 0; /* Reload can use r28:r29 for reload register and for frame pointer in one insn. It's wrong. We must disable it. */ if (mode != Pmode reload_in_progress frame_pointer_required_p () regno = REG_Y (regno + GET_MODE_SIZE (mode)) = (REG_Y + 1)) return 0; + if (mode == DImode) + { if ( (regno 20) (!(regno 1)) ) + return 1; + else + return 0; + } + if (mode == QImode) return 1; /* if (regno 24 !AVR_ENHANCED) return 1;*/ return !(regno 1); } /* Returns 1 if X is a valid address for an I/O register of size SIZE (1 or 2). Used for lds/sts - in/out optimization. Add 0x20 to SIZE to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */ int avr_io_address_p (rtx x, int size) { return (optimize 0 GET_CODE (x) == CONST_INT INTVAL (x) = 0x20 INTVAL (x) = 0x60 - size); } /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2. */ -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18887
[Bug target/19293] avr-gcc crashes when using shifts with negative shift count
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-01-18 23:27 --- Hi, I have just stepped over a patch suggested by Bernardo Innocenti in order to treat the case of shift_count == 0 correctly. My presently suggested patch (above) only treats the case of negative shift counts. I did not realize that the case of 0 also is buggy. So for treating the shifting problem comprehensively, one should combine both. This could be done by replacing the checks for 0 in my patch by checks for = 0. Yours, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19293
[Bug target/19329] [3.4 Regression] Miscompilation with bitfields
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-01-18 23:35 --- I have the impression that Bug #19329 is the same as bug #19239 (as one might think already when looking at the similarity of the numbers :-) ) 19239, howeverr so far has addressed the issue of *negative* and other really illegal shift counts. In a patch treating both problems correctly, one should possibly implement both: Treatment of negative and other illegal shift counts and positive shift counts. Yours, Björn. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19329
[Bug target/19329] [3.4 Regression] Miscompilation with bitfields
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-01-18 23:43 --- Sorry for this: In my posting above, I have misspelled the bug number. I wanted to refer you to bug #19293 (and not #19239, luckyly the number of possible permutations is countable). By the way at #19293, you will also find a patch suggestion that should be eaysily adapted to all of the present shifting problems. Yours again, Björn -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19329
[Bug c/19293] New: avr-gcc crashes when using shifts with negative shift count
avr-gcc crashes with an internal compiler error when shift operations with negative shift count are used, e.g. a -13. Error message is negative instruction length, probably since the expression used for calculating the instruction length (c-code) assumes the shift count to be a positive number. Test cases known to fail are, e.g. . gcc.c-torture/compile/20020710-1 20021119-1 20021123-4 920626-1 930621-1 Problem is present in 4.0 and I expect it to exist in all the previous releases. (compare the test report in [EMAIL PROTECTED] Björn. -- Summary: avr-gcc crashes when using shifts with negative shift count Product: gcc Version: 4.0.0 Status: UNCONFIRMED Severity: minor Priority: P2 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bjoern dot m dot haase at web dot de CC: gcc-bugs at gcc dot gnu dot org GCC target triplet: avr-*-* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19293
[Bug target/19293] avr-gcc crashes when using shifts with negative shift count
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-01-06 17:35 --- It seems that the standard says that shift operations with negative shift count are supposed to yield an unspecified result. Is there some more specific convention for gcc on how to behave in these cases? Otherwise the only thing to do would be to fix the instruction length calculation in the back-end code. Copy from C-Standards description: http://www.open-std.org/jtc1/sc22/open/n2794/n2794.txt 6.5.7 Bitwise shift operators Syntax [#1] shift-expr: additive-expr shift-expr additive-expr shift-expr additive-expr Constraints [#2] Each of the operands shall have integer type. Semantics [#3] The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19293
[Bug target/19293] avr-gcc crashes when using shifts with negative shift count
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-01-06 18:57 --- If it would be OK for GCC to simply ignore negative constant shift counts, the following patch would do. I have tested this with the test suite for gcc-3.4.3 . Unfortunately avr-gcc is still broken on head, so I could not test it properly for 4.0 . I, however, expect no difficulties either. regards, Björn Index: avr.c === RCS file: /cvsroot/gcc/gcc/gcc/config/avr/avr.c,v retrieving revision 1.108.4.3 diff -c -1 -0 -r1.108.4.3 avr.c *** avr.c 28 Sep 2004 01:13:55 - 1.108.4.3 --- avr.c 6 Jan 2005 18:44:28 - *** *** 3287,3307 const char * ashrqi3_out (rtx insn, rtx operands[], int *len) { if (GET_CODE (operands[2]) == CONST_INT) { int k; if (!len) len = k; ! switch (INTVAL (operands[2])) { case 1: *len = 1; return AS1 (asr,%0); case 2: *len = 2; return (AS1 (asr,%0) CR_TAB AS1 (asr,%0)); --- 3287,3312 const char * ashrqi3_out (rtx insn, rtx operands[], int *len) { if (GET_CODE (operands[2]) == CONST_INT) { int k; if (!len) len = k; ! ! if ( (INTVAL(operands[2]) 0) || (INTVAL(operands[2]) 7) ) !{ /* illegal shift count */ ! *len = 0; ! return ; !} switch (INTVAL (operands[2])) { case 1: *len = 1; return AS1 (asr,%0); case 2: *len = 2; return (AS1 (asr,%0) CR_TAB AS1 (asr,%0)); *** *** 3357,3376 --- 3362,3387 { if (GET_CODE (operands[2]) == CONST_INT) { int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL); int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]); int k; int *t = len; if (!len) len = k; + + if ( (INTVAL(operands[2]) 0) || (INTVAL(operands[2]) 15) ) + { /* illegal shift count */ + *len = 0; + return ; + } switch (INTVAL (operands[2])) { case 4: case 5: /* XXX try to optimize this too? */ break; case 6: if (optimize_size) *** *** 3517,3537 const char * ashrsi3_out (rtx insn, rtx operands[], int *len) { if (GET_CODE (operands[2]) == CONST_INT) { int k; int *t = len; if (!len) len = k; ! switch (INTVAL (operands[2])) { case 8: { int reg0 = true_regnum (operands[0]); int reg1 = true_regnum (operands[1]); *len=6; if (reg0 = reg1) return (AS2 (mov,%A0,%B1) CR_TAB AS2 (mov,%B0,%C1) CR_TAB --- 3528,3553 const char * ashrsi3_out (rtx insn, rtx operands[], int *len) { if (GET_CODE (operands[2]) == CONST_INT) { int k; int *t = len; if (!len) len = k; ! ! if ((INTVAL(operands[2]) 0) || (INTVAL(operands[2])31)) ! { /* illegal shift count */ ! *len = 0; ! return ; ! } switch (INTVAL (operands[2])) { case 8: { int reg0 = true_regnum (operands[0]); int reg1 = true_regnum (operands[1]); *len=6; if (reg0 = reg1) return (AS2 (mov,%A0,%B1) CR_TAB AS2 (mov,%B0,%C1) CR_TAB *** *** 3632,3652 const char * lshrqi3_out (rtx insn, rtx operands[], int *len) { if (GET_CODE (operands[2]) == CONST_INT) { int k; if (!len) len = k; ! switch (INTVAL (operands[2])) { default: *len = 1; return AS1 (clr,%0); case 1: *len = 1; return AS1 (lsr,%0); --- 3648,3673 const char * lshrqi3_out (rtx insn, rtx operands[], int *len) { if (GET_CODE (operands[2]) == CONST_INT) { int k; if (!len) len = k; ! if ( (INTVAL(operands[2]) 0) || (INTVAL(operands[2]) 7) ) ! { /* illegal shift count */ ! *len = 0; ! return ; ! } ! switch (INTVAL (operands[2])) { default: *len = 1; return AS1 (clr,%0); case 1: *len = 1; return AS1 (lsr,%0); *** *** 3719,3747 insn, operands, len, 1); return ; } /* 16bit logic shift right
[Bug middle-end/18887] [4.0 Regression] libgcc2.h Improperly determines required built-in function size requirements.
--- Additional Comments From bjoern dot m dot haase at web dot de 2005-01-05 19:47 --- Hi, I have the impression that the origin of the bug is not in first line linked to a wrong assignment of types in libgcc2. I doubt whether the problem is not linked to a problem during reload. I.e. I assume that reload presently is no longer able to reload any long long objects properly for the avr target. This is something that used to work in 3.4.3. and seemingly also older revisions of head 4.0 up to about beginning of December. In order to confirm this, I have used a workaround by commenting out the code of the hand full of libgcc2 functions that caused the problems. I.e. I have modified them so that they essentially do nothing. You will have to remove 3 function bodies, IIRC. Of course this will result in compiler output that does not execute properly if these functions ever happen to be used. But at compile time a problem should never should show up. I.e. using empty functions in libgcc2 should never inhibit a proper reload. After building the compiler this way, I have started the test suite and observed about 150 regressions in comparison to 3.4.3. All of them showed up at compile time. They all issued an error message of the type /home/bmh/gnucvs/head/gcc/gcc/testsuite/gcc.c-torture/execute/961122-1.c:11 internal compiler error: in find_valid_class, at reload.c:719 When checking gcc-3.4.3, I have obtained a PASS for these test cases. Namely 961122-1.c compiles correctly with gcc-3.4.3. There are quite a number of files generating this error. All files that I have investigated had made use of long longs. If it helps, I will post a complete list of them. c-torture/execute/961122-1.c is a fairly typical example and I'd suggest to concentrate on it first, since it is also a fairly short test case. If I'm not making a mistake 961122-1.c does also does not make any use of the conversion functions that I had to mutilate in order to make avr-gcc bootstrap. I also have verified that gcc-3.4.3 indeed has made use of the full DI modes. I.e. 3.4.3 has generated code with 8 Byte - objects. Maybe one should rather look a bit closer at the changes in reload.c . Yours, Björn -- What|Removed |Added CC||bjoern dot m dot haase at ||web dot de http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18887