From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16699 invoked by alias); 11 Apr 2002 18:36:01 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 16680 invoked by uid 71); 11 Apr 2002 18:36:00 -0000 Resent-Date: 11 Apr 2002 18:36:00 -0000 Resent-Message-ID: <20020411183600.16679.qmail@sources.redhat.com> Resent-From: gcc-gnats@gcc.gnu.org (GNATS Filer) Resent-To: nobody@gcc.gnu.org Resent-Cc: gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org Resent-Reply-To: gcc-gnats@gcc.gnu.org, ted@arraycomm.com Received:(qmail 16643 invoked by uid 61); 11 Apr 2002 18:35:49 -0000 Message-Id:<20020411183548.16642.qmail@sources.redhat.com> Date: Thu, 11 Apr 2002 11:36:00 -0000 From: ted@arraycomm.com Reply-To: ted@arraycomm.com To: gcc-gnats@gcc.gnu.org X-Send-Pr-Version:gnatsweb-2.9.3 (1.1.1.1.2.31) Subject: optimization/6261: Has this combiner pass bug been fixed? X-SW-Source: 2002-04/txt/msg00620.txt.bz2 List-Id: >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 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 Reply-To: Richard.Earnshaw@arm.com To: Ted Merrill 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 * 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);