Article View: gnu.gcc.bug
Article #1194(none)
From: Jeremy Allison
Date: Tue, 13 Oct 1992 16:51
Date: Tue, 13 Oct 1992 16:51
341 lines
9703 bytes
9703 bytes
Dear GCC maintainers,
Firstly, thanks for such a great product. I really appreciate being
able to use ansi C and c++ on my obsolete machine (a Sun386i).
I believe I have found a bug in code generation using gcc2.2.2 with
-fpic under a sun386i, but I believe this bug would also hit other
architectures.I am generating pic code using the patch I submitted
earlier to change the format of the assembler generated output for
the sun386i - I don't think this is having an effect on the rtl
generated though. Please contact me if you wish a copy of this
patch.
Consider the following program, testcase.c
-------cut here---------------------
#ifdef WORKS
const double val = 0.3;
#else
#define val 0.3
#endif
int main()
{
float newval = 5.0;
float testval = newval/val;
printf("should be 16.66666 etc. but is %f\n", testval);
}
-------------end testcase-----------
Compile using pic code :-
% gcc -fpic testcase.c
Then run
% a.out
should be 16.66666 etc. but is Inf
But compile with the -DWORKS flag set,
% gcc -fpic -DWORKS testcase.c
Then run
% a.out
should be 16.66666 etc. but is 16.666666
All is well.
I have examined the code generated and have discovered
the following.
---------Assembler generated with -fpic -DWORKS (correct code) -----------
.file "testcase.c"
.version "GNU C 2.2.2"
gcc2_compiled.:
.globl val
.text
.align 4
val:
.double 2.9999999999999998889777e-01
.LC0:
.byte 0x73,0x68,0x6f,0x75,0x6c,0x64,0x20,0x62,0x65,0x20
.byte 0x31,0x36,0x2e,0x36,0x36,0x36,0x36,0x36,0x20,0x65
.byte 0x74,0x63,0x2e,0x20,0x62,0x75,0x74,0x20,0x69,0x73
.byte 0x20,0x25,0x66,0xa,0x0
.align 4
.globl main
main:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
pushl %ebx
call .L2
.L2:
popl %ebx
addl $_globtb_offset,%ebx
call __main, %eax
movl $1084227584,-4(%ebp)
flds -4(%ebp)
movl val(%ebx),%eax
fdivl (%eax)
fstps -8(%ebp)
flds -8(%ebp)
subl $8,%esp
fstpl (%esp)
movl .LC0(%ebx),%edx
movl %edx,%eax
pushl %eax
call printf, %eax
addl $12,%esp
.L1:
movl -12(%ebp),%ebx
leave
ret
-----------RTL GENERATED FOR ABOVE ASSEMBLER -----
-----(using gcc -fpic -c -dr -DWORKS testcase.c)--
;; Function main
(note 2 0 3 "" NOTE_INSN_DELETED)
(note 3 2 4 "" NOTE_INSN_FUNCTION_BEG)
(note 4 3 6 "" NOTE_INSN_DELETED)
(call_insn 6 4 8 (parallel[
(call (mem:QI (symbol_ref:SI ("__main")))
(const_int 0))
(set (reg:SI 7)
(plus:SI (reg:SI 7)
(const_int 0)))
] ) -1 (nil)
(nil))
(note 8 6 9 "" NOTE_INSN_BLOCK_BEG)
(insn 9 8 11 (set (mem:SF (plus:SI (reg:SI 18)
(const_int -4)))
(const_double:SF (const_int 0) 0 1075052544)) -1 (nil)
(nil))
(insn 11 9 13 (set (reg:DF 21)
(float_extend:DF (mem:SF (plus:SI (reg:SI 18)
(const_int -4))))) -1 (nil)
(nil))
(insn 13 11 14 (set (reg:SI 22)
(mem:SI (plus:SI (reg:SI 3)
(symbol_ref:SI ("val"))))) -1 (nil)
(nil))
(insn 14 13 15 (set (reg:DF 23)
(div:DF (reg:DF 21)
(mem/u:DF (reg:SI 22)))) -1 (nil)
(nil))
(insn 15 14 17 (set (mem:SF (plus:SI (reg:SI 18)
(const_int -8)))
(float_truncate:SF (reg:DF 23))) -1 (nil)
(nil))
(insn 17 15 18 (set (reg:DF 24)
(float_extend:DF (mem:SF (plus:SI (reg:SI 18)
(const_int -8))))) -1 (nil)
(nil))
(insn 18 17 20 (set (mem:DF (pre_dec:SI (reg:SI 7)))
(reg:DF 24)) -1 (nil)
(nil))
(insn 20 18 21 (set (reg:SI 27)
(mem:SI (plus:SI (reg:SI 3)
(symbol_ref/v:SI ("*.LC0"))))) -1 (nil)
(nil))
(insn 21 20 22 (set (reg:SI 26)
(reg:SI 27)) -1 (nil)
(expr_list:REG_EQUAL (symbol_ref/v:SI ("*.LC0"))
(nil)))
(insn 22 21 24 (set (mem:SI (pre_dec:SI (reg:SI 7)))
(reg:SI 26)) -1 (nil)
(nil))
(call_insn 24 22 25 (set (reg:SI 0)
(call (mem:QI (symbol_ref:SI ("printf")))
(const_int 12))) -1 (nil)
(nil))
(insn 25 24 27 (set (reg:SI 7)
(plus:SI (reg:SI 7)
(const_int 12))) -1 (nil)
(nil))
(note 27 25 28 "" NOTE_INSN_BLOCK_END)
(note 28 27 30 "" NOTE_INSN_FUNCTION_END)
(code_label 30 28 0 1 "")
-------------------end code-------------------------------
-------Assembler generated with -fpic (incorrect code)----
.file "testcase.c"
.version "GNU C 2.2.2"
gcc2_compiled.:
.text
.LC0:
.byte 0x73,0x68,0x6f,0x75,0x6c,0x64,0x20,0x62,0x65,0x20
.byte 0x31,0x36,0x2e,0x36,0x36,0x36,0x36,0x36,0x20,0x65
.byte 0x74,0x63,0x2e,0x20,0x62,0x75,0x74,0x20,0x69,0x73
.byte 0x20,0x25,0x66,0xa,0x0
.align 4
.LC1:
.double 2.9999999999999998889777e-01
.align 4
.globl main
main:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
pushl %ebx
call .L2
.L2:
popl %ebx
addl $_globtb_offset,%ebx
call __main, %eax
movl $1084227584,-4(%ebp)
flds -4(%ebp)
fldl .LC1(%ebx) <======= NOTE INCORRECT PIC REFERENCE
fdivrp %st,%st(1) Should be : movl .LC1(%ebx),%eax
fstps -8(%ebp) fdivl (%eax)
flds -8(%ebp)
subl $8,%esp
fstpl (%esp)
movl .LC0(%ebx),%edx
movl %edx,%eax
pushl %eax
call printf, %eax
addl $12,%esp
.L1:
movl -12(%ebp),%ebx
leave
ret
-------RTL GENERATED FOR ABOVE ASSEMBLER ---
-----(using gcc -c -fpic -dr testcase.c)----
;; Function main
(note 2 0 3 "" NOTE_INSN_DELETED)
(note 3 2 4 "" NOTE_INSN_FUNCTION_BEG)
(note 4 3 6 "" NOTE_INSN_DELETED)
(call_insn 6 4 8 (parallel[
(call (mem:QI (symbol_ref:SI ("__main")))
(const_int 0))
(set (reg:SI 7)
(plus:SI (reg:SI 7)
(const_int 0)))
] ) -1 (nil)
(nil))
(note 8 6 9 "" NOTE_INSN_BLOCK_BEG)
(insn 9 8 11 (set (mem:SF (plus:SI (reg:SI 18)
(const_int -4)))
(const_double:SF (const_int 0) 0 1075052544)) -1 (nil)
(nil))
(insn 11 9 12 (set (reg:DF 21)
(float_extend:DF (mem:SF (plus:SI (reg:SI 18)
(const_int -4))))) -1 (nil)
(nil))
(insn 12 11 13 (set (reg:DF 23)
(const_double:DF (const_int 0) 858993459 1070805811)) -1 (nil)
(nil))
(insn 13 12 14 (set (reg:DF 22)
(div:DF (reg:DF 21)
(reg:DF 23))) -1 (nil)
(nil))
(insn 14 13 16 (set (mem:SF (plus:SI (reg:SI 18)
(const_int -8)))
(float_truncate:SF (reg:DF 22))) -1 (nil)
(nil))
(insn 16 14 17 (set (reg:DF 24)
(float_extend:DF (mem:SF (plus:SI (reg:SI 18)
(const_int -8))))) -1 (nil)
(nil))
(insn 17 16 19 (set (mem:DF (pre_dec:SI (reg:SI 7)))
(reg:DF 24)) -1 (nil)
(nil))
(insn 19 17 20 (set (reg:SI 27)
(mem:SI (plus:SI (reg:SI 3)
(symbol_ref/v:SI ("*.LC0"))))) -1 (nil)
(nil))
(insn 20 19 21 (set (reg:SI 26)
(reg:SI 27)) -1 (nil)
(expr_list:REG_EQUAL (symbol_ref/v:SI ("*.LC0"))
(nil)))
(insn 21 20 23 (set (mem:SI (pre_dec:SI (reg:SI 7)))
(reg:SI 26)) -1 (nil)
(nil))
(call_insn 23 21 24 (set (reg:SI 0)
(call (mem:QI (symbol_ref:SI ("printf")))
(const_int 12))) -1 (nil)
(nil))
(insn 24 23 26 (set (reg:SI 7)
(plus:SI (reg:SI 7)
(const_int 12))) -1 (nil)
(nil))
(note 26 24 27 "" NOTE_INSN_BLOCK_END)
(note 27 26 29 "" NOTE_INSN_FUNCTION_END)
(code_label 29 27 0 1 "")
---------------end code-----------------------------
I have examined the GCC 2.2.2 code and believe I know what
is going wrong, but not yet how to fix it !
All numeric constants in a program are put onto a linked list
within each function and then just before the function is
generated are allocated real addresses and output. This is done
in the immed_double_const routines in varasm.c. The problem seems
to be that when pic references are made to these constants *and the
constant is too big to fix into a register* (ie. double float) then
an incorrect pic reference is generated. When the constant is turned
into an symbolic constant (-DWORKS) then a symbol is generated for
this value and correct pic is generated. The outputting of the pool
constants doesn't seem to be going through the "legitimize_pic_address"
function, which I would have thought should fix the problem.
I have been investigating adding code to generate more rtx expressions
into the immed_double_const routine to return an rtx expression containing
the correct pic code. Please let me know if you think this is the correct
solution (as I haven't been able to get it to work yet, and also would like
to fix this one !).
Regards,
Jeremy Allison.
Technical Details
Message-ID:
<9210131651.AA09483@legion.Corp.Sun.COM>Path:
arc1-ca.pugleaf.net!sparky!uunet!think.com!sdd.hp.com!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!corp.SUn.COM!Jeremy.AllisonShow Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug Path: arc1-ca.pugleaf.net!sparky!uunet!think.com!sdd.hp.com!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!corp.SUn.COM!Jeremy.Allison From: Jeremy.Allison@corp.SUn.COM (Jeremy Allison) Subject: (none) Message-ID: <9210131651.AA09483@legion.Corp.Sun.COM> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Tue, 13 Oct 1992 16:51:42 GMT Approved: bug-gcc@prep.ai.mit.edu Lines: 342