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
#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:
bug.s
Description: Binary data