This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] PR/14262 (ABI corner case confusion)


Jim Wilson wrote:

> > I've tried this with my test case, and it works; however it
> > generates abysmally bad code; the argument is read byte
> > per byte, and those bytes are then pasted together using
> > shifts and ors to form a 4-byte entity :-/
> 
> I am not seeing this.  I tried both your first and second testcases.
> For the first testcase, I get
> 	llgf	%r2,160(%r15)
> For the second testcase, I get
> 	lg	%r2,.L10-.L9(%r13)
> .L10:
> 	.quad	67305985
> where the quad operand in hex is 0x4030201

Those test cases were intended for -O0, if you build them with
optimization, it'll see through the artifical nature of the test.

> Actually, I see that the code is really bad if you compile
> unoptimized but I wouldn't worry about that.  If you want good code,
> then compile with -O.

I agree, but I'm getting really bad code even with -O3 in somewhat
more realistic tests, like the one appended below.

This results in 

        brasl   %r14,alloc
        llgc    %r4,0(%r2)
        llgc    %r14,1(%r2)
        sllg    %r5,%r4,24
        llgc    %r0,2(%r2)
        sllg    %r3,%r14,16
        ogr     %r3,%r5
        sllg    %r1,%r0,8
        ogr     %r1,%r3
        llgc    %r2,3(%r2)
        ogr     %r2,%r1
        brasl   %r14,verify

instead of

        brasl   %r14,alloc
        l       %r2,0(%r2)
        brasl   %r14,verify

or even

        brasl   %r14,alloc
        llfg    %r2,0(%r2)
        brasl   %r14,verify

Bye,
Ulrich


/* PR target/14262 */
/* { dg-do run } */

#include <sys/mman.h>

typedef char   ACS;
typedef char   LSM;
typedef char   PANEL;
typedef char   DRIVE;
typedef struct {
    ACS             acs;
    LSM             lsm;
} LSMID;
typedef struct {
    LSMID           lsm_id;
    PANEL           panel;
} PANELID;
typedef struct {
    PANELID         panel_id;
    DRIVE           drive;
} DRIVEID;

void __attribute__ ((__noinline__)) verify (DRIVEID driveid) 
{
  if (driveid.drive != 1)
    abort ();
  if (driveid.panel_id.panel != 2)
    abort ();
  if (driveid.panel_id.lsm_id.lsm != 3)
    abort ();
  if (driveid.panel_id.lsm_id.acs != 4)
    abort ();
}

DRIVEID * __attribute__ ((__noinline__)) alloc (void)
{
  DRIVEID *p;

  p = (DRIVEID *)mmap (0, 8192, PROT_READ|PROT_WRITE, 
		       MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
  if (p == (DRIVEID *)MAP_FAILED)
    exit (0);
  mprotect (p + 1024, 4096, PROT_NONE);

  p[1023].drive = 1;
  p[1023].panel_id.panel = 2;
  p[1023].panel_id.lsm_id.lsm = 3;
  p[1023].panel_id.lsm_id.acs = 4;

  return p + 1023;
}

int main (void)
{
  DRIVEID *p = alloc ();
  verify (*p);

  return 0;
}




-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]