Bug 7856 - [arm] invalid offset in constant pool reference
Summary: [arm] invalid offset in constant pool reference
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 3.2
: P3 normal
Target Milestone: ---
Assignee: Richard Earnshaw
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-09-08 06:46 UTC by Philip Blundell
Modified: 2003-07-25 17:33 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
unicodectype.i.bz2 (31.13 KB, application/octet-stream)
2003-05-21 15:17 UTC, Philip Blundell
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Philip Blundell 2002-09-08 06:46:01 UTC
Build the attached file with -O3 -fPIC.  The assembler chokes on the resulting code with:

/home/pb/unicodectype.s:9735: Error: illegal value for co-processor offset
/home/pb/unicodectype.s:9760: Error: illegal value for co-processor offset

The offending lines are of the form

        ldfeqd  f0, .L185
and
        ldfeqd  f0, .L185+8

This is a regression from GCC 3.0

Release:
gcc 3.2

Environment:
arm-linux
Comment 1 Richard Earnshaw 2002-09-09 03:56:43 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Confirmed as a bug.
    
    The problem comes about due to a change that Nick made to 
    try to improve the performance of prologue and epilogue code.
    His change means that if the link register is not clobbered then
    it is never saved on the stack, even if other call-saved registers
    need to be saved.  The consequence of this is that we 
    sometimes end up generating 2-instruction return sequences
    when we previously only generated a single instruction.
    
    Although at first sight this appears to be faster, it is not 
    necessarily the best soloution, particularly when the return
    is conditional, since we end up making the conditional
    sequence longer.
    
    The particular consequence of this change is that the length of the 'return' and 'conditional-return' instructions needs to take
    into account this longer sequence if the constant spilling code
    is to do its job correctly.
    
    However, I'm not yet convinced that Nick's change is for the
    best overall.
Comment 2 Richard Earnshaw 2002-09-09 15:12:33 UTC
From: Richard Earnshaw <rearnsha@cambridge.arm.com>
To: gcc-gnats@gcc.gnu.org
Cc: Richard.Earnshaw@arm.com
Subject: Re: target/7856: [arm] invalid offset in constant pool reference 
Date: Mon, 09 Sep 2002 15:12:33 +0100

 stupid gnats setup...
 
 ------- Forwarded Message
 
 Date:    Mon, 09 Sep 2002 14:56:39 +0100
 From:    Richard Earnshaw <rearnsha@arm.com>
 To:      Philip Blundell <pb@nexus.co.uk>
 cc:      rearnsha@gcc.gnu.org, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org,
 	 nickc@redhat.com, nobody@gcc.gnu.org, rearnsha@arm.com
 Subject: Re: target/7856: [arm] invalid offset in constant pool reference 
 
 > On Mon, 2002-09-09 at 11:56, rearnsha@gcc.gnu.org wrote:
 > >     However, I'm not yet convinced that Nick's change is for the
 > >     best overall.
 > 
 > Well, mmm, it's tricky to know which gives you better code on average. 
 > XScale makes it worse, because the penalty for using ldm/stm is greater
 > on those devices - you pay something like a two-cycle startup cost, plus
 > one cycle for every register transferred.  So pushing LR unnecessarily
 > could cost you three cycles at entry and the same at exit, if you only
 > had one other register to save.
 > 
 > Presumably we could avoid the particular problem at hand by making
 > use_return_insn() detect this situation - it already does this for
 > interworking, which is the other main case where
 > output_return_instruction would generate a 2-instruction sequence.
 
 Ok, lets try a bit more detailed analysis:
 
 For XScale:
 scenario 1:
 	b<cond>	return_seqence		@ cost 5/1 (predict NOT taken)
 
  return_sequence:
 	ldr	sl, [sp], #4		@ cost 1
 	bx	lr			@ cost 5
 
     Condition true Total = 11 cycles
     Condition false total = 1 cycle
 
 Scenario 2:
 	ldr<cond> sl, [sp], #4		@ cost 1/1
 	bx<cond>  lr			@ cost 5/1
 
     Condition true total = 6 cycles
     Condition false total = 2 cycles
 
 Scenario 3:
 	ldm<cond> sp!, {sl, pc}		@ cost 9/2? (Not sure on no-exec cost)
 
     Condition true total = 9 cycles
     Condition false total = 2 cycles
 
 For arm10
 Scenario 1:
 	b<cond> return_sequence		@ cost 4/0 (predict NOT taken)
 
  return_sequence:
 	ldr	sl, [sp], #4		@ cost 1
 	bx	lr			@ cost 4
 
     Condition true total = 9 cycles
     Condition flase total = 0 cycle
 
 Scenario 2:
 	ldr<cond> sl, [sp], #4		@ cost 1/1
 	bx<cond>  lr			@ cost 4/2
 
     Condition true total = 5 cycles
     Condition false total = 3 cycles
 
 Scenario 3:
 	ldm<cond> sp!, {sl, pc}		@ cost 7/2
 
     Condition true total = 7 cycles
     Condition false total = 2 cycles
 
 For arm9e
 Scenario 1:
 	b<cond> return_sequence		@ cost 3/1
 
  return_sequence:
 	ldr	sl, [sp], #4		@ cost 1
 	bx	lr			@ cost 3
 
     Condition true total = 7 cycles
     Condition flase total = 1 cycle
 
 Scenario 2:
 	ldr<cond> sl, [sp], #4		@ cost 1/1
 	bx<cond>  lr			@ cost 3/1
 
     Condition true total = 4 cycles
     Condition false total = 2 cycles
 
 Scenario 3:
 	ldm<cond> sp!, {sl, pc}		@ cost 6/1
 
     Condition true total = 6 cycles
     Condition false total = 1 cycles
 
 For arm7tdmi
 Scenario 1:
 	b<cond> return_sequence		@ cost 3/1
 
  return_sequence:
 	ldr	sl, [sp], #4		@ cost 3
 	bx	lr			@ cost 3
 
     Condition true total = 9 cycles
     Condition flase total = 1 cycle
 
 Scenario 2:
 	ldr<cond> sl, [sp], #4		@ cost 3/1
 	bx<cond>  lr			@ cost 3/1
 
     Condition true total = 6 cycles
     Condition false total = 2 cycles
 
 Scenario 3:
 	ldm<cond> sp!, {sl, pc}		@ cost 6/1
 
     Condition true total = 6 cycles
     Condition false total = 1 cycles
 
 So it's fairly clear from this, that with the possible exception of the 
 7tdmi, we do not want to use an ldm instruction.  Now for both arm10 and 
 XScale, where branch prediction starts to kick in, it's also clear that we 
 want to use a branch instruction instead of a conditionally executed exit 
 sequence; this is particularly so inside a loop when we would like to 
 benefit from the branch predictor eliminating the branch entirely.  
 However, this does increase the cost of returning quite significantly in 
 all cases.
 
 It's also fairly clear that scenario 2 is almost never the 'best' sequence 
 (except when we think a conditional return is very likely).
 
 So I think the conclusion from all this is that we should make 
 use_return_insn () return false whenever a return sequence would be ldr 
 <reg> followed by a mov pc, lr.  We should probably still allow an 
 unconditional return sequence to be up to two instructions long (I don't 
 think there's much to be gained from allowing it to be longer), and we 
 should then adjust the length attribute of the "return" insn to be 8 
 (currently 4) to indicate the longest sequence possible (we could make it 
 more accurate if we really needed, but there seems to be little point).
 
 R.
 
 
 ------- End of Forwarded Message
 
 
 

Comment 3 Richard Earnshaw 2002-11-01 07:00:28 UTC
Responsible-Changed-From-To: unassigned->rearnsha
Responsible-Changed-Why: .
Comment 4 Richard Earnshaw 2002-11-01 07:00:28 UTC
State-Changed-From-To: analyzed->closed
State-Changed-Why: Fixed.
Comment 5 Richard Earnshaw 2002-11-01 14:40:24 UTC
From: rearnsha@gcc.gnu.org
To: gcc-gnats@gcc.gnu.org
Cc:  
Subject: target/7856
Date: 1 Nov 2002 14:40:24 -0000

 CVSROOT:	/cvs/gcc
 Module name:	gcc
 Branch: 	gcc-3_2-branch
 Changes by:	rearnsha@gcc.gnu.org	2002-11-01 06:40:24
 
 Modified files:
 	gcc            : ChangeLog 
 	gcc/config/arm : arm.c 
 
 Log message:
 	PR target/7856
 	* arm.c (use_return_insn): Don't use a return insn if there are
 	saved integer regs, but LR is not one of them.
 
 Patches:
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.13152.2.657.2.113&r2=1.13152.2.657.2.114
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/arm/arm.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.196.2.5&r2=1.196.2.5.2.1
 

Comment 6 Richard Earnshaw 2002-11-01 14:41:57 UTC
From: rearnsha@gcc.gnu.org
To: gcc-gnats@gcc.gnu.org
Cc:  
Subject: target/7856
Date: 1 Nov 2002 14:41:57 -0000

 CVSROOT:	/cvs/gcc
 Module name:	gcc
 Changes by:	rearnsha@gcc.gnu.org	2002-11-01 06:41:57
 
 Modified files:
 	gcc            : ChangeLog 
 	gcc/config/arm : arm.c 
 
 Log message:
 	PR target/7856
 	* arm.c (use_return_insn): Don't use a return insn if there are
 	saved integer regs, but LR is not one of them.
 
 Patches:
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=1.15834&r2=1.15835
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/arm/arm.c.diff?cvsroot=gcc&r1=1.239&r2=1.240