int main(void) {
  struct A {
    int a;
    union {
      char b[5];
      char c;
    } d;
    short e;
  } s = {1, {"abcd"}, 2}, q = s;
  int m[3][2][1] = {
      {{'A'}, {'B'}},
      {
          {'C'},
      },
  };
  char msg1[] = "hello world!";
  char msg2[] = {"hello again!"};
  struct {
    char nonz1;
    short nonz2;
    int nonz3;
    char z1;
    short z2;
    int z3;
  } sz = {1, 1, 1};
  printf("%d %s %c %d\n", q.a, s.d.b, q.d.c, s.e);
  printf("%c %c %c %d\n", m[0][0][0], m[0][1][0], m[1][0][0], m[2][1][0]);
  printf("%s\n", msg1);
  printf("%s\n", msg2);
  printf("%d %d %d %d %d %d\n", sz.nonz1, sz.nonz2, sz.nonz3, sz.z1, sz.z2,
         sz.z3);
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
movl   $0x0,-0x4(%rbp)
mov    0xed7(%rip),%rax
mov    %rax,-0x10(%rbp)
mov    0xed5(%rip),%eax
mov    %eax,-0x8(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x8(%rbp),%eax
mov    %eax,-0x18(%rbp)
mov    0xec5(%rip),%rax
mov    %rax,-0x40(%rbp)
mov    0xec2(%rip),%rax
mov    %rax,-0x38(%rbp)
mov    0xebf(%rip),%rax
mov    %rax,-0x30(%rbp)
mov    0xebc(%rip),%rax
mov    %rax,-0x4d(%rbp)
mov    0xeba(%rip),%eax
mov    %eax,-0x45(%rbp)
mov    0xeb5(%rip),%al
mov    %al,-0x41(%rbp)
mov    0xeac(%rip),%rax
mov    %rax,-0x5a(%rbp)
mov    0xeaa(%rip),%eax
mov    %eax,-0x52(%rbp)
mov    0xea5(%rip),%al
mov    %al,-0x4e(%rbp)
mov    0xece(%rip),%rax
mov    %rax,-0x70(%rbp)
mov    0xecb(%rip),%rax
mov    %rax,-0x68(%rbp)
mov    -0x20(%rbp),%esi
lea    -0x10(%rbp),%rdx
add    $0x4,%rdx
movsbl -0x1c(%rbp),%ecx
movswl -0x6(%rbp),%r8d
lea    0xe72(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x40(%rbp),%esi
mov    -0x3c(%rbp),%edx
mov    -0x38(%rbp),%ecx
mov    -0x2c(%rbp),%r8d
lea    0xe64(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
lea    -0x4d(%rbp),%rsi
lea    0xe5f(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
lea    -0x5a(%rbp),%rsi
lea    0xe4d(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
movsbl -0x70(%rbp),%esi
movswl -0x6e(%rbp),%edx
mov    -0x6c(%rbp),%ecx
movsbl -0x68(%rbp),%r8d
movswl -0x66(%rbp),%r9d
mov    -0x64(%rbp),%eax
lea    0xe2b(%rip),%rdi
mov    %eax,(%rsp)
mov    $0x0,%al
call   1030 <printf@plt>
xor    %eax,%eax
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
sub    $0x38,%rsp
mov    0xede(%rip),%eax
mov    %eax,0x10(%rsp)
mov    0xecb(%rip),%rax
mov    %rax,0x8(%rsp)
lea    0xc(%rsp),%rdx
movabs $0x21646c726f7720,%rax
mov    %rax,0x2d(%rsp)
movabs $0x6f77206f6c6c6568,%rax
20 77 6f
mov    %rax,0x28(%rsp)
movabs $0x216e6961676120,%rax
mov    %rax,0x1d(%rsp)
movabs $0x6761206f6c6c6568,%rax
20 61 67
mov    %rax,0x18(%rsp)
lea    0xea4(%rip),%rdi
mov    $0x1,%esi
mov    $0x61,%ecx
mov    $0x2,%r8d
xor    %eax,%eax
call   1040 <printf@plt>
lea    0xe93(%rip),%rdi
mov    $0x41,%esi
mov    $0x42,%edx
mov    $0x43,%ecx
xor    %r8d,%r8d
xor    %eax,%eax
call   1040 <printf@plt>
lea    0x28(%rsp),%rdi
call   1030 <puts@plt>
lea    0x18(%rsp),%rdi
call   1030 <puts@plt>
movl   $0x0,(%rsp)
lea    0xe65(%rip),%rdi
mov    $0x1,%esi
mov    $0x1,%edx
mov    $0x1,%ecx
xor    %r8d,%r8d
xor    %r9d,%r9d
xor    %eax,%eax
call   1040 <printf@plt>
xor    %eax,%eax
add    $0x38,%rsp
ret

LLVM IR (-O0):
%struct.A = type { i32, %union.anon, i16 }
%union.anon = type { [5 x i8] }
%struct.anon = type { i8, i16, i32, i8, i16, i32 }
@__const.main.s = %struct.A { i32 1, %union.anon { [5 x i8] c"abcd\00" }, i16 2 }
@__const.main.m = [3 x [2 x [1 x i32]]] [[2 x [1 x i32]] [[1 x i32] [i32 65], [1 x i32] [i32 66]], [2 x [1 x i32]] [[1 x i32] [i32 67], [1 x i32] zeroinitializer], [2 x [1 x i32]] zeroinitializer]
@__const.main.msg1 = [13 x i8] c"hello world!\00"
@__const.main.msg2 = [13 x i8] c"hello again!\00"
@__const.main.sz = %struct.anon { i8 1, i16 1, i32 1, i8 0, i16 0, i32 0 }
@.str = [13 x i8] c"%d %s %c %d\0A\00"
@.str.1 = [13 x i8] c"%c %c %c %d\0A\00"
@.str.2 = [4 x i8] c"%s\0A\00"
@.str.3 = [19 x i8] c"%d %d %d %d %d %d\0A\00"
define i32 @main() {
%1 = alloca i32
%2 = alloca %struct.A
%3 = alloca %struct.A
%4 = alloca [3 x [2 x [1 x i32]]]
%5 = alloca [13 x i8]
%6 = alloca [13 x i8]
%7 = alloca %struct.anon
store i32 0, i32* %1
%8 = bitcast %struct.A* %2 to i8*
%9 = bitcast %struct.A* %3 to i8*
%10 = bitcast %struct.A* %2 to i8*
%11 = bitcast [3 x [2 x [1 x i32]]]* %4 to i8*
%12 = bitcast [13 x i8]* %5 to i8*
%13 = bitcast [13 x i8]* %6 to i8*
%14 = bitcast %struct.anon* %7 to i8*
%15 = getelementptr inbounds %struct.A, %struct.A* %3, i32 0, i32 0
%16 = load i32, i32* %15
%17 = getelementptr inbounds %struct.A, %struct.A* %2, i32 0, i32 1
%18 = bitcast %union.anon* %17 to [5 x i8]*
%19 = getelementptr inbounds [5 x i8], [5 x i8]* %18, i64 0, i64 0
%20 = getelementptr inbounds %struct.A, %struct.A* %3, i32 0, i32 1
%21 = bitcast %union.anon* %20 to i8*
%22 = load i8, i8* %21
%23 = sext i8 %22 to i32
%24 = getelementptr inbounds %struct.A, %struct.A* %2, i32 0, i32 2
%25 = load i16, i16* %24
%26 = sext i16 %25 to i32
%27 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i32 %16, i8* %19, i32 %23, i32 %26)
%28 = getelementptr inbounds [3 x [2 x [1 x i32]]], [3 x [2 x [1 x i32]]]* %4, i64 0, i64 0
%29 = getelementptr inbounds [2 x [1 x i32]], [2 x [1 x i32]]* %28, i64 0, i64 0
%30 = getelementptr inbounds [1 x i32], [1 x i32]* %29, i64 0, i64 0
%31 = load i32, i32* %30
%32 = getelementptr inbounds [3 x [2 x [1 x i32]]], [3 x [2 x [1 x i32]]]* %4, i64 0, i64 0
%33 = getelementptr inbounds [2 x [1 x i32]], [2 x [1 x i32]]* %32, i64 0, i64 1
%34 = getelementptr inbounds [1 x i32], [1 x i32]* %33, i64 0, i64 0
%35 = load i32, i32* %34
%36 = getelementptr inbounds [3 x [2 x [1 x i32]]], [3 x [2 x [1 x i32]]]* %4, i64 0, i64 1
%37 = getelementptr inbounds [2 x [1 x i32]], [2 x [1 x i32]]* %36, i64 0, i64 0
%38 = getelementptr inbounds [1 x i32], [1 x i32]* %37, i64 0, i64 0
%39 = load i32, i32* %38
%40 = getelementptr inbounds [3 x [2 x [1 x i32]]], [3 x [2 x [1 x i32]]]* %4, i64 0, i64 2
%41 = getelementptr inbounds [2 x [1 x i32]], [2 x [1 x i32]]* %40, i64 0, i64 1
%42 = getelementptr inbounds [1 x i32], [1 x i32]* %41, i64 0, i64 0
%43 = load i32, i32* %42
%44 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i64 0, i64 0), i32 %31, i32 %35, i32 %39, i32 %43)
%45 = getelementptr inbounds [13 x i8], [13 x i8]* %5, i64 0, i64 0
%46 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), i8* %45)
%47 = getelementptr inbounds [13 x i8], [13 x i8]* %6, i64 0, i64 0
%48 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), i8* %47)
%49 = getelementptr inbounds %struct.anon, %struct.anon* %7, i32 0, i32 0
%50 = load i8, i8* %49
%51 = sext i8 %50 to i32
%52 = getelementptr inbounds %struct.anon, %struct.anon* %7, i32 0, i32 1
%53 = load i16, i16* %52
%54 = sext i16 %53 to i32
%55 = getelementptr inbounds %struct.anon, %struct.anon* %7, i32 0, i32 2
%56 = load i32, i32* %55
%57 = getelementptr inbounds %struct.anon, %struct.anon* %7, i32 0, i32 3
%58 = load i8, i8* %57
%59 = sext i8 %58 to i32
%60 = getelementptr inbounds %struct.anon, %struct.anon* %7, i32 0, i32 4
%61 = load i16, i16* %60
%62 = sext i16 %61 to i32
%63 = getelementptr inbounds %struct.anon, %struct.anon* %7, i32 0, i32 5
%64 = load i32, i32* %63
%65 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.3, i64 0, i64 0), i32 %51, i32 %54, i32 %56, i32 %59, i32 %62, i32 %64)
ret i32 0
}

LLVM IR (-O2):
%struct.A = type { i32, %union.anon, i16 }
%union.anon = type { [5 x i8] }
@__const.main.s = %struct.A { i32 1, %union.anon { [5 x i8] c"abcd\00" }, i16 2 }
@__const.main.msg1 = [13 x i8] c"hello world!\00"
@__const.main.msg2 = [13 x i8] c"hello again!\00"
@.str = [13 x i8] c"%d %s %c %d\0A\00"
@.str.1 = [13 x i8] c"%c %c %c %d\0A\00"
@.str.3 = [19 x i8] c"%d %d %d %d %d %d\0A\00"
define i32 @main() {
%1 = alloca %struct.A
%2 = alloca [13 x i8]
%3 = alloca [13 x i8]
%4 = bitcast %struct.A* %1 to i8*
%5 = getelementptr inbounds %struct.A, %struct.A* %1, i64 0, i32 1, i32 0, i64 0
%6 = getelementptr inbounds [13 x i8], [13 x i8]* %2, i64 0, i64 0
%7 = getelementptr inbounds [13 x i8], [13 x i8]* %3, i64 0, i64 0
%8 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i32 1, i8* %5, i32 97, i32 2)
%9 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i64 0, i64 0), i32 65, i32 66, i32 67, i32 0)
%10 = call i32 @puts(i8* %6)
%11 = call i32 @puts(i8* %7)
%12 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([19 x i8], [19 x i8]* @.str.3, i64 0, i64 0), i32 1, i32 1, i32 1, i32 0, i32 0, i32 0)
ret i32 0
}