#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 */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ abort();
void foo(int N) {
  int i, j;
  int x[1000][1000];
  for (i = 0; i < N; i++)
    for (j = 0; j < N; j++)
      x[i][j] = i + j + 3;
  for (i = 0; i < N; i++)
    for (j = 0; j < N; j++)
      if (x[i][j] != i + j + 3)
        abort();
}


x86 assembly (clang, -O0):
<foo>:
push   %rbp
mov    %rsp,%rbp
sub    $0x3d0910,%rsp
mov    %edi,-0x4(%rbp)
movl   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    118a <foo+0x7a>
movl   $0x0,-0xc(%rbp)
mov    -0xc(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    1177 <foo+0x67>
mov    -0x8(%rbp),%edx
add    -0xc(%rbp),%edx
add    $0x3,%edx
movslq -0x8(%rbp),%rcx
lea    -0x3d0910(%rbp),%rax
imul   $0xfa0,%rcx,%rcx
add    %rcx,%rax
movslq -0xc(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    1138 <foo+0x28>
jmp    117c <foo+0x6c>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    1125 <foo+0x15>
movl   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    120a <foo+0xfa>
movl   $0x0,-0xc(%rbp)
mov    -0xc(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    11f7 <foo+0xe7>
movslq -0x8(%rbp),%rcx
lea    -0x3d0910(%rbp),%rax
imul   $0xfa0,%rcx,%rcx
add    %rcx,%rax
movslq -0xc(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    -0x8(%rbp),%ecx
add    -0xc(%rbp),%ecx
add    $0x3,%ecx
cmp    %ecx,%eax
je     11e4 <foo+0xd4>
mov    $0x0,%al
call   1030 <abort@plt>
jmp    11e9 <foo+0xd9>
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    11a4 <foo+0x94>
jmp    11fc <foo+0xec>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    1191 <foo+0x81>
add    $0x3d0910,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<foo>:
push   %r15
push   %r14
push   %rbx
sub    $0x3d0900,%rsp
test   %edi,%edi
jle    134f <foo+0x23f>
mov    %edi,%r15d
mov    %r15d,%r11d
and    $0xfffffff8,%r11d
lea    -0x8(%r11),%r9
mov    %r9,%r10
shr    $0x3,%r10
add    $0x1,%r10
mov    %r10,%r8
and    $0xfffffffffffffffe,%r8
lea    0x30(%rsp),%rdx
mov    %rsp,%rsi
mov    $0x3,%ecx
xor    %r14d,%r14d
movdqa 0xea3(%rip),%xmm8
movdqa 0xeaa(%rip),%xmm9
movdqa 0xeb1(%rip),%xmm10
movdqa 0xeb8(%rip),%xmm11
jmp    119f <foo+0x8f>
nopw   0x0(%rax,%rax,1)
add    $0x1,%r14
add    $0xfa0,%rdx
add    $0xfa0,%rsi
add    $0x1,%rcx
cmp    %r15,%r14
je     12f8 <foo+0x1e8>
cmp    $0x8,%edi
jae    11b0 <foo+0xa0>
xor    %eax,%eax
jmp    12d0 <foo+0x1c0>
nopl   0x0(%rax,%rax,1)
lea    0x3(%r14),%rax
movq   %rax,%xmm4
pshufd $0x44,%xmm4,%xmm3
test   %r9,%r9
je     12e4 <foo+0x1d4>
lea    0x7(%r14),%rax
movq   %rax,%xmm5
pshufd $0x44,%xmm5,%xmm2
mov    %r8,%rax
xor    %ebx,%ebx
movdqa %xmm9,%xmm5
movdqa %xmm8,%xmm6
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movdqa %xmm3,%xmm4
paddq  %xmm5,%xmm4
movdqa %xmm3,%xmm0
paddq  %xmm6,%xmm0
shufps $0x88,%xmm0,%xmm4
movdqa %xmm2,%xmm0
paddq  %xmm5,%xmm0
movdqa %xmm2,%xmm7
paddq  %xmm6,%xmm7
shufps $0x88,%xmm7,%xmm0
movaps %xmm4,-0x30(%rdx,%rbx,4)
movaps %xmm0,-0x20(%rdx,%rbx,4)
movdqa %xmm6,%xmm0
paddq  %xmm10,%xmm0
movdqa %xmm5,%xmm4
paddq  %xmm10,%xmm4
movdqa %xmm3,%xmm7
paddq  %xmm4,%xmm7
movdqa %xmm3,%xmm1
paddq  %xmm0,%xmm1
shufps $0x88,%xmm1,%xmm7
paddq  %xmm2,%xmm4
paddq  %xmm2,%xmm0
shufps $0x88,%xmm0,%xmm4
movaps %xmm7,-0x10(%rdx,%rbx,4)
movaps %xmm4,(%rdx,%rbx,4)
add    $0x10,%rbx
paddq  %xmm11,%xmm5
paddq  %xmm11,%xmm6
add    $0xfffffffffffffffe,%rax
jne    11f0 <foo+0xe0>
test   $0x1,%r10b
je     12b7 <foo+0x1a7>
movdqa %xmm3,%xmm0
paddq  %xmm5,%xmm0
paddq  %xmm6,%xmm3
shufps $0x88,%xmm3,%xmm0
lea    0x7(%r14),%eax
movd   %eax,%xmm1
pshufd $0x44,%xmm1,%xmm1
paddq  %xmm1,%xmm6
paddq  %xmm5,%xmm1
shufps $0x88,%xmm6,%xmm1
imul   $0xfa0,%r14,%rax
add    %rsp,%rax
movaps %xmm0,(%rax,%rbx,4)
movaps %xmm1,0x10(%rax,%rbx,4)
mov    %r11,%rax
cmp    %r15,%r11
je     1180 <foo+0x70>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
lea    (%rcx,%rax,1),%ebx
mov    %ebx,(%rsi,%rax,4)
add    $0x1,%rax
cmp    %rax,%r15
jne    12d0 <foo+0x1c0>
jmp    1180 <foo+0x70>
xor    %ebx,%ebx
movdqa %xmm9,%xmm5
movdqa %xmm8,%xmm6
test   $0x1,%r10b
jne    127b <foo+0x16b>
jmp    12b7 <foo+0x1a7>
test   %edi,%edi
jle    134f <foo+0x23f>
mov    %r15,%rax
neg    %rax
mov    %rsp,%rcx
xor    %edx,%edx
nopw   0x0(%rax,%rax,1)
mov    $0x3,%esi
cs nopw 0x0(%rax,%rax,1)
nop
mov    -0xc(%rcx,%rsi,4),%edi
lea    (%rdx,%rsi,1),%rbx
cmp    %rdi,%rbx
jne    135c <foo+0x24c>
lea    (%rax,%rsi,1),%rdi
add    $0x1,%rdi
add    $0x1,%rsi
cmp    $0x3,%rdi
jne    1320 <foo+0x210>
add    $0x1,%rdx
add    $0xfa0,%rcx
cmp    %r15,%rdx
jne    1310 <foo+0x200>
add    $0x3d0900,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret
xor    %eax,%eax
call   1030 <abort@plt>

LLVM IR (-O0):
define void @foo(i32 %0) {
%2 = alloca i32
%3 = alloca i32
%4 = alloca i32
%5 = alloca [1000 x [1000 x i32]]
store i32 %0, i32* %2
store i32 0, i32* %3
br label %6
6: ; preds = %30, %1
%7 = load i32, i32* %3
%8 = load i32, i32* %2
%9 = icmp slt i32 %7, %8
br i1 %9, label %10, label %33
10: ; preds = %6
store i32 0, i32* %4
br label %11
11: ; preds = %26, %10
%12 = load i32, i32* %4
%13 = load i32, i32* %2
%14 = icmp slt i32 %12, %13
br i1 %14, label %15, label %29
15: ; preds = %11
%16 = load i32, i32* %3
%17 = load i32, i32* %4
%18 = add nsw i32 %16, %17
%19 = add nsw i32 %18, 3
%20 = load i32, i32* %3
%21 = sext i32 %20 to i64
%22 = getelementptr inbounds [1000 x [1000 x i32]], [1000 x [1000 x i32]]* %5, i64 0, i64 %21
%23 = load i32, i32* %4
%24 = sext i32 %23 to i64
%25 = getelementptr inbounds [1000 x i32], [1000 x i32]* %22, i64 0, i64 %24
store i32 %19, i32* %25
br label %26
26: ; preds = %15
%27 = load i32, i32* %4
%28 = add nsw i32 %27, 1
store i32 %28, i32* %4
br label %11
29: ; preds = %11
br label %30
30: ; preds = %29
%31 = load i32, i32* %3
%32 = add nsw i32 %31, 1
store i32 %32, i32* %3
br label %6
33: ; preds = %6
store i32 0, i32* %3
br label %34
34: ; preds = %63, %33
%35 = load i32, i32* %3
%36 = load i32, i32* %2
%37 = icmp slt i32 %35, %36
br i1 %37, label %38, label %66
38: ; preds = %34
store i32 0, i32* %4
br label %39
39: ; preds = %59, %38
%40 = load i32, i32* %4
%41 = load i32, i32* %2
%42 = icmp slt i32 %40, %41
br i1 %42, label %43, label %62
43: ; preds = %39
%44 = load i32, i32* %3
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds [1000 x [1000 x i32]], [1000 x [1000 x i32]]* %5, i64 0, i64 %45
%47 = load i32, i32* %4
%48 = sext i32 %47 to i64
%49 = getelementptr inbounds [1000 x i32], [1000 x i32]* %46, i64 0, i64 %48
%50 = load i32, i32* %49
%51 = load i32, i32* %3
%52 = load i32, i32* %4
%53 = add nsw i32 %51, %52
%54 = add nsw i32 %53, 3
%55 = icmp ne i32 %50, %54
br i1 %55, label %56, label %58
56: ; preds = %43
%57 = call i32 (...) @abort()
unreachable
58: ; preds = %43
br label %59
59: ; preds = %58
%60 = load i32, i32* %4
%61 = add nsw i32 %60, 1
store i32 %61, i32* %4
br label %39
62: ; preds = %39
br label %63
63: ; preds = %62
%64 = load i32, i32* %3
%65 = add nsw i32 %64, 1
store i32 %65, i32* %3
br label %34
66: ; preds = %34
ret void
}

LLVM IR (-O2):
define void @foo(i32 %0) {
%2 = alloca [1000 x [1000 x i32]]
%3 = bitcast [1000 x [1000 x i32]]* %2 to i8*
%4 = icmp sgt i32 %0, 0
br i1 %4, label %5, label %106
5: ; preds = %1
%6 = zext i32 %0 to i64
%7 = and i64 %6, 4294967288
%8 = add nsw i64 %7, -8
%9 = lshr exact i64 %8, 3
%10 = add nuw nsw i64 %9, 1
%11 = icmp ult i32 %0, 8
%12 = and i64 %6, 4294967288
%13 = and i64 %10, 1
%14 = icmp eq i64 %8, 0
%15 = and i64 %10, 4611686018427387902
%16 = icmp eq i64 %13, 0
%17 = icmp eq i64 %12, %6
br label %18
18: ; preds = %85, %5
%19 = phi i64 [ 0, %5 ], [ %86, %85 ]
%20 = add nuw nsw i64 %19, 3
br i1 %11, label %73, label %21
21: ; preds = %18
%22 = insertelement <4 x i64> poison, i64 %20, i64 0
%23 = shufflevector <4 x i64> %22, <4 x i64> poison, <4 x i32> zeroinitializer
br i1 %14, label %57, label %24
24: ; preds = %21
%25 = add nuw i64 %19, 7
%26 = insertelement <4 x i64> poison, i64 %25, i64 0
%27 = shufflevector <4 x i64> %26, <4 x i64> poison, <4 x i32> zeroinitializer
%28 = add nuw i64 %19, 7
%29 = insertelement <4 x i64> poison, i64 %28, i64 0
%30 = shufflevector <4 x i64> %29, <4 x i64> poison, <4 x i32> zeroinitializer
br label %31
31: ; preds = %31, %24
%32 = phi i64 [ 0, %24 ], [ %53, %31 ]
%33 = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, %24 ], [ %54, %31 ]
%34 = phi i64 [ 0, %24 ], [ %55, %31 ]
%35 = add nuw nsw <4 x i64> %23, %33
%36 = add <4 x i64> %27, %33
%37 = getelementptr inbounds [1000 x [1000 x i32]], [1000 x [1000 x i32]]* %2, i64 0, i64 %19, i64 %32
%38 = trunc <4 x i64> %35 to <4 x i32>
%39 = trunc <4 x i64> %36 to <4 x i32>
%40 = bitcast i32* %37 to <4 x i32>*
store <4 x i32> %38, <4 x i32>* %40
%41 = getelementptr inbounds i32, i32* %37, i64 4
%42 = bitcast i32* %41 to <4 x i32>*
store <4 x i32> %39, <4 x i32>* %42
%43 = or i64 %32, 8
%44 = add <4 x i64> %33, <i64 8, i64 8, i64 8, i64 8>
%45 = add nuw nsw <4 x i64> %23, %44
%46 = add <4 x i64> %30, %44
%47 = getelementptr inbounds [1000 x [1000 x i32]], [1000 x [1000 x i32]]* %2, i64 0, i64 %19, i64 %43
%48 = trunc <4 x i64> %45 to <4 x i32>
%49 = trunc <4 x i64> %46 to <4 x i32>
%50 = bitcast i32* %47 to <4 x i32>*
store <4 x i32> %48, <4 x i32>* %50
%51 = getelementptr inbounds i32, i32* %47, i64 4
%52 = bitcast i32* %51 to <4 x i32>*
store <4 x i32> %49, <4 x i32>* %52
%53 = add nuw i64 %32, 16
%54 = add <4 x i64> %33, <i64 16, i64 16, i64 16, i64 16>
%55 = add i64 %34, 2
%56 = icmp eq i64 %55, %15
br i1 %56, label %57, label %31
57: ; preds = %31, %21
%58 = phi i64 [ 0, %21 ], [ %53, %31 ]
%59 = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, %21 ], [ %54, %31 ]
br i1 %16, label %72, label %60
60: ; preds = %57
%61 = add nuw nsw <4 x i64> %23, %59
%62 = add nuw i64 %19, 7
%63 = insertelement <4 x i64> poison, i64 %62, i64 0
%64 = shufflevector <4 x i64> %63, <4 x i64> poison, <4 x i32> zeroinitializer
%65 = add <4 x i64> %64, %59
%66 = getelementptr inbounds [1000 x [1000 x i32]], [1000 x [1000 x i32]]* %2, i64 0, i64 %19, i64 %58
%67 = trunc <4 x i64> %61 to <4 x i32>
%68 = trunc <4 x i64> %65 to <4 x i32>
%69 = bitcast i32* %66 to <4 x i32>*
store <4 x i32> %67, <4 x i32>* %69
%70 = getelementptr inbounds i32, i32* %66, i64 4
%71 = bitcast i32* %70 to <4 x i32>*
store <4 x i32> %68, <4 x i32>* %71
br label %72
72: ; preds = %57, %60
br i1 %17, label %85, label %73
73: ; preds = %18, %72
%74 = phi i64 [ 0, %18 ], [ %12, %72 ]
br label %78
75: ; preds = %85
br i1 %4, label %76, label %106
76: ; preds = %75
%77 = zext i32 %0 to i64
br label %88
78: ; preds = %73, %78
%79 = phi i64 [ %83, %78 ], [ %74, %73 ]
%80 = add nuw nsw i64 %20, %79
%81 = getelementptr inbounds [1000 x [1000 x i32]], [1000 x [1000 x i32]]* %2, i64 0, i64 %19, i64 %79
%82 = trunc i64 %80 to i32
store i32 %82, i32* %81
%83 = add nuw nsw i64 %79, 1
%84 = icmp eq i64 %83, %6
br i1 %84, label %85, label %78
85: ; preds = %78, %72
%86 = add nuw nsw i64 %19, 1
%87 = icmp eq i64 %86, %6
br i1 %87, label %75, label %18
88: ; preds = %103, %76
%89 = phi i64 [ 0, %76 ], [ %104, %103 ]
%90 = add nuw nsw i64 %89, 3
br label %93
91: ; preds = %93
%92 = icmp eq i64 %100, %77
br i1 %92, label %103, label %93
93: ; preds = %88, %91
%94 = phi i64 [ 0, %88 ], [ %100, %91 ]
%95 = getelementptr inbounds [1000 x [1000 x i32]], [1000 x [1000 x i32]]* %2, i64 0, i64 %89, i64 %94
%96 = load i32, i32* %95
%97 = add nuw nsw i64 %90, %94
%98 = zext i32 %96 to i64
%99 = icmp eq i64 %97, %98
%100 = add nuw nsw i64 %94, 1
br i1 %99, label %91, label %101
101: ; preds = %93
%102 = tail call i32 (...) @abort()
unreachable
103: ; preds = %91
%104 = add nuw nsw i64 %89, 1
%105 = icmp eq i64 %104, %77
br i1 %105, label %106, label %88
106: ; preds = %103, %1, %75
ret void
}