Thread View: gnu.gcc.bug
1 messages
1 total messages
Started by Jeremy Allison
Tue, 13 Oct 1992 16:51
(none)
Author: 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.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads