[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::decc_bugs

Title:DEC C Problem Reporting Forum
Notice:Report DEC C++ problems in TURRIS::C_PLUS_PLUS
Moderator:CXXC::REPETETCHEON
Created:Fri Nov 13 1992
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:1299
Total number of notes:6249

1262.0. "accvio with nodisjoint switch on VAX" by HYDRA::DORHAMER () Thu Feb 13 1997 10:21

Progress Software has reported the following possible optimization bug
in the DEC C v5.5 compiler on OpenVMS VAX.  Their test case is getting an
access violation when he uses the compiler switch /Optim=(NoInline,NoDisjoint).
The access violation disappears when they use /NoOptimize or 
/Optim=(NoInline,Disjoint).  They would like to understand if this is a bug
in the compiler or a problem in their code.

Thanks,
Karen Dorhamer
Software Partner Engineering


From:	US6RMC::"[email protected]" "John Ferlan" 12-FEB-1997 12:16:35.63
To:	hydra::dorhamer
CC:	[email protected]
Subj:	DEC C BUG? with optimizer


I think I've uncovered an "anomoly" with the DEC C optimizer - I'd like it if
you could run this by the DEC C notesfile for me and see what kind of response
there is.  I've whittled down my code to a smaller program which exhibits the
problem based on the optimize switch "DisJoin".  However, in my larger code
(the Oracle DataServer Client) just changing the switch doesn't work.

The problem is seen on OpenVMS VAX - and was reproduced by the V5.5 DEC C
compiler (I saw it on V5.0-003 first, but I did try it on V5.5-002 compiler
just to make sure it wasn't already fixed...).

A caveat, I don't write the code, I just try to make it work on VMS ;-)

Anyways, here's the code:

BUG.C
include        <stdio.h>
#include        <ssdef.h>


struct bbuf {
    unsigned char       *next;
    unsigned char       *end;
    };
typedef struct bbuf BBUF;

struct foo {
    int         a;
    int         b;
    short int   bar1;
    short int   bar2;
    int         c;
    int         d;
    BBUF        *bbuf;
    };

struct common {
    unsigned char *foo;
    };

struct common common;
struct common *pc = &common;

void foobar ( )
{
    struct foo          *pfoo = (struct foo *)pc->foo;

    if ( pfoo->bar1 && (pfoo->bar1 == pfoo->bar2) &&
         ( pfoo->bbuf->next  - pfoo->bbuf->end))
    {
        int a = 1;
    }
}

unsigned int main(int argc, char **argv)
{
    struct foo          *pfoo;
    BBUF                *pbbuf;

    pbbuf = (BBUF *)malloc ( sizeof (BBUF) );
    pbbuf->next = (unsigned char *)0x41;
    pbbuf->end = (unsigned char *)0x42;

    pfoo = (struct foo *)malloc ( sizeof (struct foo) );
    pfoo->bar1 = 1;
    pfoo->bar2 = 1;
    pfoo->bbuf = pbbuf;

    pc->foo = (unsigned char *)pfoo;

    foobar ( );
    return 0;
}

=====================

Here's my "compile.com" :
$ if p1 .eqs. "DEBUG"
$ then
$    debug_opt = "/Debug=All/NoOptimize"
$ else
$    debug_opt = "/Debug=(Trace)/Optim=(NoInline,NoDisjoint)"
$ endif
$!
$ cc/decc/G_Float/Standard=Relaxed_Ansi/Member_Alignment -
        'debug_opt' -
        /List/Show=All/Machine -
    bug.c
$ link bug.obj
$ exit


=======================================================

If I "run bug"
$ run bug
%SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual address=00000005,
PC
=0000041C, PSL=03C00004
%TRACE-F-TRACEBACK, symbolic stack dump follows
module name     routine name                     line       rel PC    abs PC

BUG             foobar                           1602      0000001C  0000041C
BUG             main                             1625      00000060  00000488


================

If I change compile.com to /optimize=disjoint, then this works fine... What
I've whittled it down to is the following line:

 1602               if ( pfoo->bar1 && (pfoo->bar1 == pfoo->bar2) &&
                           50 08 A1 32    000D          cvtwl   8(r1),r0
                                 13 13    0011          beql    noname.2
                           5C 0A A1 32    0013          cvtwl   10(r1),ap
                              5C 50 D1    0017          cmpl    r0,ap
                                 0A 12    001A          bneq    noname.2
                        04 AC 14 B1 D1    001C          cmpl    @20(r1),4(ap)
                                 03 13    0021          beql    noname.2

 1603                    ( pfoo->bbuf->next  - pfoo->bbuf->end))


The problem as I see it is @ 001C, where the (ap) now has a 1 in it and there
is a cmpl @ 4(1) or ACCVIO @ VA=00000005

============

Again, unfortuneately for me, in the larger module where I first see the
problem
simply changing the "disjoint" optimize value doesn't work, the code gets
optimized the same way (which doesn't make sense, but I'm still looking into
what that is).


======

What I'd like to hear is if in fact this is considered a bug? or is it just
another case of "coding practice" here @ Progress that I would have to be
on the watch for...

I'm sure I can work up a way around the problem, but my fear is that although
I found/fixed this one case, there would be others lurking which have been
optimized in the same manner.  Unfortunately, compiling /noopt is not a good
solution for all the code, since that would be a blow to performance...

Anyways, thanks in advance for the help.


John

FWIW: I am able to work around it as follows:

/* No bug */
    if ( pfoo->bar1 && (pfoo->bar1 == pfoo->bar2) )
    {
        BBUF *pbbuf = pfoo->bbuf;

        if ( pbbuf->next  - pbbuf->end )
        {
            printf ("No bug\n");
        }
    }

Note how I have to reference BBUF "directly"... It appears that the generated
code believes this was already done...

    
T.RTitleUserPersonal
Name
DateLines
1262.1Ask the customer to drop the trace keywordDECC::VMCCUTCHEONThu Feb 13 1997 12:1526
Yes, this is a bug and its reproducible in our development stream.  I will add
the problem to our bug list.  With the cut down example that
the customer gave you, I was able to work around the problem by
replacing the /debug=trace qualifier with /debug.  

with this command line, I get correct looking code,
(note that w now load the ap register at 002B)

$  cc/decc/Debug/opt=(noinline,NODISJOINT)/List/Machine note.c

2101               if ( pfoo->bar1 && (pfoo->bar1 == pfoo->bar2) &&
                           5C 08 A2 32    0018          cvtwl   8(r2),ap
                                 25 13    001C          beql    noname.2
                           50 08 A2 32    001E          cvtwl   8(r2),r0
                           5C 0A A2 32    0022          cvtwl   10(r2),ap
                              5C 50 D1    0026          cmpl    r0,ap
                                 18 12    0029          bneq    noname.2
                           5C 14 A2 D0    002B          movl    20(r2),ap
                        04 AC 14 B2 D1    002F          cmpl    @20(r2),4(ap)
                                 0D 13    0034          beql    noname.2

 2102                    ( pfoo->bbuf->next  - pfoo->bbuf->end))

thanks for reporting this.

--val