#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*/ memcpy(char *, char *, int);
int /*<<< orphan*/ report(int);
signed long test_array(int i) {
  char a1[] = "This test string MUST NOT be modified...";
  char a2[100];
  report(a1[5]);
  memcpy(a2, a1, 40);
  report(a1[5]);
  report(a2[5]);
  report(i);
  i += a2[0] + a2[1] + a2[2] + a2[3] + a2[4] + a2[5] + a2[6] + a2[7] + a2[8] +
       a2[9] + a2[10] + a2[11] + a2[12] + a2[13] + a2[14] + a2[15] + a2[16] +
       a2[17] + a2[18] + a2[19] + a2[20] + a2[21] + a2[22] + a2[23] + a2[24] +
       a2[25] + a2[26] + a2[27] + a2[28] + a2[29] + a2[30] + a2[31] + a2[32] +
       a2[33] + a2[34] + a2[35] + a2[36] + a2[37] + a2[38] + a2[39];
  report(i);
  return i;
}


x86 assembly (clang, -O0):
<test_array>:
push   %rbp
mov    %rsp,%rbp
sub    $0xa0,%rsp
mov    %edi,-0x4(%rbp)
lea    -0x30(%rbp),%rdi
lea    0xec7(%rip),%rsi
mov    $0x29,%edx
call   1030 <memcpy@plt>
movsbl -0x2b(%rbp),%edi
call   1040 <report@plt>
lea    -0xa0(%rbp),%rdi
lea    -0x30(%rbp),%rsi
mov    $0x28,%edx
call   1030 <memcpy@plt>
movsbl -0x2b(%rbp),%edi
call   1040 <report@plt>
movsbl -0x9b(%rbp),%edi
call   1040 <report@plt>
mov    -0x4(%rbp),%edi
call   1040 <report@plt>
movsbl -0xa0(%rbp),%eax
movsbl -0x9f(%rbp),%ecx
add    %ecx,%eax
movsbl -0x9e(%rbp),%ecx
add    %ecx,%eax
movsbl -0x9d(%rbp),%ecx
add    %ecx,%eax
movsbl -0x9c(%rbp),%ecx
add    %ecx,%eax
movsbl -0x9b(%rbp),%ecx
add    %ecx,%eax
movsbl -0x9a(%rbp),%ecx
add    %ecx,%eax
movsbl -0x99(%rbp),%ecx
add    %ecx,%eax
movsbl -0x98(%rbp),%ecx
add    %ecx,%eax
movsbl -0x97(%rbp),%ecx
add    %ecx,%eax
movsbl -0x96(%rbp),%ecx
add    %ecx,%eax
movsbl -0x95(%rbp),%ecx
add    %ecx,%eax
movsbl -0x94(%rbp),%ecx
add    %ecx,%eax
movsbl -0x93(%rbp),%ecx
add    %ecx,%eax
movsbl -0x92(%rbp),%ecx
add    %ecx,%eax
movsbl -0x91(%rbp),%ecx
add    %ecx,%eax
movsbl -0x90(%rbp),%ecx
add    %ecx,%eax
movsbl -0x8f(%rbp),%ecx
add    %ecx,%eax
movsbl -0x8e(%rbp),%ecx
add    %ecx,%eax
movsbl -0x8d(%rbp),%ecx
add    %ecx,%eax
movsbl -0x8c(%rbp),%ecx
add    %ecx,%eax
movsbl -0x8b(%rbp),%ecx
add    %ecx,%eax
movsbl -0x8a(%rbp),%ecx
add    %ecx,%eax
movsbl -0x89(%rbp),%ecx
add    %ecx,%eax
movsbl -0x88(%rbp),%ecx
add    %ecx,%eax
movsbl -0x87(%rbp),%ecx
add    %ecx,%eax
movsbl -0x86(%rbp),%ecx
add    %ecx,%eax
movsbl -0x85(%rbp),%ecx
add    %ecx,%eax
movsbl -0x84(%rbp),%ecx
add    %ecx,%eax
movsbl -0x83(%rbp),%ecx
add    %ecx,%eax
movsbl -0x82(%rbp),%ecx
add    %ecx,%eax
movsbl -0x81(%rbp),%ecx
add    %ecx,%eax
movsbl -0x80(%rbp),%ecx
add    %ecx,%eax
movsbl -0x7f(%rbp),%ecx
add    %ecx,%eax
movsbl -0x7e(%rbp),%ecx
add    %ecx,%eax
movsbl -0x7d(%rbp),%ecx
add    %ecx,%eax
movsbl -0x7c(%rbp),%ecx
add    %ecx,%eax
movsbl -0x7b(%rbp),%ecx
add    %ecx,%eax
movsbl -0x7a(%rbp),%ecx
add    %ecx,%eax
movsbl -0x79(%rbp),%ecx
add    %ecx,%eax
add    -0x4(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%edi
call   1040 <report@plt>
movslq -0x4(%rbp),%rax
add    $0xa0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<test_array>:
push   %rbp
push   %rbx
sub    $0x98,%rsp
mov    %edi,%ebx
movups 0xee7(%rip),%xmm0
movups %xmm0,0x19(%rsp)
movaps 0xed2(%rip),%xmm0
movaps %xmm0,0x10(%rsp)
movaps 0xeb6(%rip),%xmm0
movaps %xmm0,(%rsp)
mov    $0x74,%edi
call   1040 <report@plt>
lea    0x30(%rsp),%rdi
mov    %rsp,%rsi
mov    $0x28,%edx
call   1030 <memcpy@plt>
movsbl 0x5(%rsp),%edi
call   1040 <report@plt>
movsbl 0x35(%rsp),%edi
call   1040 <report@plt>
mov    %ebx,%edi
call   1040 <report@plt>
movdqa 0x30(%rsp),%xmm0
movdqa 0x40(%rsp),%xmm1
punpcklbw %xmm1,%xmm2
punpckhwd %xmm2,%xmm3
psrad  $0x18,%xmm3
punpcklbw %xmm0,%xmm4
punpckhwd %xmm4,%xmm5
psrad  $0x18,%xmm5
paddd  %xmm3,%xmm5
punpckhbw %xmm1,%xmm1
punpckhwd %xmm1,%xmm3
psrad  $0x18,%xmm3
punpckhbw %xmm0,%xmm0
punpckhwd %xmm0,%xmm6
psrad  $0x18,%xmm6
paddd  %xmm3,%xmm6
paddd  %xmm5,%xmm6
punpcklwd %xmm2,%xmm2
psrad  $0x18,%xmm2
punpcklwd %xmm4,%xmm3
psrad  $0x18,%xmm3
paddd  %xmm2,%xmm3
punpcklwd %xmm1,%xmm1
psrad  $0x18,%xmm1
punpcklwd %xmm0,%xmm0
psrad  $0x18,%xmm0
paddd  %xmm1,%xmm0
paddd  %xmm3,%xmm0
paddd  %xmm6,%xmm0
movq   0x50(%rsp),%xmm1
punpcklbw %xmm1,%xmm1
punpckhwd %xmm1,%xmm2
psrad  $0x18,%xmm2
punpcklwd %xmm1,%xmm1
psrad  $0x18,%xmm1
paddd  %xmm2,%xmm1
pshufd $0xee,%xmm0,%xmm2
paddd  %xmm0,%xmm2
pshufd $0x55,%xmm2,%xmm0
paddd  %xmm2,%xmm0
movd   %xmm0,%eax
pshufd $0xee,%xmm1,%xmm0
paddd  %xmm1,%xmm0
pshufd $0x55,%xmm0,%xmm1
paddd  %xmm0,%xmm1
movd   %xmm1,%ebp
add    %eax,%ebp
add    %ebx,%ebp
mov    %ebp,%edi
call   1040 <report@plt>
movslq %ebp,%rax
add    $0x98,%rsp
pop    %rbx
pop    %rbp
ret

LLVM IR (-O0):
@__const.test_array.a1 = [41 x i8] c"This test string MUST NOT be modified...\00"
define i64 @test_array(i32 %0) {
%2 = alloca i32
%3 = alloca [41 x i8]
%4 = alloca [100 x i8]
store i32 %0, i32* %2
%5 = bitcast [41 x i8]* %3 to i8*
%6 = getelementptr inbounds [41 x i8], [41 x i8]* %3, i64 0, i64 5
%7 = load i8, i8* %6
%8 = sext i8 %7 to i32
%9 = call i32 @report(i32 %8)
%10 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 0
%11 = getelementptr inbounds [41 x i8], [41 x i8]* %3, i64 0, i64 0
%12 = call i32 @memcpy(i8* %10, i8* %11, i32 40)
%13 = getelementptr inbounds [41 x i8], [41 x i8]* %3, i64 0, i64 5
%14 = load i8, i8* %13
%15 = sext i8 %14 to i32
%16 = call i32 @report(i32 %15)
%17 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 5
%18 = load i8, i8* %17
%19 = sext i8 %18 to i32
%20 = call i32 @report(i32 %19)
%21 = load i32, i32* %2
%22 = call i32 @report(i32 %21)
%23 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 0
%24 = load i8, i8* %23
%25 = sext i8 %24 to i32
%26 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 1
%27 = load i8, i8* %26
%28 = sext i8 %27 to i32
%29 = add nsw i32 %25, %28
%30 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 2
%31 = load i8, i8* %30
%32 = sext i8 %31 to i32
%33 = add nsw i32 %29, %32
%34 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 3
%35 = load i8, i8* %34
%36 = sext i8 %35 to i32
%37 = add nsw i32 %33, %36
%38 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 4
%39 = load i8, i8* %38
%40 = sext i8 %39 to i32
%41 = add nsw i32 %37, %40
%42 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 5
%43 = load i8, i8* %42
%44 = sext i8 %43 to i32
%45 = add nsw i32 %41, %44
%46 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 6
%47 = load i8, i8* %46
%48 = sext i8 %47 to i32
%49 = add nsw i32 %45, %48
%50 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 7
%51 = load i8, i8* %50
%52 = sext i8 %51 to i32
%53 = add nsw i32 %49, %52
%54 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 8
%55 = load i8, i8* %54
%56 = sext i8 %55 to i32
%57 = add nsw i32 %53, %56
%58 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 9
%59 = load i8, i8* %58
%60 = sext i8 %59 to i32
%61 = add nsw i32 %57, %60
%62 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 10
%63 = load i8, i8* %62
%64 = sext i8 %63 to i32
%65 = add nsw i32 %61, %64
%66 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 11
%67 = load i8, i8* %66
%68 = sext i8 %67 to i32
%69 = add nsw i32 %65, %68
%70 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 12
%71 = load i8, i8* %70
%72 = sext i8 %71 to i32
%73 = add nsw i32 %69, %72
%74 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 13
%75 = load i8, i8* %74
%76 = sext i8 %75 to i32
%77 = add nsw i32 %73, %76
%78 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 14
%79 = load i8, i8* %78
%80 = sext i8 %79 to i32
%81 = add nsw i32 %77, %80
%82 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 15
%83 = load i8, i8* %82
%84 = sext i8 %83 to i32
%85 = add nsw i32 %81, %84
%86 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 16
%87 = load i8, i8* %86
%88 = sext i8 %87 to i32
%89 = add nsw i32 %85, %88
%90 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 17
%91 = load i8, i8* %90
%92 = sext i8 %91 to i32
%93 = add nsw i32 %89, %92
%94 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 18
%95 = load i8, i8* %94
%96 = sext i8 %95 to i32
%97 = add nsw i32 %93, %96
%98 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 19
%99 = load i8, i8* %98
%100 = sext i8 %99 to i32
%101 = add nsw i32 %97, %100
%102 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 20
%103 = load i8, i8* %102
%104 = sext i8 %103 to i32
%105 = add nsw i32 %101, %104
%106 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 21
%107 = load i8, i8* %106
%108 = sext i8 %107 to i32
%109 = add nsw i32 %105, %108
%110 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 22
%111 = load i8, i8* %110
%112 = sext i8 %111 to i32
%113 = add nsw i32 %109, %112
%114 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 23
%115 = load i8, i8* %114
%116 = sext i8 %115 to i32
%117 = add nsw i32 %113, %116
%118 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 24
%119 = load i8, i8* %118
%120 = sext i8 %119 to i32
%121 = add nsw i32 %117, %120
%122 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 25
%123 = load i8, i8* %122
%124 = sext i8 %123 to i32
%125 = add nsw i32 %121, %124
%126 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 26
%127 = load i8, i8* %126
%128 = sext i8 %127 to i32
%129 = add nsw i32 %125, %128
%130 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 27
%131 = load i8, i8* %130
%132 = sext i8 %131 to i32
%133 = add nsw i32 %129, %132
%134 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 28
%135 = load i8, i8* %134
%136 = sext i8 %135 to i32
%137 = add nsw i32 %133, %136
%138 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 29
%139 = load i8, i8* %138
%140 = sext i8 %139 to i32
%141 = add nsw i32 %137, %140
%142 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 30
%143 = load i8, i8* %142
%144 = sext i8 %143 to i32
%145 = add nsw i32 %141, %144
%146 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 31
%147 = load i8, i8* %146
%148 = sext i8 %147 to i32
%149 = add nsw i32 %145, %148
%150 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 32
%151 = load i8, i8* %150
%152 = sext i8 %151 to i32
%153 = add nsw i32 %149, %152
%154 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 33
%155 = load i8, i8* %154
%156 = sext i8 %155 to i32
%157 = add nsw i32 %153, %156
%158 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 34
%159 = load i8, i8* %158
%160 = sext i8 %159 to i32
%161 = add nsw i32 %157, %160
%162 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 35
%163 = load i8, i8* %162
%164 = sext i8 %163 to i32
%165 = add nsw i32 %161, %164
%166 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 36
%167 = load i8, i8* %166
%168 = sext i8 %167 to i32
%169 = add nsw i32 %165, %168
%170 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 37
%171 = load i8, i8* %170
%172 = sext i8 %171 to i32
%173 = add nsw i32 %169, %172
%174 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 38
%175 = load i8, i8* %174
%176 = sext i8 %175 to i32
%177 = add nsw i32 %173, %176
%178 = getelementptr inbounds [100 x i8], [100 x i8]* %4, i64 0, i64 39
%179 = load i8, i8* %178
%180 = sext i8 %179 to i32
%181 = add nsw i32 %177, %180
%182 = load i32, i32* %2
%183 = add nsw i32 %182, %181
store i32 %183, i32* %2
%184 = load i32, i32* %2
%185 = call i32 @report(i32 %184)
%186 = load i32, i32* %2
%187 = sext i32 %186 to i64
ret i64 %187
}

LLVM IR (-O2):
@__const.test_array.a1 = [41 x i8] c"This test string MUST NOT be modified...\00"
define i64 @test_array(i32 %0) {
%2 = alloca [41 x i8]
%3 = alloca [100 x i8]
%4 = getelementptr inbounds [41 x i8], [41 x i8]* %2, i64 0, i64 0
%5 = getelementptr inbounds [100 x i8], [100 x i8]* %3, i64 0, i64 0
%6 = getelementptr inbounds [41 x i8], [41 x i8]* %2, i64 0, i64 5
%7 = tail call i32 @report(i32 116)
%8 = call i32 @memcpy(i8* %5, i8* %4, i32 40)
%9 = load i8, i8* %6
%10 = sext i8 %9 to i32
%11 = call i32 @report(i32 %10)
%12 = getelementptr inbounds [100 x i8], [100 x i8]* %3, i64 0, i64 5
%13 = load i8, i8* %12
%14 = sext i8 %13 to i32
%15 = call i32 @report(i32 %14)
%16 = call i32 @report(i32 %0)
%17 = bitcast [100 x i8]* %3 to <32 x i8>*
%18 = load <32 x i8>, <32 x i8>* %17
%19 = sext <32 x i8> %18 to <32 x i32>
%20 = getelementptr inbounds [100 x i8], [100 x i8]* %3, i64 0, i64 32
%21 = bitcast i8* %20 to <8 x i8>*
%22 = load <8 x i8>, <8 x i8>* %21
%23 = sext <8 x i8> %22 to <8 x i32>
%24 = call i32 @llvm.vector.reduce.add.v32i32(<32 x i32> %19)
%25 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %23)
%26 = add i32 %24, %25
%27 = add i32 %26, %0
%28 = call i32 @report(i32 %27)
%29 = sext i32 %27 to i64
ret i64 %29
}