Test gcc.c-torture/compile/930210-1.c, when compiled with: -O2 -c produces the warning: /var/tmp//ccSVOi5X.s: Assembler messages: /var/tmp//ccSVOi5X.s:23: Warning: source register same as write-back base Because of the following instruction generated in the assembly: strb r2, [r2], #1 The assembler warning is produced because the instruction is unpredictable when the source register and the base destination register are the same and post-increment addressing is used. Note that while this test doesn't fail for the arm-none-elf target, a similar test case does demonstrate the same issue: void f(void) { char c1, c2; char *p1, *p2; c1 = c2 = *p1++; while (c1--) *p2++ = *p1++; } This behavior is present in gcc-4.1.0-20050405, and gcc-4.0.0-20050410 (RC1). Configuration options: --target=arm-unknown-elf --program-prefix=arm-elf- --disable-nls -- enable-languages=c,c++ --with-newlib --enable-multilib --disable-shared
Patch here: <http://gcc.gnu.org/ml/gcc-patches/2005-04/msg01291.html>. Do you know if this is a regression from say 3.4.x?
Subject: Re: Compiler-generated code produces an assembler warning I don't see this same behavior on 3.4.3. - Josh On Apr 12, 2005, at 10:08 AM, pinskia at gcc dot gnu dot org wrote: > > ------- Additional Comments From pinskia at gcc dot gnu dot org > 2005-04-12 17:08 ------- > Patch here: <http://gcc.gnu.org/ml/gcc-patches/2005-04/msg01291.html>. > > Do you know if this is a regression from say 3.4.x? > > -- > What |Removed |Added > ----------------------------------------------------------------------- > ----- > CC| |pinskia at gcc dot > gnu dot > | |org > Status|UNCONFIRMED |NEW > Ever Confirmed| |1 > Keywords| |patch > Last reconfirmed|0000-00-00 00:00:00 |2005-04-12 17:08:16 > date| | > > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20972 > > ------- You are receiving this mail because: ------- > You reported the bug, or are watching the reporter. >
The ARM ARM says that STR Rd, [Rn], #4 and STR Rd, [Rn, #4]! are unpredictable if Rd == Rn. That is, the auto-inc side effect is permitted to take place before Rd is read. There's currently no way for a back-end to describe that an auto-inc operation might be an early-clobber. The obvious '&<>' in the constraint doesn't work, causing an abort in find_reloads(). This bug isn't really a regression (the limitation has always been there), but the vagaries of register allocation means that it is only recently that it's started doing this (either that, or the assembler has only recently started whining about it :-).
Postponed until 4.0.2.
Maybe you could add a reload_completed split to not use autoincrements if Rd == Rn?
As described by Richard, this is not a regression so therefor not marking as such.
(In reply to comment #3) > There's currently no way for a back-end to describe that an auto-inc operation > might be an early-clobber. The obvious '&<>' in the constraint doesn't work, > causing an abort in find_reloads(). Actually, according to rtl.texi, there is no way to describe an auto-inc operation that is not an early-clobber at all. They are basically an earlyclobber for insns that do/would fit for a load-store architecture. If you have more than one memory address in the insn, it gets more complicated, as rtl.texi makes a distiction between address and non-address uses: If a register used as the operand of these expressions is used in another address in an insn, the original value of the register is used. Uses of the register outside of an address are not permitted within the same insn as a use in an embedded side effect expression because such insns behave differently on different machines and hence must be treated as ambiguous and disallowed.
OK, then that moves this from being a minor into a more serious problem. The compiler is clearly failing to behave as specified.
The bug is in flow.c and fixed by the new df.c rewrite of dataflow. Ken and I tripped over the same problem.
(In reply to comment #9) > The bug is in flow.c and fixed by the new df.c rewrite of dataflow. Ken and I > tripped over the same problem. > While I thought this earlier, I do not believe it now. There is a problem in flow that it fails to generate reg-dead notes for dead index regs in auto-inc insns, but this is a separate problem.
Also just noticed that offline copy of longest-match get extra move: .L15: movzbl 2(%eax), %edi #, tmp87 leal 2(%eax), %ecx #, scan.158 movl %edi, %edx # tmp87, cmpb 2(%ebx), %dl #, jne .L6 #, movzbl 3(%eax), %edi #, tmp88 leal 3(%eax), %ecx #, scan.158 movl %edi, %edx # tmp88, cmpb 3(%ebx), %dl #, jne .L6 #, movzbl 4(%eax), %edi #, tmp89 leal 4(%eax), %ecx #, scan.158 movl %edi, %edx # tmp89, cmpb 4(%ebx), %dl #, jne .L6 #, movzbl 5(%eax), %edi #, tmp90 leal 5(%eax), %ecx #, scan.158 movl %edi, %edx # tmp90, cmpb 5(%ebx), %dl #, jne .L6 #, while inlined copy is fine: .L98: movzbl 1(%eax), %edx #, leal 1(%eax), %edi #, scan cmpb 1(%ecx), %dl #, jne .L161 #, movzbl 2(%eax), %edx #, leal 2(%eax), %edi #, scan cmpb 2(%ecx), %dl #, jne .L161 #, movzbl 3(%eax), %edx #, leal 3(%eax), %edi #, scan cmpb 3(%ecx), %dl #, jne .L161 #, movzbl 4(%eax), %edx #, leal 4(%eax), %edi #, scan cmpb 4(%ecx), %dl #, jne .L161 #, interesting :)
Is there still a bug here, after the IRA merge?
Can't reproduce with trunk or release branches for the attached testcase.
If it works for Ramana, it works for me.