#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */
typedef struct TYPE_6__ TYPE_3__;
typedef struct TYPE_5__ TYPE_2__;
typedef struct TYPE_4__ TYPE_1__;

/* Type definitions */
struct TYPE_6__ {
  int member_0;
  int member_1;
  int member_2;
  int member_3;
  int member_4;
};
struct TYPE_5__ {
  int member_0;
  int member_1;
  int member_2;
  int member_3;
  int member_4;
};
struct TYPE_4__ {
  int member_0;
  int member_1;
  int member_2;
  int member_3;
  int member_4;
};

/* Variables and functions */
int /*<<< orphan*/ func_1(int ***);
int /*<<< orphan*/ func_2(int ***);
int /*<<< orphan*/ func_3(int ***);
int main(void) {
  int a[2][3][5] = {
      {{10, 20, 30, 40, 50}, {60, 70, 80, 90, 100}, {110, 120, 130, 140, 150}},
      {{160, 170, 180, 190, 200},
       {210, 220, 230, 240, 250},
       {260, 270, 280, 290, 300}},
  };
  int(*p)[3][5] = a;
  int(*q)[2][3][5] = &a;
  func_1(a);
  func_2(a);
  func_3(a);
  func_1(p);
  func_2(p);
  func_3(p);
  func_1(*q);
  func_2(*q);
  func_3(*q);
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x90,%rsp
movl   $0x0,-0x4(%rbp)
lea    -0x80(%rbp),%rdi
lea    0xea3(%rip),%rsi
mov    $0x78,%edx
call   1040 <memcpy@plt>
lea    -0x80(%rbp),%rax
mov    %rax,-0x88(%rbp)
lea    -0x80(%rbp),%rax
mov    %rax,-0x90(%rbp)
lea    -0x80(%rbp),%rdi
call   1060 <func_1@plt>
lea    -0x80(%rbp),%rdi
call   1030 <func_2@plt>
lea    -0x80(%rbp),%rdi
call   1050 <func_3@plt>
mov    -0x88(%rbp),%rdi
call   1060 <func_1@plt>
mov    -0x88(%rbp),%rdi
call   1030 <func_2@plt>
mov    -0x88(%rbp),%rdi
call   1050 <func_3@plt>
mov    -0x90(%rbp),%rdi
call   1060 <func_1@plt>
mov    -0x90(%rbp),%rdi
call   1030 <func_2@plt>
mov    -0x90(%rbp),%rdi
call   1050 <func_3@plt>
xor    %eax,%eax
add    $0x90,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbx
sub    $0x80,%rsp
mov    0xf31(%rip),%rax
mov    %rax,0x70(%rsp)
movaps 0xf15(%rip),%xmm0
movaps %xmm0,0x60(%rsp)
movaps 0xef9(%rip),%xmm0
movaps %xmm0,0x50(%rsp)
movaps 0xedd(%rip),%xmm0
movaps %xmm0,0x40(%rsp)
movaps 0xec1(%rip),%xmm0
movaps %xmm0,0x30(%rsp)
movaps 0xea5(%rip),%xmm0
movaps %xmm0,0x20(%rsp)
movaps 0xe89(%rip),%xmm0
movaps %xmm0,0x10(%rsp)
movaps 0xe6d(%rip),%xmm0
movaps %xmm0,(%rsp)
mov    %rsp,%rbx
mov    %rbx,%rdi
call   1050 <func_1@plt>
mov    %rbx,%rdi
call   1030 <func_2@plt>
mov    %rbx,%rdi
call   1040 <func_3@plt>
mov    %rbx,%rdi
call   1050 <func_1@plt>
mov    %rbx,%rdi
call   1030 <func_2@plt>
mov    %rbx,%rdi
call   1040 <func_3@plt>
mov    %rbx,%rdi
call   1050 <func_1@plt>
mov    %rbx,%rdi
call   1030 <func_2@plt>
mov    %rbx,%rdi
call   1040 <func_3@plt>
xor    %eax,%eax
add    $0x80,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@__const.main.a = [2 x [3 x [5 x i32]]] [[3 x [5 x i32]] [[5 x i32] [i32 10, i32 20, i32 30, i32 40, i32 50], [5 x i32] [i32 60, i32 70, i32 80, i32 90, i32 100], [5 x i32] [i32 110, i32 120, i32 130, i32 140, i32 150]], [3 x [5 x i32]] [[5 x i32] [i32 160, i32 170, i32 180, i32 190, i32 200], [5 x i32] [i32 210, i32 220, i32 230, i32 240, i32 250], [5 x i32] [i32 260, i32 270, i32 280, i32 290, i32 300]]]
define i32 @main() {
%1 = alloca i32
%2 = alloca [2 x [3 x [5 x i32]]]
%3 = alloca [3 x [5 x i32]]*
%4 = alloca [2 x [3 x [5 x i32]]]*
store i32 0, i32* %1
%5 = bitcast [2 x [3 x [5 x i32]]]* %2 to i8*
%6 = getelementptr inbounds [2 x [3 x [5 x i32]]], [2 x [3 x [5 x i32]]]* %2, i64 0, i64 0
store [3 x [5 x i32]]* %6, [3 x [5 x i32]]** %3
store [2 x [3 x [5 x i32]]]* %2, [2 x [3 x [5 x i32]]]** %4
%7 = getelementptr inbounds [2 x [3 x [5 x i32]]], [2 x [3 x [5 x i32]]]* %2, i64 0, i64 0
%8 = bitcast [3 x [5 x i32]]* %7 to i32***
%9 = call i32 @func_1(i32*** %8)
%10 = getelementptr inbounds [2 x [3 x [5 x i32]]], [2 x [3 x [5 x i32]]]* %2, i64 0, i64 0
%11 = bitcast [3 x [5 x i32]]* %10 to i32***
%12 = call i32 @func_2(i32*** %11)
%13 = getelementptr inbounds [2 x [3 x [5 x i32]]], [2 x [3 x [5 x i32]]]* %2, i64 0, i64 0
%14 = bitcast [3 x [5 x i32]]* %13 to i32***
%15 = call i32 @func_3(i32*** %14)
%16 = load [3 x [5 x i32]]*, [3 x [5 x i32]]** %3
%17 = bitcast [3 x [5 x i32]]* %16 to i32***
%18 = call i32 @func_1(i32*** %17)
%19 = load [3 x [5 x i32]]*, [3 x [5 x i32]]** %3
%20 = bitcast [3 x [5 x i32]]* %19 to i32***
%21 = call i32 @func_2(i32*** %20)
%22 = load [3 x [5 x i32]]*, [3 x [5 x i32]]** %3
%23 = bitcast [3 x [5 x i32]]* %22 to i32***
%24 = call i32 @func_3(i32*** %23)
%25 = load [2 x [3 x [5 x i32]]]*, [2 x [3 x [5 x i32]]]** %4
%26 = getelementptr inbounds [2 x [3 x [5 x i32]]], [2 x [3 x [5 x i32]]]* %25, i64 0, i64 0
%27 = bitcast [3 x [5 x i32]]* %26 to i32***
%28 = call i32 @func_1(i32*** %27)
%29 = load [2 x [3 x [5 x i32]]]*, [2 x [3 x [5 x i32]]]** %4
%30 = getelementptr inbounds [2 x [3 x [5 x i32]]], [2 x [3 x [5 x i32]]]* %29, i64 0, i64 0
%31 = bitcast [3 x [5 x i32]]* %30 to i32***
%32 = call i32 @func_2(i32*** %31)
%33 = load [2 x [3 x [5 x i32]]]*, [2 x [3 x [5 x i32]]]** %4
%34 = getelementptr inbounds [2 x [3 x [5 x i32]]], [2 x [3 x [5 x i32]]]* %33, i64 0, i64 0
%35 = bitcast [3 x [5 x i32]]* %34 to i32***
%36 = call i32 @func_3(i32*** %35)
ret i32 0
}

LLVM IR (-O2):
@__const.main.a = [2 x [3 x [5 x i32]]] [[3 x [5 x i32]] [[5 x i32] [i32 10, i32 20, i32 30, i32 40, i32 50], [5 x i32] [i32 60, i32 70, i32 80, i32 90, i32 100], [5 x i32] [i32 110, i32 120, i32 130, i32 140, i32 150]], [3 x [5 x i32]] [[5 x i32] [i32 160, i32 170, i32 180, i32 190, i32 200], [5 x i32] [i32 210, i32 220, i32 230, i32 240, i32 250], [5 x i32] [i32 260, i32 270, i32 280, i32 290, i32 300]]]
define i32 @main() {
%1 = alloca [2 x [3 x [5 x i32]]]
%2 = bitcast [2 x [3 x [5 x i32]]]* %1 to i8*
%3 = bitcast [2 x [3 x [5 x i32]]]* %1 to i32***
%4 = call i32 @func_1(i32*** %3)
%5 = call i32 @func_2(i32*** %3)
%6 = call i32 @func_3(i32*** %3)
%7 = call i32 @func_1(i32*** %3)
%8 = call i32 @func_2(i32*** %3)
%9 = call i32 @func_3(i32*** %3)
%10 = call i32 @func_1(i32*** %3)
%11 = call i32 @func_2(i32*** %3)
%12 = call i32 @func_3(i32*** %3)
ret i32 0
}