This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
optimization/6261: Has this combiner pass bug been fixed?
- From: ted at arraycomm dot com
- To: gcc-gnats at gcc dot gnu dot org
- Date: 11 Apr 2002 18:35:48 -0000
- Subject: optimization/6261: Has this combiner pass bug been fixed?
- Reply-to: ted at arraycomm dot com
>Number: 6261
>Category: optimization
>Synopsis: Has this combiner pass bug been fixed?
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Apr 11 11:36:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: Ted Merrill, ArrayComm, Inc.
>Release: gcc 3.04
>Organization:
>Environment:
gcc 3.04 conf.g for ARM/thumb with -mthumb running on solaris
>Description:
The problem effects certain types of bit shift/mask
operations, and caused incorrect results from
newlib math library.
Evidentally if affects targets other than ARM/thumb.
Richard Earnshaw very helpfully provided me a patch
that fixes this problem.
This is just to document this, and ensure that it gets
into 3.1 at least...
-Ted Merrill
>How-To-Repeat:
>Fix:
See patch in attachment.
We've seen no problems since applying the patch.
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="attach.txt"
Content-Disposition: inline; filename="attach.txt"
::::::::::::::
mail1.txt
::::::::::::::
>From ted@arraycomm.com Thu Apr 11 11:25:32 2002
Date: Tue, 26 Feb 2002 19:05:58 -0800 (PST)
From: Ted Merrill <ted@arraycomm.com>
To: Richard.Earnshaw@arm.com
Cc: gcc-bugs@gcc.gnu.org, ted@arraycomm.com, rearnsha@arm.com
Subject: gcc 3.0.4 thumb floating pt bug
Richard,
Following i describe what i believe to be a bug in the arm/thumb
code generation of the latest gcc, and also of gcc since at least 3.0.0.
We've been bedeviled for sometime by e.g. pow(10.0,0.2) returning 0.0
and by other occasional floating point bugs.
I just upgraded to newlib-1.10.0 and gcc-3.0.4, both of which are for
the moment reasonably current, and the problem is still there.
(Target is arm, running in thumb mode; optimization flag is -O).
After long tracing i finally narrowed this down to the following
compiler bug which can be summarized as:
(int j=0x3fe542a5)
newlib-1.10.0/newlib/libm/math/e_pow.c line 273:
if ((j&0x7fffffff) >= 0x4090cc00)
{
... under flow code...
}
The underflow code incorrectly executes because the generated assembly
code looks like:
(r5 is j == 0x3fe542a5)
lsl r3,r5,#1 (sets r5 to 0x7fca854a)
ldr r4,(pc-relative location containing 0x812197ff which is 2*0x4090cc00-1)
cmp r3,r4 (sets N=1,Z=0,C=0,V=1)
blt (past overflow code)
The blt instruction branches only if N!=V which is not the case here,
thus the underflow code executes (which should not be the case).
The correct instruction to use would have been BLS (with appropriate
fiddling of the constant).
The blt would make sense if r3 and r4 were really signed integers.
Although blt would have been appropriate for signed integers,
the optimization clearly(?) recognizes that positive quantities are being
compared (otherwise the optimization could not be done) and
the comparison must be treated as unsigned.
(I assume the point of the optimization was to avoid loading the
constant 0x7fffffff... a good thing to avoid).
Attached is the .c and .s files of a simple test case.
Thanks for your (otherwise) excellent work.
If you have time to produce a patch in the next week or so i will
probably have time to test it.
In any event, i'd appreciate an ack that you got this message.
Thanks
-Ted Merrill
ArrayComm, Inc.
ted@arraycomm.com
[ Part 2, "bug1.c" Text/PLAIN (Name: "bug1.c") 4 lines. ]
[ Unable to print this part. ]
[ Part 3, "bug1.s" Text/PLAIN (Name: "bug1.c.o.s") 100 lines. ]
[ Unable to print this part. ]
::::::::::::::
bug1.c
::::::::::::::
int bug1(int j)
{
if ( (j&0x7fffffff) >= 0x4090cc00 )
{
return 1;
}
else
{
return 0;
}
}
int bug1test(void)
{
int j = 0x3fe542a5;
return bug1(j);
}
::::::::::::::
bug1.s
::::::::::::::
@ Generated by gcc 3.0 for ARM/elf
.file "bug1.c.o.i"
.code 16
.section .debug_abbrev
.Ldebug_abbrev0:
.section .text
.Ltext0:
.section .debug_info
.Ldebug_info0:
.section .debug_line
.Ldebug_line0:
.text
.align 2
.global bug1
.thumb_func
.type bug1,function
bug1:
.LFB1:
.LM1:
push {r7, lr}
mov r7, sp
.LM2:
lsl r0, r0, #1
ldr r3, .L4
cmp r0, r3
blt .L2
.LM3:
mov r0, #1
b .L1
.L2:
.LM4:
mov r0, #0
.LM5:
.L1:
mov sp, r7
pop {r7, pc}
.L5:
.align 2
.L4:
.word -2128504833
.LFE1:
.Lfe1:
.size bug1,.Lfe1-bug1
.align 2
.global bug1test
.thumb_func
.type bug1test,function
bug1test:
.LFB2:
.LM6:
push {r7, lr}
.LBB2:
mov r7, sp
.LM7:
ldr r0, .L7
bl bug1
.LBE2:
.LM8:
mov sp, r7
pop {r7, pc}
.L8:
.align 2
.L7:
.word 1071989413
.LFE2:
.Lfe2:
.size bug1test,.Lfe2-bug1test
.section .text
.Letext0:
.section .debug_line
.4byte .LELT0-.LSLT0
.LSLT0:
.2byte 0x2
.4byte .LELTP0-.LASLTP0
.LASLTP0:
.byte 0x4
.byte 0x1
.byte 0xf6
.byte 0xf5
.byte 0xa
.byte 0x0
.byte 0x1
.byte 0x1
.byte 0x1
.byte 0x1
.byte 0x0
.byte 0x0
.byte 0x0
.byte 0x1
.ascii "/s/home/ted/_wdsl/gccbug"
.byte 0
.byte 0x0
.ascii "o/lib.thumb/bug1.c.o.i\000"
.byte 0x1
.byte 0x0
.byte 0x0
.ascii "bug1.c\000"
.byte 0x1
.byte 0x0
.byte 0x0
.byte 0x0
.LELTP0:
.byte 0x0
.byte 0x5
.byte 0x2
.4byte .LM1
.byte 0x4
.byte 0x2
.byte 0x15
.byte 0x0
.byte 0x5
.byte 0x2
.4byte .LM2
.byte 0x15
.byte 0x0
.byte 0x5
.byte 0x2
.4byte .LM3
.byte 0x16
.byte 0x0
.byte 0x5
.byte 0x2
.4byte .LM4
.byte 0x18
.byte 0x0
.byte 0x5
.byte 0x2
.4byte .LM5
.byte 0x16
.byte 0x0
.byte 0x5
.byte 0x2
.4byte .LM6
.byte 0x17
.byte 0x0
.byte 0x5
.byte 0x2
.4byte .LM7
.byte 0x16
.byte 0x0
.byte 0x5
.byte 0x2
.4byte .LM8
.byte 0x15
.byte 0x0
.byte 0x5
.byte 0x2
.4byte .Letext0
.byte 0x0
.byte 0x1
.byte 0x1
.LELT0:
.section .debug_info
.4byte 0xa5
.2byte 0x2
.4byte .Ldebug_abbrev0
.byte 0x4
.byte 0x1
.4byte .Ldebug_line0
.4byte .Letext0
.4byte .Ltext0
.ascii "/s/home/ted/_wdsl/gccbug/o/lib.thumb/bug1.c.o.i\000"
.ascii "GNU C 3.0\000"
.byte 0x1
.byte 0x2
.4byte 0x7b
.byte 0x1
.ascii "bug1\000"
.byte 0x2
.byte 0x2
.byte 0x1
.4byte 0x7b
.4byte .LFB1
.4byte .LFE1
.byte 0x1
.byte 0x57
.byte 0x3
.ascii "j\000"
.byte 0x2
.byte 0x1
.4byte 0x7b
.byte 0x1
.byte 0x50
.byte 0x0
.byte 0x4
.ascii "int\000"
.byte 0x4
.byte 0x5
.byte 0x5
.byte 0x1
.ascii "bug1test\000"
.byte 0x2
.byte 0xe
.byte 0x1
.4byte 0x7b
.4byte .LFB2
.4byte .LFE2
.byte 0x1
.byte 0x57
.byte 0x6
.ascii "j\000"
.byte 0x2
.byte 0xf
.4byte 0x7b
.byte 0x0
.byte 0x0
.section .debug_abbrev
.byte 0x1
.byte 0x11
.byte 0x1
.byte 0x10
.byte 0x6
.byte 0x12
.byte 0x1
.byte 0x11
.byte 0x1
.byte 0x3
.byte 0x8
.byte 0x25
.byte 0x8
.byte 0x13
.byte 0xb
.byte 0x0
.byte 0x0
.byte 0x2
.byte 0x2e
.byte 0x1
.byte 0x1
.byte 0x13
.byte 0x3f
.byte 0xc
.byte 0x3
.byte 0x8
.byte 0x3a
.byte 0xb
.byte 0x3b
.byte 0xb
.byte 0x27
.byte 0xc
.byte 0x49
.byte 0x13
.byte 0x11
.byte 0x1
.byte 0x12
.byte 0x1
.byte 0x40
.byte 0xa
.byte 0x0
.byte 0x0
.byte 0x3
.byte 0x5
.byte 0x0
.byte 0x3
.byte 0x8
.byte 0x3a
.byte 0xb
.byte 0x3b
.byte 0xb
.byte 0x49
.byte 0x13
.byte 0x2
.byte 0xa
.byte 0x0
.byte 0x0
.byte 0x4
.byte 0x24
.byte 0x0
.byte 0x3
.byte 0x8
.byte 0xb
.byte 0xb
.byte 0x3e
.byte 0xb
.byte 0x0
.byte 0x0
.byte 0x5
.byte 0x2e
.byte 0x1
.byte 0x3f
.byte 0xc
.byte 0x3
.byte 0x8
.byte 0x3a
.byte 0xb
.byte 0x3b
.byte 0xb
.byte 0x27
.byte 0xc
.byte 0x49
.byte 0x13
.byte 0x11
.byte 0x1
.byte 0x12
.byte 0x1
.byte 0x40
.byte 0xa
.byte 0x0
.byte 0x0
.byte 0x6
.byte 0x34
.byte 0x0
.byte 0x3
.byte 0x8
.byte 0x3a
.byte 0xb
.byte 0x3b
.byte 0xb
.byte 0x49
.byte 0x13
.byte 0x0
.byte 0x0
.byte 0x0
.section .debug_pubnames
.4byte 0x24
.2byte 0x2
.4byte .Ldebug_info0
.4byte 0xa9
.4byte 0x53
.ascii "bug1\000"
.4byte 0x82
.ascii "bug1test\000"
.4byte 0x0
.section .debug_aranges
.4byte 0x1c
.2byte 0x2
.4byte .Ldebug_info0
.byte 0x4
.byte 0x0
.2byte 0x0
.2byte 0x0
.4byte .Ltext0
.4byte .Letext0-.Ltext0
.4byte 0x0
.4byte 0x0
.data
::::::::::::::
mail2.txt
::::::::::::::
>From rearnsha@arm.com Thu Apr 11 11:17:31 2002
Date: Wed, 27 Feb 2002 10:59:23 +0000
From: Richard Earnshaw <rearnsha@arm.com>
Reply-To: Richard.Earnshaw@arm.com
To: Ted Merrill <ted@arraycomm.com>
Cc: Richard.Earnshaw@arm.com, gcc-bugs@gcc.gnu.org, rearnsha@arm.com
Subject: Re: gcc 3.0.4 thumb floating pt bug
Ted,
This is a generic bug in the combiner pass.
Can you please try this patch.
R.
2002-02-27 Richard Earnshaw <rearnsha@arm.com>
* combine.c (simplify_comparision): If simplifying a logical-shift
right and compare with constant to eliminate the shift, make the
comparison unsigned.
[ Part 2, "gcc-lsrcmp.patch" Text/X-PATCH (Name: "gcc-lsrcmp.patch") ]
[ 21 lines. ]
[ Unable to print this part. ]
::::::::::::::
gcc-lsrcmp.patch
::::::::::::::
Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.267
diff -p -r1.267 combine.c
*** combine.c 2002/02/20 23:15:00 1.267
--- combine.c 2002/02/27 10:55:40
*************** simplify_comparison (code, pop0, pop1)
*** 10885,10890 ****
--- 10885,10895 ----
|| (floor_log2 (const_op) + INTVAL (XEXP (op0, 1))
< mode_width)))
{
+ /* If the shift was logical, then we must make the condition
+ unsigned. */
+ if (GET_CODE (op0) == LSHIFTRT)
+ code = unsigned_condition (code);
+
const_op <<= INTVAL (XEXP (op0, 1));
op1 = GEN_INT (const_op);
op0 = XEXP (op0, 0);