From: Dibyendu Majumdar <mobile@majumdar.org.uk>
To: David Malcolm <dmalcolm@redhat.com>
Cc: jit@gcc.gnu.org
Subject: Re: A possible code generation issue
Date: Thu, 01 Jan 2015 00:00:00 -0000 [thread overview]
Message-ID: <CACXZuxfP_huMs8OFkutm7affRiRV7YK4vWZ1yBt5SMCp+hB8UQ@mail.gmail.com> (raw)
In-Reply-To: <CACXZuxceUXP7woZot1gy-ahscx+ime2X-Xi0YXUy7jK=j4wmWg@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1326 bytes --]
On 4 July 2015 at 23:09, Dibyendu Majumdar <mobile@majumdar.org.uk> wrote:
> On 4 July 2015 at 22:41, David Malcolm <dmalcolm@redhat.com> wrote:
>>> Adding the -fno-strict-aliasing appears to resolve the issue with -O2
>>> and -O3 but with this enabled the benchmarks are degraded.
>>
>> If "-fno-strict-aliasing" resolved this, then that suggests that there
>> are various casts in the code that if this were C would take us into
>> "undefined behavior" territory, and the optimizer is trying a little too
>> hard. This isn't C, but similar rules apply. If that's what this is,
>> then this is at least a documentation issue with libgccjit; we need to
>> document what the rules are.
>>
>>
>> Of course, it could well be a bug at my end.
>>
Dave,
Attached is a hacked version in C of the dump from the code. I thought
it might be useful to generate code directly using gcc -O3 -S on this
file - from what I can tell the generated code looks different from
what I am getting in libgccjit.
BTW the dump of types is problematic in many ways:
1) types are in wrong order
2) function types are incorrectly output
3) array types are incorrectly output
4) in one case as least a pointer was missing.
It would be useful if the generated dump was correct C so that it can
directly compiled in gcc.
Thanks and Regards
Dibyendu
[-- Attachment #2: bug.c --]
[-- Type: text/x-csrc, Size: 12320 bytes --]
#include <stdbool.h>
#include <stdlib.h>
struct ravi_lua_State;
struct ravi_lua_Debug;
struct ravi_GCObject;
union ravi_Value;
struct ravi_TValue;
struct ravi_TString;
struct ravi_Table;
struct ravi_Udata;
struct ravi_Upvaldesc;
struct ravi_LocVar;
struct ravi_LClosure;
struct ravi_RaviJITProto;
struct ravi_Proto;
struct ravi_UpVal;
struct ravi_CClosure;
union ravi_Closure;
struct ravi_TKey_nk;
union ravi_TKey;
struct ravi_Node;
struct ravi_RaviArray;
struct ravi_lua_longjmp;
struct ravi_Mbuffer;
struct ravi_stringtable;
struct ravi_CallInfo;
struct ravi_CallInfo_lua;
struct ravi_CallInfo_C;
union ravi_CallInfo_u;
struct ravi_State;
struct ravi_global_State;
struct ravi_UpVal_u_open;
union ravi_UpVal_u;
struct ravi_GCObject
{
struct ravi_GCObject * next;
unsigned char tt;
unsigned char marked;
};
union ravi_Value
{
struct ravi_GCObject * gc;
void * p;
int b;
int (*f) (struct ravi_lua_State *);
long long i;
double n;
};
struct ravi_TValue
{
union ravi_Value value_;
int tt_;
};
struct ravi_TString
{
struct ravi_GCObject * next;
unsigned char tt;
unsigned char marked;
unsigned char extra;
unsigned int hash;
size_t len;
struct ravi_TString * hash_next;
};
struct ravi_RaviArray
{
void * data;
unsigned int len;
unsigned int size;
unsigned char array_type;
unsigned char array_modifier;
};
struct ravi_Table
{
struct ravi_GCObject * next;
unsigned char tt;
unsigned char marked;
unsigned char flags;
unsigned char lsizenode;
unsigned int sizearray;
struct ravi_TValue * array;
struct ravi_Node * node;
struct ravi_Node * lastfree;
struct ravi_Table * metatable;
struct ravi_GCObject * gclist;
struct ravi_RaviArray ravi_array;
};
struct ravi_Udata
{
struct ravi_GCObject * next;
unsigned char tt;
unsigned char marked;
unsigned char ttuv_;
struct ravi_Table * metatable;
size_t len;
union ravi_Value user_;
};
struct ravi_Upvaldesc
{
struct ravi_TString * name;
int type;
unsigned char instack;
unsigned char idx;
};
struct ravi_LocVar
{
struct ravi_TString * varname;
int startpc;
int endpc;
int ravi_type;
};
struct ravi_LClosure
{
struct ravi_GCObject * next;
unsigned char tt;
unsigned char marked;
unsigned char nupvalues;
struct ravi_GCObject * gclist;
struct ravi_Proto * p;
struct ravi_UpVal *upvals[1];
};
struct ravi_RaviJITProto
{
unsigned char jit_status;
unsigned char jit_flags;
unsigned short execution_count;
void * jit_data;
int (* jit_function) (struct ravi_lua_State *);
};
struct ravi_Proto
{
struct ravi_GCObject * next;
unsigned char tt;
unsigned char marked;
unsigned char numparams;
unsigned char is_vararg;
unsigned char maxstacksize;
int sizeupvalues;
int sizek;
int sizecode;
int sizelineinfo;
int sizep;
int sizelocvars;
int linedefined;
int lastlinedefined;
struct ravi_TValue * k;
unsigned int * code;
struct ravi_Proto * * p;
int * lineinfo;
struct ravi_LocVar * locvars;
struct ravi_Upvaldesc * upvalues;
struct ravi_LClosure * cache;
struct ravi_TString * source;
struct ravi_GCObject * gclist;
struct ravi_RaviJITProto ravi_jit;
};
struct ravi_TKey_nk
{
union ravi_Value value_;
int tt_;
int next;
};
union ravi_TKey
{
struct ravi_TKey_nk nk;
struct ravi_TValue tvk;
};
struct ravi_Node
{
struct ravi_TValue i_val;
union ravi_TKey i_key;
};
struct ravi_Mbuffer
{
char * buffer;
size_t n;
size_t buffsize;
};
struct ravi_stringtable
{
struct ravi_TString * * hash;
int nuse;
int size;
};
struct ravi_CallInfo_lua
{
struct ravi_TValue * base;
unsigned int * savedpc;
};
struct ravi_CallInfo_C
{
int (*k) (struct ravi_lua_State *, int, long long);
long long old_errfunc;
long long ctx;
};
union ravi_CallInfo_u
{
struct ravi_CallInfo_lua l;
struct ravi_CallInfo_C c;
};
struct ravi_CClosure
{
struct ravi_GCObject * next;
unsigned char tt;
unsigned char marked;
unsigned char nupvalues;
struct ravi_GCObject * gclist;
int (*f) (struct ravi_lua_State *);
struct ravi_TValue upvalue[1];
};
union ravi_Closure
{
struct ravi_CClosure c;
struct ravi_LClosure l;
};
struct ravi_CallInfo
{
struct ravi_TValue * func;
struct ravi_TValue * top;
struct ravi_CallInfo * previous;
struct ravi_CallInfo * next;
union ravi_CallInfo_u u;
long long extra;
short nresults;
unsigned char callstatus;
};
struct ravi_lua_State
{
struct ravi_GCObject * next;
unsigned char tt;
unsigned char marked;
unsigned char status;
struct ravi_TValue * top;
struct ravi_global_State * l_G;
struct ravi_CallInfo * ci;
unsigned int * oldpc;
struct ravi_TValue * stack_last;
struct ravi_TValue * stack;
struct ravi_UpVal * openupval;
struct ravi_GCObject * gclist;
struct ravi_lua_State * twups;
struct ravi_lua_longjmp * errorJmp;
struct ravi_CallInfo base_ci;
void * (*hook) (struct ravi_lua_State *, struct ravi_lua_Debug *);
long long errfunc;
int stacksize;
int basehookcount;
int hookcount;
unsigned short nny;
unsigned short nCcalls;
unsigned char hookmask;
unsigned char allowhook;
};
struct ravi_UpVal_u_open
{
struct ravi_UpVal * next;
int touched;
};
union ravi_UpVal_u
{
struct ravi_UpVal_u_open open;
struct ravi_TValue value;
};
struct ravi_UpVal
{
struct ravi_TValue * v;
size_t refcount;
union ravi_UpVal_u u;
};
extern int
luaD_poscall (struct ravi_lua_State * L, struct ravi_TValue * firstResult); /* (imported) */
extern void
luaC_upvalbarrier_ (struct ravi_lua_State * L, struct ravi_UpVal * uv); /* (imported) */
extern int
luaD_precall (struct ravi_lua_State * L, struct ravi_TValue * func, int nresults); /* (imported) */
extern int
luaD_call (struct ravi_lua_State * L, struct ravi_TValue * func, int nresults, int allowyield); /* (imported) */
extern void
luaV_execute (struct ravi_lua_State * L); /* (imported) */
extern void
luaF_close (struct ravi_lua_State * L, struct ravi_TValue * level); /* (imported) */
extern int
luaV_equalobj (struct ravi_lua_State * L, const struct ravi_TValue * t1, const struct ravi_TValue * t2); /* (imported) */
extern int
luaV_lessthan (struct ravi_lua_State * L, const struct ravi_TValue * l, const struct ravi_TValue * r); /* (imported) */
extern int
luaV_lessequal (struct ravi_lua_State * L, const struct ravi_TValue * l, const struct ravi_TValue * r); /* (imported) */
extern void
luaG_runerror (struct ravi_lua_State * L, const char * fmt); /* (imported) */
extern int
luaV_forlimit (struct ravi_TValue * obj, long long * p, long long step, int * stopnow); /* (imported) */
extern int
luaV_tonumber_ (const struct ravi_TValue * obj, double * n); /* (imported) */
extern int
luaV_tointeger_ (const struct ravi_TValue * obj, long long * p); /* (imported) */
extern void
luaV_objlen (struct ravi_lua_State * L, struct ravi_TValue * ra, const struct ravi_TValue * rb); /* (imported) */
extern void
luaV_gettable (struct ravi_lua_State * L, const struct ravi_TValue * t, struct ravi_TValue * key, struct ravi_TValue * val); /* (imported) */
extern void
luaV_settable (struct ravi_lua_State * L, const struct ravi_TValue * t, struct ravi_TValue * key, struct ravi_TValue * val); /* (imported) */
extern void
luaT_trybinTM (struct ravi_lua_State * L, const struct ravi_TValue * p1, const struct ravi_TValue * p2, struct ravi_TValue * res, int event); /* (imported) */
extern void
raviV_op_loadnil (struct ravi_CallInfo * ci, int a, int b); /* (imported) */
extern void
raviV_op_newarrayint (struct ravi_lua_State * L, struct ravi_CallInfo * ci, struct ravi_TValue * ra); /* (imported) */
extern void
raviV_op_newarrayfloat (struct ravi_lua_State * L, struct ravi_CallInfo * ci, struct ravi_TValue * ra); /* (imported) */
extern void
raviV_op_newtable (struct ravi_lua_State * L, struct ravi_CallInfo * ci, struct ravi_TValue * ra, int b, int c); /* (imported) */
extern void
raviV_op_setlist (struct ravi_lua_State * L, struct ravi_CallInfo * ci, struct ravi_TValue * ra, int b, int c); /* (imported) */
extern long long
luaV_div (struct ravi_lua_State * L, long long m, long long n); /* (imported) */
extern long long
luaV_mod (struct ravi_lua_State * L, long long m, long long n); /* (imported) */
extern void
raviV_op_concat (struct ravi_lua_State * L, struct ravi_CallInfo * ci, int a, int b, int c); /* (imported) */
extern void
raviV_op_closure (struct ravi_lua_State * L, struct ravi_CallInfo * ci, struct ravi_LClosure * cl, int a, int Bx); /* (imported) */
extern void
raviV_op_vararg (struct ravi_lua_State * L, struct ravi_CallInfo * ci, struct ravi_LClosure * cl, int a, int b); /* (imported) */
extern void
raviH_set_int (struct ravi_lua_State * L, struct ravi_Table * table, unsigned int key, long long value); /* (imported) */
extern void
raviH_set_float (struct ravi_lua_State * L, struct ravi_Table * table, unsigned int key, double value); /* (imported) */
extern void
raviV_op_setupval (struct ravi_lua_State * L, struct ravi_LClosure * cl, struct ravi_TValue * ra, int b); /* (imported) */
//extern int
//printf (const char * format); /* (imported) */
extern int
ravif1 (struct ravi_lua_State * L)
{
struct ravi_LClosure * cl;
bool isfalse_0_4;
bool comparison_0_5;
bool comparison_0_6;
bool comparison_0_7;
bool isfalse_0_10;
bool comparison_0_11;
bool comparison_0_12;
bool comparison_0_13;
bool isfalse_0_16;
bool comparison_0_17;
bool comparison_0_18;
bool comparison_0_19;
bool comparison_0_22;
bool comparison_0_26;
entry:
cl = (struct ravi_LClosure *)L->ci->func->value_.gc;
(void)raviV_op_loadnil (L->ci, (int)0, (int)0);
(&L->ci->u.l.base[(int)1])->value_.i = (&cl->p->k[(int)0])->value_.i;
(&L->ci->u.l.base[(int)1])->tt_ = (&cl->p->k[(int)0])->tt_;
comparison_0_5 = (&L->ci->u.l.base[(int)1])->tt_ == (int)0;
comparison_0_6 = (&L->ci->u.l.base[(int)1])->tt_ == (int)1;
comparison_0_7 = (&L->ci->u.l.base[(int)1])->value_.b == (int)0;
isfalse_0_4 = comparison_0_5 || comparison_0_6 && comparison_0_7;
if (!(isfalse_0_4)) goto OP_TEST_do_jmp_2_8; else goto OP_TEST_do_skip_2_9;
jmp_5_1:
(&L->ci->u.l.base[(int)1])->value_.b = (int)0;
(&L->ci->u.l.base[(int)1])->tt_ = (int)1;
comparison_0_11 = (&L->ci->u.l.base[(int)1])->tt_ == (int)0;
comparison_0_12 = (&L->ci->u.l.base[(int)1])->tt_ == (int)1;
comparison_0_13 = (&L->ci->u.l.base[(int)1])->value_.b == (int)0;
isfalse_0_10 = comparison_0_11 || comparison_0_12 && comparison_0_13;
if (!(!(isfalse_0_10))) goto OP_TEST_do_jmp_5_14; else goto OP_TEST_do_skip_5_15;
jmp_9_2:
(&L->ci->u.l.base[(int)1])->value_.i = (&cl->p->k[(int)0])->value_.i;
(&L->ci->u.l.base[(int)1])->tt_ = (&cl->p->k[(int)0])->tt_;
comparison_0_17 = (&L->ci->u.l.base[(int)1])->tt_ == (int)0;
comparison_0_18 = (&L->ci->u.l.base[(int)1])->tt_ == (int)1;
comparison_0_19 = (&L->ci->u.l.base[(int)1])->value_.b == (int)0;
isfalse_0_16 = comparison_0_17 || comparison_0_18 && comparison_0_19;
if (!(isfalse_0_16)) goto OP_TEST_do_jmp_9_20; else goto OP_TEST_do_skip_9_21;
jmp_12_3:
(&L->ci->u.l.base[(int)1])->value_.b = (int)0;
(&L->ci->u.l.base[(int)1])->tt_ = (int)1;
L->top = &L->ci->u.l.base[(int)2];
comparison_0_22 = cl->p->sizep > (int)0;
if (comparison_0_22) goto OP_RETURN_if_sizep_gt_0_12_23; else goto OP_RETURN_else_sizep_gt_0_12_24;
OP_TEST_do_jmp_2_8:
goto jmp_5_1;
OP_TEST_do_skip_2_9:
goto jmp_5_1;
OP_TEST_do_jmp_5_14:
goto jmp_9_2;
OP_TEST_do_skip_5_15:
(&L->ci->u.l.base[(int)0])->value_.b = (int)1;
(&L->ci->u.l.base[(int)0])->tt_ = (int)1;
goto jmp_9_2;
OP_TEST_do_jmp_9_20:
goto jmp_12_3;
OP_TEST_do_skip_9_21:
goto jmp_12_3;
OP_RETURN_if_sizep_gt_0_12_23:
(void)luaF_close (L, L->ci->u.l.base);
goto OP_RETURN_else_sizep_gt_0_12_24;
OP_RETURN_else_sizep_gt_0_12_24:
(void)luaD_poscall (L, (&L->ci->u.l.base[(int)1]));
return (int)1;
LINK_BLOCK_13_25:
L->top = &L->ci->u.l.base[(int)0];
comparison_0_26 = cl->p->sizep > (int)0;
if (comparison_0_26) goto OP_RETURN_if_sizep_gt_0_13_27; else goto OP_RETURN_else_sizep_gt_0_13_28;
OP_RETURN_if_sizep_gt_0_13_27:
(void)luaF_close (L, L->ci->u.l.base);
goto OP_RETURN_else_sizep_gt_0_13_28;
OP_RETURN_else_sizep_gt_0_13_28:
(void)luaD_poscall (L, (&L->ci->u.l.base[(int)0]));
return (int)1;
}
[-- Attachment #3: bug.s --]
[-- Type: application/octet-stream, Size: 1959 bytes --]
.file "bug.c"
.section .text.unlikely,"ax",@progbits
.LCOLDB0:
.text
.LHOTB0:
.p2align 4,,15
.globl ravif1
.type ravif1, @function
ravif1:
.LFB10:
.cfi_startproc
.L2:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
pushq %rbx
.cfi_def_cfa_offset 24
.cfi_offset 3, -24
movq %rdi, %rbx
xorl %edx, %edx
xorl %esi, %esi
subq $8, %rsp
.cfi_def_cfa_offset 32
movq 32(%rdi), %rdi
movq (%rdi), %rax
movq (%rax), %rbp
call raviV_op_loadnil
movq 32(%rbx), %rax
movq 24(%rbp), %rdx
movq 32(%rax), %rax
movq 48(%rdx), %rdx
movq (%rdx), %rdx
movq %rdx, 16(%rax)
movq 24(%rbp), %rcx
movq 32(%rbx), %rax
movq 48(%rcx), %rcx
movq 32(%rax), %rdx
movl 8(%rcx), %ecx
movl %ecx, 24(%rdx)
movq 32(%rax), %rax
movl $0, 16(%rax)
movq 32(%rbx), %rax
movq 32(%rax), %rdx
movl $1, 24(%rdx)
movq 32(%rax), %rax
movl 24(%rax), %edx
testl %edx, %edx
je .L5
movl 16(%rax), %ecx
testl %ecx, %ecx
jne .L4
cmpl $1, %edx
je .L5
.L4:
movl $1, (%rax)
movq 32(%rbx), %rax
movq 32(%rax), %rdx
movl $1, 8(%rdx)
movq 32(%rax), %rax
.L3:
.L5:
movq 24(%rbp), %rdx
movq 48(%rdx), %rdx
movq (%rdx), %rdx
movq %rdx, 16(%rax)
movq 24(%rbp), %rcx
movq 32(%rbx), %rax
movq 48(%rcx), %rcx
movq 32(%rax), %rdx
movl 8(%rcx), %ecx
movl %ecx, 24(%rdx)
movq 32(%rax), %rax
movl $0, 16(%rax)
movq 32(%rbx), %rax
movq 32(%rax), %rdx
movl $1, 24(%rdx)
movq 32(%rax), %rdi
leaq 32(%rdi), %rdx
movq %rdx, 16(%rbx)
movq 24(%rbp), %rdx
movl 32(%rdx), %edx
testl %edx, %edx
jle .L6
.L7:
movq 32(%rax), %rsi
movq %rbx, %rdi
call luaF_close
movq 32(%rbx), %rax
.L6:
movq 32(%rax), %rsi
movq %rbx, %rdi
addq $16, %rsi
call luaD_poscall
addq $8, %rsp
.cfi_def_cfa_offset 24
movl $1, %eax
popq %rbx
.cfi_def_cfa_offset 16
popq %rbp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE10:
.size ravif1, .-ravif1
.section .text.unlikely
.LCOLDE0:
.text
.LHOTE0:
.ident "GCC: (GNU) 5.1.1 20150704"
.section .note.GNU-stack,"",@progbits
next prev parent reply other threads:[~2015-07-06 21:29 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-01 0:00 Dibyendu Majumdar
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` Filed PR jit/66812 for the " David Malcolm
2015-01-01 0:00 ` David Malcolm
2015-01-01 0:00 ` David Malcolm
2015-01-01 0:00 ` David Malcolm
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` David Malcolm
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` David Malcolm
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` David Malcolm
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` David Malcolm
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` David Malcolm
2015-01-01 0:00 ` [PATCH] PR jit/66812: Candidate fix for for the code generation issue, v1 David Malcolm
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` David Malcolm
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` David Malcolm
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` Filed PR jit/66812 for the code generation issue Dibyendu Majumdar
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` David Malcolm
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` David Malcolm
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` David Malcolm
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` A possible " David Malcolm
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` Dibyendu Majumdar [this message]
2015-01-01 0:00 ` Dibyendu Majumdar
2015-01-01 0:00 ` PR jit/66783 (Re: A possible code generation issue) David Malcolm
2015-01-01 0:00 ` [PATCH, committed] PR jit/66783: prevent use of opaque structs David Malcolm
2015-01-01 0:00 ` Filed PR jit/66811: jit jumps aren't compilable as C (Re: A possible code generation issue) David Malcolm
2015-01-01 0:00 ` Filed PR jit/66811: jit dumps " David Malcolm
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CACXZuxfP_huMs8OFkutm7affRiRV7YK4vWZ1yBt5SMCp+hB8UQ@mail.gmail.com \
--to=mobile@majumdar.org.uk \
--cc=dmalcolm@redhat.com \
--cc=jit@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).