public inbox for jit@gcc.gnu.org
 help / color / mirror / Atom feed
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

  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).