int main(int argc, const char *argv[]) {
  unsigned int input[20], output[20], i, input2[20], output2[20];
  unsigned int check_results[20] = {
      3208,  1334, 28764,  35679,  2789,  13028, 4754,  168364, 91254,  12399,
      22848, 8174, 307964, 146829, 22009, 32668, 11594, 447564, 202404, 31619};
  unsigned int check_results2[20] = {
      7136,  2702, 84604,  57909,  6633,  16956, 6122,  224204, 113484, 16243,
      26776, 9542, 363804, 169059, 25853, 36596, 12962, 503404, 224634, 35463};
  for (i = 0; i < 20; i++) {
    input[i] = i % 256;
    input2[i] = i + 2;
    output[i] = 0;
    output2[i] = 0;
    __asm__ volatile("");
  }
  foo(input, output, input2, output2);
  for (i = 0; i < 20; i++)
    if (output[i] != check_results[i] || output2[i] != check_results2[i])
      abort();
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x200,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
lea    -0x1b0(%rbp),%rdi
lea    0xea9(%rip),%rsi
mov    $0x50,%edx
call   1040 <memcpy@plt>
lea    -0x200(%rbp),%rdi
lea    0xee1(%rip),%rsi
mov    $0x50,%edx
call   1040 <memcpy@plt>
movl   $0x0,-0xb4(%rbp)
cmpl   $0x14,-0xb4(%rbp)
jae    11f2 <main+0xc2>
mov    -0xb4(%rbp),%ecx
and    $0xff,%ecx
mov    -0xb4(%rbp),%eax
mov    %ecx,-0x60(%rbp,%rax,4)
mov    -0xb4(%rbp),%ecx
add    $0x2,%ecx
mov    -0xb4(%rbp),%eax
mov    %ecx,-0x110(%rbp,%rax,4)
mov    -0xb4(%rbp),%eax
movl   $0x0,-0xb0(%rbp,%rax,4)
mov    -0xb4(%rbp),%eax
movl   $0x0,-0x160(%rbp,%rax,4)
mov    -0xb4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xb4(%rbp)
jmp    1183 <main+0x53>
lea    -0x60(%rbp),%rdi
lea    -0xb0(%rbp),%rsi
lea    -0x110(%rbp),%rdx
lea    -0x160(%rbp),%rcx
mov    $0x0,%al
call   1050 <foo@plt>
movl   $0x0,-0xb4(%rbp)
cmpl   $0x14,-0xb4(%rbp)
jae    1287 <main+0x157>
mov    -0xb4(%rbp),%eax
mov    -0xb0(%rbp,%rax,4),%eax
mov    -0xb4(%rbp),%ecx
cmp    -0x1b0(%rbp,%rcx,4),%eax
jne    1269 <main+0x139>
mov    -0xb4(%rbp),%eax
mov    -0x160(%rbp,%rax,4),%eax
mov    -0xb4(%rbp),%ecx
cmp    -0x200(%rbp,%rcx,4),%eax
je     126e <main+0x13e>
call   1030 <abort@plt>
jmp    1273 <main+0x143>
mov    -0xb4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xb4(%rbp)
jmp    121c <main+0xec>
xor    %eax,%eax
add    $0x200,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
sub    $0x148,%rsp
xor    %eax,%eax
nopl   0x0(%rax)
mov    %eax,0xf0(%rsp,%rax,4)
lea    0x2(%rax),%ecx
mov    %ecx,0xa0(%rsp,%rax,4)
movl   $0x0,0x50(%rsp,%rax,4)
movl   $0x0,(%rsp,%rax,4)
add    $0x1,%rax
cmp    $0x14,%rax
jne    1130 <main+0x10>
lea    0xf0(%rsp),%rdi
lea    0x50(%rsp),%rsi
lea    0xa0(%rsp),%rdx
mov    %rsp,%rcx
xor    %eax,%eax
call   1040 <foo@plt>
mov    $0x1,%eax
lea    0xe7b(%rip),%rcx
lea    0xec4(%rip),%rdx
nopl   0x0(%rax)
mov    0x4c(%rsp,%rax,4),%esi
cmp    -0x4(%rcx,%rax,4),%esi
jne    11c9 <main+0xa9>
mov    -0x4(%rsp,%rax,4),%esi
cmp    -0x4(%rdx,%rax,4),%esi
jne    11c9 <main+0xa9>
mov    0x50(%rsp,%rax,4),%esi
cmp    (%rcx,%rax,4),%esi
jne    11c9 <main+0xa9>
mov    (%rsp,%rax,4),%esi
cmp    (%rdx,%rax,4),%esi
jne    11c9 <main+0xa9>
add    $0x2,%rax
cmp    $0x15,%rax
jne    1190 <main+0x70>
xor    %eax,%eax
add    $0x148,%rsp
ret
call   1030 <abort@plt>

LLVM IR (-O0):
@__const.main.check_results = [20 x i32] [i32 3208, i32 1334, i32 28764, i32 35679, i32 2789, i32 13028, i32 4754, i32 168364, i32 91254, i32 12399, i32 22848, i32 8174, i32 307964, i32 146829, i32 22009, i32 32668, i32 11594, i32 447564, i32 202404, i32 31619]
@__const.main.check_results2 = [20 x i32] [i32 7136, i32 2702, i32 84604, i32 57909, i32 6633, i32 16956, i32 6122, i32 224204, i32 113484, i32 16243, i32 26776, i32 9542, i32 363804, i32 169059, i32 25853, i32 36596, i32 12962, i32 503404, i32 224634, i32 35463]
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca [20 x i32]
%7 = alloca [20 x i32]
%8 = alloca i32
%9 = alloca [20 x i32]
%10 = alloca [20 x i32]
%11 = alloca [20 x i32]
%12 = alloca [20 x i32]
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
%13 = bitcast [20 x i32]* %11 to i8*
%14 = bitcast [20 x i32]* %12 to i8*
store i32 0, i32* %8
br label %15
15: ; preds = %35, %2
%16 = load i32, i32* %8
%17 = icmp ult i32 %16, 20
br i1 %17, label %18, label %38
18: ; preds = %15
%19 = load i32, i32* %8
%20 = urem i32 %19, 256
%21 = load i32, i32* %8
%22 = zext i32 %21 to i64
%23 = getelementptr inbounds [20 x i32], [20 x i32]* %6, i64 0, i64 %22
store i32 %20, i32* %23
%24 = load i32, i32* %8
%25 = add i32 %24, 2
%26 = load i32, i32* %8
%27 = zext i32 %26 to i64
%28 = getelementptr inbounds [20 x i32], [20 x i32]* %9, i64 0, i64 %27
store i32 %25, i32* %28
%29 = load i32, i32* %8
%30 = zext i32 %29 to i64
%31 = getelementptr inbounds [20 x i32], [20 x i32]* %7, i64 0, i64 %30
store i32 0, i32* %31
%32 = load i32, i32* %8
%33 = zext i32 %32 to i64
%34 = getelementptr inbounds [20 x i32], [20 x i32]* %10, i64 0, i64 %33
store i32 0, i32* %34
br label %35
35: ; preds = %18
%36 = load i32, i32* %8
%37 = add i32 %36, 1
store i32 %37, i32* %8
br label %15
38: ; preds = %15
%39 = getelementptr inbounds [20 x i32], [20 x i32]* %6, i64 0, i64 0
%40 = getelementptr inbounds [20 x i32], [20 x i32]* %7, i64 0, i64 0
%41 = getelementptr inbounds [20 x i32], [20 x i32]* %9, i64 0, i64 0
%42 = getelementptr inbounds [20 x i32], [20 x i32]* %10, i64 0, i64 0
%43 = call i32 (i32*, i32*, i32*, i32*, ...) bitcast (i32 (...)* @foo to i32 (i32*, i32*, i32*, i32*, ...)*)(i32* %39, i32* %40, i32* %41, i32* %42)
store i32 0, i32* %8
br label %44
44: ; preds = %69, %38
%45 = load i32, i32* %8
%46 = icmp ult i32 %45, 20
br i1 %46, label %47, label %72
47: ; preds = %44
%48 = load i32, i32* %8
%49 = zext i32 %48 to i64
%50 = getelementptr inbounds [20 x i32], [20 x i32]* %7, i64 0, i64 %49
%51 = load i32, i32* %50
%52 = load i32, i32* %8
%53 = zext i32 %52 to i64
%54 = getelementptr inbounds [20 x i32], [20 x i32]* %11, i64 0, i64 %53
%55 = load i32, i32* %54
%56 = icmp ne i32 %51, %55
br i1 %56, label %67, label %57
57: ; preds = %47
%58 = load i32, i32* %8
%59 = zext i32 %58 to i64
%60 = getelementptr inbounds [20 x i32], [20 x i32]* %10, i64 0, i64 %59
%61 = load i32, i32* %60
%62 = load i32, i32* %8
%63 = zext i32 %62 to i64
%64 = getelementptr inbounds [20 x i32], [20 x i32]* %12, i64 0, i64 %63
%65 = load i32, i32* %64
%66 = icmp ne i32 %61, %65
br i1 %66, label %67, label %68
67: ; preds = %57, %47
unreachable
68: ; preds = %57
br label %69
69: ; preds = %68
%70 = load i32, i32* %8
%71 = add i32 %70, 1
store i32 %71, i32* %8
br label %44
72: ; preds = %44
ret i32 0
}

LLVM IR (-O2):
@__const.main.check_results = [20 x i32] [i32 3208, i32 1334, i32 28764, i32 35679, i32 2789, i32 13028, i32 4754, i32 168364, i32 91254, i32 12399, i32 22848, i32 8174, i32 307964, i32 146829, i32 22009, i32 32668, i32 11594, i32 447564, i32 202404, i32 31619]
@__const.main.check_results2 = [20 x i32] [i32 7136, i32 2702, i32 84604, i32 57909, i32 6633, i32 16956, i32 6122, i32 224204, i32 113484, i32 16243, i32 26776, i32 9542, i32 363804, i32 169059, i32 25853, i32 36596, i32 12962, i32 503404, i32 224634, i32 35463]
define i32 @main(i32 %0, i8** nocapture readnone %1) {
%3 = alloca [20 x i32]
%4 = alloca [20 x i32]
%5 = alloca [20 x i32]
%6 = alloca [20 x i32]
%7 = bitcast [20 x i32]* %3 to i8*
%8 = bitcast [20 x i32]* %4 to i8*
%9 = bitcast [20 x i32]* %5 to i8*
%10 = bitcast [20 x i32]* %6 to i8*
br label %11
11: ; preds = %2, %11
%12 = phi i64 [ 0, %2 ], [ %20, %11 ]
%13 = getelementptr inbounds [20 x i32], [20 x i32]* %3, i64 0, i64 %12
%14 = trunc i64 %12 to i32
store i32 %14, i32* %13
%15 = getelementptr inbounds [20 x i32], [20 x i32]* %5, i64 0, i64 %12
%16 = trunc i64 %12 to i32
%17 = add i32 %16, 2
store i32 %17, i32* %15
%18 = getelementptr inbounds [20 x i32], [20 x i32]* %4, i64 0, i64 %12
store i32 0, i32* %18
%19 = getelementptr inbounds [20 x i32], [20 x i32]* %6, i64 0, i64 %12
store i32 0, i32* %19
tail call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"()
%20 = add nuw nsw i64 %12, 1
%21 = icmp eq i64 %20, 20
br i1 %21, label %22, label %11
22: ; preds = %11
%23 = getelementptr inbounds [20 x i32], [20 x i32]* %3, i64 0, i64 0
%24 = getelementptr inbounds [20 x i32], [20 x i32]* %4, i64 0, i64 0
%25 = getelementptr inbounds [20 x i32], [20 x i32]* %5, i64 0, i64 0
%26 = getelementptr inbounds [20 x i32], [20 x i32]* %6, i64 0, i64 0
%27 = call i32 (i32*, i32*, i32*, i32*, ...) bitcast (i32 (...)* @foo to i32 (i32*, i32*, i32*, i32*, ...)*)(i32* %23, i32* %24, i32* %25, i32* %26)
br label %44
28: ; preds = %51
%29 = or i64 %45, 1
%30 = getelementptr inbounds [20 x i32], [20 x i32]* %4, i64 0, i64 %29
%31 = load i32, i32* %30
%32 = getelementptr inbounds [20 x i32], [20 x i32]* @__const.main.check_results, i64 0, i64 %29
%33 = load i32, i32* %32
%34 = icmp eq i32 %31, %33
br i1 %34, label %35, label %57
35: ; preds = %28
%36 = getelementptr inbounds [20 x i32], [20 x i32]* %6, i64 0, i64 %29
%37 = load i32, i32* %36
%38 = getelementptr inbounds [20 x i32], [20 x i32]* @__const.main.check_results2, i64 0, i64 %29
%39 = load i32, i32* %38
%40 = icmp eq i32 %37, %39
br i1 %40, label %41, label %57
41: ; preds = %35
%42 = add nuw nsw i64 %45, 2
%43 = icmp eq i64 %42, 20
br i1 %43, label %58, label %44
44: ; preds = %41, %22
%45 = phi i64 [ 0, %22 ], [ %42, %41 ]
%46 = getelementptr inbounds [20 x i32], [20 x i32]* %4, i64 0, i64 %45
%47 = load i32, i32* %46
%48 = getelementptr inbounds [20 x i32], [20 x i32]* @__const.main.check_results, i64 0, i64 %45
%49 = load i32, i32* %48
%50 = icmp eq i32 %47, %49
br i1 %50, label %51, label %57
51: ; preds = %44
%52 = getelementptr inbounds [20 x i32], [20 x i32]* %6, i64 0, i64 %45
%53 = load i32, i32* %52
%54 = getelementptr inbounds [20 x i32], [20 x i32]* @__const.main.check_results2, i64 0, i64 %45
%55 = load i32, i32* %54
%56 = icmp eq i32 %53, %55
br i1 %56, label %28, label %57
57: ; preds = %35, %28, %51, %44
unreachable
58: ; preds = %41
ret i32 0
}