sh64-elf build failure because of lib1funcs-Os-4-200.asm
Hi Joern, Hi Alex, The sh64-elf toolchain currently fails to build from the mainline GCC sources because it contains unsupported SH assembler: ./xgcc \ -B./ \ -B/usr/local/sh64-superh-elf/bin/ \ -isystem /usr/local/sh64-superh-elf/include \ -isystem /usr/local/sh64-superh-elf/sys-include \ -L.../sh64-superh-elf/ld \ -c \ -o sdivsi3_i4i-Os-4-200.o \ -DL_sdivsi3_i4i \ -x assembler-with-cpp .../gcc/config/sh/lib1funcs-Os-4-200.asm .../gcc/config/sh/lib1funcs-Os-4-200.asm: Assembler messages: .../gcc/config/sh/lib1funcs-Os-4-200.asm:277: Error: unknown opcode .../gcc/config/sh/lib1funcs-Os-4-200.asm:278: Error: unknown opcode [snip] I am not sure how this should be fixed however. Should the functions in lib1funcs-02-4-200.asm be protected by another #ifdef so that they are not built for this target ? Or maybe the rules in t-sh need to be updated to include an architecture selection switch ? (eg -m2a-single ?) Cheers Nick
Re: sh64-elf build failure because of lib1funcs-Os-4-200.asm
Hi Joern, I have a patch for it, but due to problems with our hardware, newlib, and issues with the way the linux libgcc is built, I have not been able to test the patch satisfactorily. I can confirm that the patch allows GCC to build for both an sh64-elf and an sh-elf target. I am now running regressions tests to see if it introduces any new problems. (I doubt that it will, but it never hurts to check). Cheers Nick
Bug building target libiberty for mips64vrel-elf toolchain
Hi Eric, Hi Richard, We recently ran across an ICE building a target libiberty for one of the multilibs of the mips64vrel-elf toolchain: .../libiberty/regex.c: In function 'byte_re_match_2_internal': .../libiberty/regex.c:7481: error: insn does not satisfy its constraints: (insn 5211 1697 1699 173 .../libiberty/regex.c:6589 (set (reg:SI 5 $5) (lo_sum:SI (reg/f:SI 1104) (symbol_ref:SI ("byte_reg_unset_dummy") [flags 0x6] ))) 204 {*lowsi_mips16} (nil) (expr_list:REG_EQUAL (symbol_ref:SI ("byte_reg_unset_dummy") [flags 0x6] ) (nil))) .../libiberty/regex.c:7481: internal compiler error: in reload_cse_simplify_operands, at postreload.c:393 Please submit a full bug report, with preprocessed source if appropriate. See http://gcc.gnu.org/bugs.html> for instructions. make[3]: *** [regex.o] Error 1 make[3]: Leaving directory `.../mips64vrel-elf/mips64vrel-elf/mips16/libiberty' This problem does not appear to affect other mips toolchains, but that may just be a multilib issue. I found a simple workaround for the problem: Index: gcc/config/mips/mips.c === --- gcc/config/mips/mips.c (revision 123322) +++ gcc/config/mips/mips.c (working copy) @@ -2269,8 +2269,11 @@ mips_legitimize_const_move (enum machine /* Split moves of symbolic constants into high/low pairs. */ if (splittable_symbolic_operand (src, mode)) { - emit_insn (gen_rtx_SET (VOIDmode, dest, mips_split_symbol (dest, src))); - return; + if (! TARGET_MIPS16) + { + emit_insn (gen_rtx_SET (VOIDmode, dest, mips_split_symbol (dest, src))); + return; + } } if (mips_tls_operand_p (src)) But I am pretty sure that this is the wrong solution. Since I am not a MIPS expert however I am punting this problem to you guys. :-) Cheers Nick
Re: Bug building target libiberty for mips64vrel-elf toolchain
Hi Richard, But I am pretty sure that this is the wrong solution. Since I am not a MIPS expert however I am punting this problem to you guys. :-) Yeah, I'm afraid it's the wrong solution. ;) Thought so :-) I gather from the insn above that a use of the GP pseudo register has been introduced during reload. At first blush, I think the fix is to make mips_split_symbol move (const (unspec [(const_int 0)] UNSPEC_GP)) into "temp" when no_new_pseudos. I tried doing this but I could not find a way to make it work. :-( But then I am not as clued up on this stuff as you guys. I might have time to try a fix this weekend. Please feel free to file a bug report and assign it to [EMAIL PROTECTED] I have created a PR (31388) but I do not have the authority to assign it you. Cheers Nick
GCC testsuite failures for mips64vrel-elf toolchain with -mlong64 -mgp32
Hi Eric, Hi Richard, I need your brains... The mips64vrel-elf toolchain is showing a lot of unexpected failures in the gcc testsuite (and g++ testsuite) for multilibs which use -mlong64 and -mgp32 together. For example the first one I came across is this: % ... mips64vrel-elf/gcc/xgcc ... -mlong64 -mgp32 ... gcc.c-torture/compile/20010327-1.c gcc.c-torture/compile/20010327-1.c:12: error: initializer element is not constant Or how about this one: % ... mips64vrel-elf/gcc/xgcc ... gcc.c-torture/compile/mipscop-4.c ... -mlong64 -mgp32 gcc.c-torture/compile/mipscop-4.c:4: error: register specified for 'c3r1' isn't suitable for data type The problems all seem to extend from the fact that a long is forced to be 64-bits but the general purpose registers are 32-bits. What I am not sure about is whether this is a generic bug in gcc somewhere (that assumes that a long will fit into a register) or whether there is something mips specific about the problem. (One thing telling gcc that a long is 32-bits and another thing tell it that they are 64-bits). What do you think ? Cheers Nick
mips64vrel-elf code gen bug
Hi Eric, Hi Richard, We have received a bug report against the mips64vrel-elf toolchain which is reproducible with the mainline sources. Since it (appears to) involve MIPS code generation and I know almost nothing about MIPS I am passing it on to you in the hopes that you might be able to fix it, or at least point me in the right direction. To reproduce the problem compile the attached two files with: % mips64vrel-elf 128201-1.c 128201-2.c -Tddb.ld -mabi=32 -march=vr5000 Then run it with the simulator: % mips64vrel-elf-run a.out FPR 4 (format single) being accessed with format double - setting to unknown (PC = 0xa0100364) -2.33 (-2.33) Note the error message from the simulator. The problem appears to be $f4 register used by the sub.d instruction. I suspect, but do not know for sure, that this is somehow connected with the store_df_high pattern in mips.md. Any clues or solutions ? Cheers Nick 128201-files.tar.bz2 Description: BZip2 compressed data
Fix gcc bootstrap problem
Hi Guys, I ran a x86 hosted bootstrap of the mainline gcc and binutils sources over the weekend and it failed with this error report: bfd/elflink.c: In function 'elf_fixup_link_order': bfd/elflink.c:9893: error: type mismatch in unary expression long unsigned int int D.16764 = -D.16763 Not exactly the most helpful error report in the world, but with a set of tree dumps and a bit of guesswork I tracked the problem down to this line: offset &= ~(bfd_vma)((1 << s->alignment_power) - 1); Gcc has worked out that "~ foo - 1" is the same as "- foo" but it has failed to appreciate that the (bfd_vma) cast should apply to the constant 1 as well as the expression (1 << s->alignment_power). So it thinks that the expression above is equivalent to (paraphrasing slightly): unsigned long int D.16764; signed int D.16763; D.16763 = 1 << s->alignment_power; D.16764 = - D.16763; offset = offset & D.16764; Hence it is complaining about the unary conversion of D.16763 into D.16764. I think that this is probably a gimplification bug but that is beyond me, so I have Cc'ed this email to the gcc bugs list. In the meantime however I have hit on a simple workaround: offset &= (bfd_vma)~((1 << s->alignment_power) - 1); (ie moving the cast to a (bfd_vma) to before the inversion operator). This works in the bootstrap although it would fail if the alignment power is sufficiently large to cause the left shift to overflow an integer. So I am going to check in a variant of this change: offset &= (bfd_vma)~((1L << s->alignment_power) - 1L); which I think should satisfy everyone. I will also check the patch into the 2.18 branch. Cheers Nick PS. The bootstrap still does not succeed with this patch installed. It fails later on with this error report: i386-dis.c:4213: error: type mismatch in pointer plus expression struct dis386 * struct dis386[8] * unsigned int dp = &float_reg + D.7721 I am looking into this now. bfd/ChangeLog 2007-08-20 Nick Clifton <[EMAIL PROTECTED]> * elflink.c (elf_fixup_link_order): Rewrite conversion of s->alignment_power into an offset mask in order to avoid a gcc error message. Index: bfd/elflink.c === RCS file: /cvs/cvsfiles/devo/bfd/elflink.c,v retrieving revision 1.95 diff -c -3 -p -r1.95 elflink.c *** bfd/elflink.c 19 Aug 2007 17:49:44 - 1.95 --- bfd/elflink.c 20 Aug 2007 07:39:30 - *** elf_fixup_link_order (bfd *abfd, asectio *** 9965,9971 for (n = 0; n < seen_linkorder; n++) { s = sections[n]->u.indirect.section; ! offset &= ~(bfd_vma)((1 << s->alignment_power) - 1); s->output_offset = offset; sections[n]->offset = offset; offset += sections[n]->size; --- 9965,9971 for (n = 0; n < seen_linkorder; n++) { s = sections[n]->u.indirect.section; ! offset &= (bfd_vma)~((1L << s->alignment_power) - 1L); s->output_offset = offset; sections[n]->offset = offset; offset += sections[n]->size;
RFC: Bogus gimplification type mismatch error ?
Hi Guys, I tried bootstrapping the mainline gcc sources over the weekend, using the current mainline binutils sources in an integrated source tree. The bootstrap failed with a problem in bfd/elflink.c which I have already reported and worked around. The build then failed later on with this error message: opcodes/i386-dis.c:4213: error: type mismatch in pointer plus expression struct dis386 * struct dis386[8] * unsigned int dp = &float_reg + D.7721 I tracked this down to this line in i386-dis.c: dp = &float_reg[floatop - 0xd8][modrm.reg]; where the variables involved are typed as: const struct dis386 *dp; static const struct dis386 float_reg[][8] = { To me this looks wrong. Gcc appears to have converted multiple deferences of a multidimensional array into a single dereference of the multidimensional array. I found a workaround by explicitly performing the two dereferences one after another like this: { typedef struct dis386 eight_dis386 [8]; const eight_dis386 *dp8; dp8 = float_reg + (floatop - 0xd8); dp = dp8[modrm.reg]; } But before I check such a patch in I would like to know if the gcc error message is really correct, or if I have run across a gimplification bug. Cheers Nick
Re: RFC: Bogus gimplification type mismatch error ?
Hi Andrew, As mentioned before this error message is really an internal error, we really should be fixing GCC and not changing binutils. And I already mentioned this is most likely PR 22371 and that you should be filing bug reports about these two errors/ICEs. I have filed PR 33122 to cover this problem and added a comment to PR 22371 mentioning that 33122 might be a duplicate. Cheers Nick
unsigned long long bitfield RTL generation bug (H8 specific ?)
Hi Jeff, Hi Kazu, We have run across an H8300 RTL generation bug which I think might be generic, rather than specific to the H8300, although it may only trigger for small targets. Given the following source file: struct fields { unsigned long long u2 : 33; } flags; int main (void) { flags.u2 = 0x1ULL; return 0; } Compile with an h8300-elf toolchain. (I used -O2 but this is not necessary in order to reproduce the bug). If you run this inside GDB and break on the return you will find that flags.u2 only contains 0x1! Looking at the RTL generated in the expand pass (105r.expand) shows that something very weird is going on. (RTL trimmed slightly for this email): ;; flags.u2 = 1 (insn 11 (set (reg:HI 19) (const:HI (plus:HI (symbol_ref:HI ("flags")) (const_int 2 (insn 12 (set (reg:HI 20) (mem:HI (reg:HI 19))) (insn 13 (set (reg:HI 21) (ior:HI (reg:HI 20) (const_int 0x7fff))) (insn 14 (set (mem:HI (reg:HI 19)) (reg:HI 21)) (insn 15 (set (reg:HI 22) (const:HI (plus:HI (symbol_ref:HI ("flags")) (const_int 4 (insn 16 (set (reg:QI 23) (mem:QI (reg:HI 22))) (insn 17 (set (reg:QI 24) (ior:QI (reg:QI 23) (const_int 0x80))) (insn 18 (set (mem:QI (reg:HI 22)) (reg:QI 24)) (insn 19 (set (reg:HI 25) (symbol_ref:HI ("flags"))) (insn 20 (set (reg:HI 26) (mem:HI (reg:HI 25))) (insn 21 (set (reg:HI 27) (and:HI (reg:HI 26) (const_int 0x8000))) (insn 22 (set (mem:HI (reg:HI 25)) (reg:HI 27)) (insn 23 (set (reg:HI 28) (const:HI (plus:HI (symbol_ref:HI ("flags")) (const_int 2 (insn 24 (set (reg:QI 29) (mem:QI (reg:HI 28))) (insn 25 (set (reg:QI 30) (ior:QI (reg:QI 29) (const_int 0x80))) (insn 26 (set (mem:QI (reg:HI 28)) (reg:QI 30)) (insn 27 (set (reg:HI 31) (symbol_ref:HI ("flags"))) (insn 28 (set (reg:QI 32) (mem:QI (reg:HI 31))) (insn 29 (set (reg:QI 33) (and:QI (reg:QI 32) (const_int 0x7f))) (insn 30 (set (mem:QI (reg:HI 31)) (reg:QI 33)) Gcc appears to have a completely broken idea of how the u2 bitfield is laid out. When I saw that this was happening in RTL generation I baulked and decided to call in the big guns - you guys :-) What do you think. Is this a generic bitfield allocation problem in gcc ? Cheers Nick
Gimple ICE for MIPS ports
Hi Guys, Sometime during the last month building newlib for any of the MIPS ports broke with a gimple verification error: .../newlib/libc/stdio/vfprintf.c:480: error: type mismatch in binary expression unsigned char unsigned char int D.3477 = D.3438 & -8; [...] .../newlib/libc/stdio/vfprintf.c:480: internal compiler error: verify_gimple failed This is from a mips64vr-elf target, but I have the same failure with mipsisa32-elf and mipsisa64-elf targets as well. Cheers Nick
C6X fails to build in FSF mainline
Hi Bernd, You probably know this already. The c6x-elf target fails to build libgcc with the current FSF mainline sources: gcc/libgcc2.c: In function ‘__gnu_mulsc3’: gcc/libgcc2.c:1928:1: internal compiler error: in scan_trace, at dwarf2cfi.c:2433 Please submit a full bug report, I assume that it is because the C6X has more than one delay slot ? Cheers Nick
Help: How to update dataflow info after splitting ?
Hi Guys, I am stuck on a dataflow problem. PR 49801 is reported against the RX toolchain, but I believe it to be a generic problem. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49801 The issue I think is the split2 pass which is converting this: (set (pc) (if_then_else (geu (reg r1) (reg r2)) (label_ref 13) (pc))) into this: (set (reg:CC cc) (compare:CC (reg r1) (reg r2))) (set (pc) (if_then_else (geu (reg cc) (const_int 0)) (label_ref 13) (pc))) This new pair of insns introduces a definition and use of the condition code register (reg cc), but the dataflow information is not updated to reflect this. This causes the following pass (compare eliminate) to ICE with a dataflow checking failure if checking is enabled: shift.c:7:1: internal compiler error: in df_live_verify_transfer_functions, at df-problems.c:1816 The dataflow information for the basic block looks like this: ;; Start of basic block ( 0) -> 2 ;; bb 2 artificial_defs: { } ;; bb 2 artificial_uses: { u-1(0){ }} ;; lr in0 [r0] 1 [r1] 2 [r2] ;; lr use 0 [r0] 1 [r1] 2 [r2] ;; lr def ;; live in 0 [r0] 1 [r1] 2 [r2] ;; live gen ;; live kill ;; End of basic block 2 -> ( 3 4) ;; lr out 0 [r0] 1 [r1] 2 [r2] ;; live out 0 [r0] 1 [r1] 2 [r2] Ie no mention of the condition code register (register 16). The issue I have is that I do not know how to fix this. I thought that adding a call to df_insn_rescan for the newly created insns would work, like this: Index: gcc/recog.c === --- gcc/recog.c (revision 179611) +++ gcc/recog.c (working copy) @@ -2841,7 +2841,10 @@ for (;;) { if (INSN_P (first)) - cleanup_subreg_operands (first); + { + cleanup_subreg_operands (first); + df_insn_rescan (first); + } if (first == last) break; first = NEXT_INSN (first); But this made no difference. :-( I have considered adding a "(set (reg cc)..)" in parallel to the original jump pattern, but I am loath to do so because I have found that gcc tends to have issues with jump insns that contain parallels. Any suggestions ? Cheers Nick
AVR fails to build lto1
Hi Guys, I tried to build an avr-elf toolchain today from the current mainline GCC sources, but it fails building lto1 with: gcc/config/avr/avr.c:2591: undefined reference to `c_addr_space_name' Is there any chance that this can be fixed please ? (I am trying to investigate a binutils AVR bug report, but I need a working toolchain). Cheers Nick
Loop invariant code corrupting xstormy16 insn
Hi Zdenek, Hi Daniel, Hi Geoff, I think that I have found a small bug in the loop invariant code. The problem is exhibited when building newlib for the xstormy16-elf toolchain although it may happen with other targets as well. The problem occurs when an insn contains an r-value use of a register that is going to hoisted as well as a clobber of that register, like this: (parallel [ (set (pc) (if_then_else (lt:SI (reg:SI 45)<--- (reg:SI 26)) (label_ref:HI 129) (pc))) (clobber (reg:SI 45))<-- must be the same (clobber (scratch:BI)) ]) The important point here is that the register referenced in the first clobber must match the register used as the first argument of the condition operation. (This comes from the "ineqbranchsi" pattern in the xstormy16 machine description). The problem is that the loop-invariant optimization was deciding that (reg:SI 45) could be hoisted out of the loop, whereas really it should be left alone. I have been looking at the loop invariant code trying to figure out what needs to be changed, but so far I have not been able to puzzle it out. I think that the real problem might be the clobbers in the ineqbranchsi pattern, but I do not know how it could be changed to fix this. Any ideas ? Cheers Nick
Re: Loop invariant code corrupting xstormy16 insn
Hi Zdenek, (parallel [ (set (pc) (if_then_else (lt:SI (reg:SI 45)<--- (reg:SI 26)) (label_ref:HI 129) (pc))) (clobber (reg:SI 45))<-- must be the same (clobber (scratch:BI)) ]) actually, I probably misunderstood what you meant. The problem is that invariant motion rewrites just part of the considered insn, changing reg:45 to another register in if_then_else, but leaving it the same in the clobber? Correct. I originally had a patch like this Index: gcc/loop-invariant.c === --- gcc/loop-invariant.c(revision 125308) +++ gcc/loop-invariant.c(working copy) @@ -1212,7 +1212,14 @@ move_invariant_reg (struct loop *loop, u if (inv->def) { for (use = inv->def->uses; use; use = use->next) - *use->pos = reg; + { + rtx orig = *use->pos; + + /* Use replace_rtx() in case there are other references to +ORIG inside the insn which are not recorded in the USE +list. eg references inside CLOBBERs. */ + replace_rtx (use->insn, orig, reg); + } } return true; which I thought would solve the problem, but I found that it introduced regressions into the gcc testsuite for an x86_64-linux-gnulibc toolchain, so I abandoned it. (I did not investigate why it caused regressions, I just assumed that my approach was wrong). Cheers Nick
libgcc fails to build for sh-elf toolchain
Hi Alex, Hi Kaz, The sh-elf target is currently failing to build libgcc on the FSF mainline because: libgcc/unwind-dw2.c: In function 'execute_stack_op': libgcc/unwind-dw2.c:902:1: error: unable to generate reloads for: (set (reg:SI 147 t) (zero_extract:SI (reg:SI 621 [ MEM[(struct _Unwind_Context *)context_25(D) + 640B] ]) (const_int 1) (const_int 30))) libgcc/unwind-dw2.c:902:1: internal compiler error: in find_reloads, at reload.c:3879 This bug has only shown up in the last few weeks - the toolchain was building OK at the end of November... Cheers Nick
Infinite recursion in a function called memset
Hi Guys, Suppose a programmer creates a function called "memset" and then compiles it with gcc. Eg: % cat memset.c void * memset (void *s, int c, unsigned int n) { char *v = s; while (n--) *v++ = c; return s; } % gcc -O3 -S -fno-builtin memset.c % cat memset.s memset: .LFB0: .cfi_startproc testl %edx, %edx je .L6 subl$1, %edx subq$8, %rsp .cfi_def_cfa_offset 16 movsbl %sil, %esi addq$1, %rdx callmemset addq$8, %rsp .cfi_def_cfa_offset 8 ret Note the infinite recursion. Memset calls memset which calls memset and so on. This is with an x86_64 compiler built from today's sources, but the problem exists for all targets. The "-fno-builtin" is just to avoid the warning about the conflicting types of the memset function, but the "-O3" is necessary in order to make gcc detect the loop and decide to expand it via a library function. Now presumably the programmer knows that there is a library function called memset, but also presumably they have their own reasons for creating a memset function. Perhaps they want to add some extra annotation or debugging. It does not seem illegal though. A program provided function should take precedence over a library provided one. Anyway it seems to me that gcc should not attempt to call a function called "memset" if it is compiling code inside a function called "memset". The problem is, I cannot see an easy way of enforcing this. The memset builtin expander is called from several different places and I am not at all sure how, or if, they should be modified. Any clues ? Cheers Nick
MIPS: va_arg is unable to correct extract an empty zero-length array
Hi Eric, Hi Richard, A customer has reported the following bug with the MIPS target. Since it is for a GNU extension to the C language (zero-length arrays) that is being used in a non-intended fashion (the zero-length array is in a structure with no other fields) I doubt if you will want to investigate the problem too much, but I thought that it was worth reporting anyway: % mips64vr-elf-gcc -mgp32 -O2 -Tddb.ld -march=vr5500 bug.c % mips64vr-elf-run a.out assertion "arg4 == va4" failed: file "bug.c", line 40, function: foo As an aside if the type3 structure in bug.c is given another, non-zero-length field, then the test passes. Cheers Nick #include #include #include typedef int * type1; typedef struct { union u1 { double f1; long int f2; } f3[0]; } type3; typedef int type4; static type1 arg1 = 0; static double arg2 = 1.0; static type3 arg3 = {{}}; static type4 arg4 = 0x12345678; void foo (double parm, ...) { va_list ap; type1va1; double va2; type3va3; type4va4; va_start (ap, parm); va1 = va_arg (ap, type1); assert (arg1 == va1); va2 = va_arg (ap, double); assert (arg2 == va2); va3 = va_arg (ap, type3); va4 = va_arg (ap, type4); assert (arg4 == va4); va_end (ap); } int main (void) { foo (1.0, arg1, arg2, arg3, arg4); return 0; }
Re: MIPS: va_arg is unable to correct extract an empty zero-length array
Hi Richard, + /* Even zero-sized arguments occupy one byte. */ + if (size == 0) + size = 1; That fixes it! Thanks. Will you apply this patch yourself, or should I submit the patch and the test case as a separate email to gcc-patches ? Cheers Nick
G++: Order of static destructors ?
Hi Guys, There appears to be a discrepancy in the way that G++ orders its static destructors. Given this test program: #include using namespace std; class A { public: int i; A(int j) : i(j) { cout << "constructor A" << endl; } ~A() { cout << "destructor A : i = " << i << endl; } }; class B { public: A *n; B() { static A p(1); n = &p; cout << "constructor B" << endl; } ~B() { cout << "destructor B : i = " << n->i << endl; n->i = 10; } }; class B x1; int main (void) { return 0; } When compiled and run using an x86_64 native gcc built from today's sources this program will produce this output: constructor A constructor B destructor A : i = 1 destructor B : i = 1 However when compiled using a 3.4.4 native x86_64 compiler the following is produced when the program is run: constructor A constructor B destructor B : i = 1 destructor A : i = 10 Looking at what I hope is the right part of the C++ language specification: 3.6.3 - Termination [basic.start.term] -1- Destructors (class.dtor) for initialized objects of static storage duration (declared at block scope or at namespace scope) are called as a result of returning from main and as a result of calling exit (lib.support.start.term). These objects are destroyed in the reverse order of the completion of their constructor or of the completion of their dynamic initialization. If an object is initialized statically, the object is destroyed in the same order as if the object was dynamically initialized. For an object of array or class type, all subobjects of that object are destroyed before any local object with static storage duration initialized during the construction of the subobjects is destroyed. This appears to state that the 3.4.4 compiler got it right. The problem I believe is that the destructor for class A is registered to run using atexit() when the constructor for class B is run, but the destructor for class B is permanently recorded in the .dtors section. Since the exit() function runs the things recorded with atexit() first, before calling _exit() which runs the destructors in the .dtors section, the destructor for A is called before the destructor for B. Can anyone clarify this for me ? Is this a bug with the current G++ implementation ? Cheers Nick
RFC; MN10300 binary operators do not work on address registers
Hi Jeff, Hi Alex, Whilst working with the AM33 port I recently came across a piece of code in the glibc sources which triggered an ICE in gcc because it was generating an insn which did not match the constraints: error: insn does not satisfy its constraints: (insn (set (reg:SI a0) (ior:SI (reg:SI a0) (const_int 2))) {*mn10300.md:1330} This was generated by this code: unsigned long foo (void) { char * sp = __builtin_frame_address (0); return * (unsigned long *) ((unsigned long) sp | 2); } I believe that it is the call to __builtin_frame_address() which is placing the variable "sp" into an address register and hence causing the problem when it is treated as a data value and applied to a bit operator. I found an easy solution for the AM33 and AM33-2 ports - allow the use of integers in the second alternative of the IORSI3 insn pattern. This is permitted by the AM33 ISA and a simple patch to the mn10300.md file is all that is needed: *** gcc/config/mn10300/mn10300.md 8 May 2005 09:37:17 - 1.60 --- gcc/config/mn10300/mn10300.md 13 Jun 2005 17:36:39 - *** *** 1305,1311 (define_insn "" [(set (match_operand:SI 0 "register_operand" "=dx,!dax") (ior:SI (match_operand:SI 1 "register_operand" "%0,dax") ! (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))] "TARGET_AM33" "* { --- 1305,1311 (define_insn "" [(set (match_operand:SI 0 "register_operand" "=dx,!dax") (ior:SI (match_operand:SI 1 "register_operand" "%0,dax") ! (match_operand:SI 2 "nonmemory_operand" "dxi,daxi")))] "TARGET_AM33" "* { There are two problems however: 1. The basic MN10300 does not support bit operations on address registers so the patch does not work for the basic MN10300 IORSI3 pattern. My initial thought was that this situation would arise under such unusual circumstances that there was no need to try to optimise GCC and instead it would be enough to code a second alternative as: push a data register copy the address register into the data register perform the bit operation copy the result back into the address register pop the data register. Unfortunately I do not know enough MN10300 assembler to code this correctly. I tried, but failed :-( 2. The problem also affects the AND and XOR patterns (and the test case can easily be altered to trigger the ICE for these patterns). I think from a visual inspection of the patterns that extending the patch to cover these instructions should also work, but I am wary about the AND pattern - it looks like it uses short cuts for certain sizes of integer and I do not know enough about the AM33 ISA to know if these short cuts are valid when address registers are involved. Can you offer any advice ? Is this a reload problem whereby "sp" should be moved into a data register ? Cheers Nick
ia64-elf and i386-elf fail to build
Hi Guys, The ia64-elf and i386-elf targets currently fail to build for me using the mainline sources. The symptom is a seg-fault when running the self tests: ./xgcc <...> -xc -S -c /dev/null -fself-test : internal compiler error: Segmentation fault The cause appears to be an attempt to register a builtin type using the float128_type_node, which is NULL for these particular targets: gcc/config/ia64/ia64.c:10373 gcc/config/i386/i386.c:33347 Presumably float128_type_node should not be NULL, but I am not sure how to fix this. Any suggestions ? Cheers Nick
Re: ia64-elf and i386-elf fail to build
Hi Guys, > I think this indicates that i386 and ia64 need their own local version of > float128_type_node, set up like float80_type_node (i.e. copied from the > global one if that isn't NULL, otherwise set up locally) instead of using > the global one unconditionally, because of the existence of i386 and ia64 > targets where the TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P hook can return > false for TFmode (in which case __float128 still exists, but not > _Float128). OK - that I can do. > Though preferable would be to fix all the targets with > IX86_NO_LIBGCC_TFMODE / IX86_MAYBE_NO_LIBGCC_TFMODE / > IA64_NO_LIBGCC_TFMODE so that they include the relevant support code in > libgcc and so no longer need the TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P > hook overridden at all. I would prefer to leave this to the maintainers as I do not want to get target greping wrong. So - Jan, Uros, Jim, Steve - are these ia64 and i386 backend patches OK ? Cheers Nick gcc/ChangeLog 2016-08-25 Nick Clifton * config/ia64/ia64.c (ia64_init_builtins): Initialise the float128_type_node if that has not been done already. * config/i386/i386.c (ix86_init_builtin_types): Likewise. Index: gcc/config/i386/i386.c === --- gcc/config/i386/i386.c (revision 239761) +++ gcc/config/i386/i386.c (working copy) @@ -33341,9 +33341,19 @@ } lang_hooks.types.register_builtin_type (float80_type_node, "__float80"); - /* The __float128 type. The node has already been created as - _Float128, so we only need to register the __float128 name for - it. */ + /* The __float128 type. If TFmode is supported by libgcc then the node + has already been created as _Float128, so we only need to register the + __float128 name for it. Otherwise we have to create the float128 + type first. */ +#if defined IX86_NO_LIBGCC_TFMODE || defined IX86_MAYBE_NO_LIBGCC_TFMODE + if (float128_type_node == NULL) +{ + float128_type_node = make_node (REAL_TYPE); + TYPE_PRECISION (float128_type_node) = 128; + layout_type (float128_type_node); + SET_TYPE_MODE (float128_type_node, TFmode); +} +#endif lang_hooks.types.register_builtin_type (float128_type_node, "__float128"); const_string_type_node Index: gcc/config/ia64/ia64.c === --- gcc/config/ia64/ia64.c (revision 239761) +++ gcc/config/ia64/ia64.c (working copy) @@ -10368,6 +10368,13 @@ tree const_string_type = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST)); +#ifdef IA64_NO_LIBGCC_TFMODE + gcc_assert (float128_type_node == NULL); + float128_type_node = make_node (REAL_TYPE); + TYPE_PRECISION (float128_type_node) = 128; + layout_type (float128_type_node); + SET_TYPE_MODE (float128_type_node, TFmode); +#endif (*lang_hooks.types.register_builtin_type) (float128_type_node, "__float128");
Re: ia64-elf and i386-elf fail to build
Hi Joseph, >> * config/ia64/ia64.c (ia64_init_builtins): Initialise the >> float128_type_node if that has not been done already. >> * config/i386/i386.c (ix86_init_builtin_types): Likewise. > > No, this is wrong. The global node must remain as NULL when the type is > not fully supported. You need a different name for the local node, e.g. > i386_float128_type_node (and then update all back-end uses to use the > local node). Oh, OK - new patch in the works. Cheers Nick