#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*/ memset(unsigned char *, int /*<<< orphan*/, int);
void Permute(unsigned char *inBlock, char perm[16][16][8],
             unsigned char *outBlock) {
  int i;
  int j;
  char *p;
  char *q;
  unsigned char *oBlock;
  if (perm == NULL) {
    for (i = 8; i != 0; i--)
      *outBlock++ = *inBlock++;
    return;
  }
  memset(outBlock, 0, 8);
  for (j = 0; j < 16; j += 2) {
    oBlock = outBlock;
    p = perm[j][(*inBlock >> 4) & 017];
    q = perm[j + 1][*inBlock & 017];
    for (i = 8; i != 0; i--)
      *oBlock++ |= *p++ | *q++;
    inBlock++;
  }
  return;
}


x86 assembly (clang, -O0):
<Permute>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    1175 <Permute+0x65>
movl   $0x8,-0x1c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
je     1170 <Permute+0x60>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
mov    (%rax),%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x1c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x1c(%rbp)
jmp    1136 <Permute+0x26>
jmp    126e <Permute+0x15e>
mov    -0x18(%rbp),%rdi
xor    %esi,%esi
mov    $0x8,%edx
call   1030 <memset@plt>
movl   $0x0,-0x20(%rbp)
cmpl   $0x10,-0x20(%rbp)
jge    1269 <Permute+0x159>
mov    -0x18(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
shl    $0x7,%rcx
add    %rcx,%rax
mov    -0x8(%rbp),%rcx
movzbl (%rcx),%ecx
sar    $0x4,%ecx
and    $0xf,%ecx
movslq %ecx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    %rax,-0x28(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
shl    $0x7,%rcx
add    %rcx,%rax
mov    -0x8(%rbp),%rcx
movzbl (%rcx),%ecx
and    $0xf,%ecx
movslq %ecx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    %rax,-0x30(%rbp)
movl   $0x8,-0x1c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
je     124f <Permute+0x13f>
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
movsbl (%rax),%edx
mov    -0x30(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x30(%rbp)
movsbl (%rax),%eax
or     %eax,%edx
mov    -0x38(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x38(%rbp)
movzbl (%rax),%ecx
or     %edx,%ecx
mov    %cl,(%rax)
mov    -0x1c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x1c(%rbp)
jmp    11fb <Permute+0xeb>
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
mov    -0x20(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x20(%rbp)
jmp    118c <Permute+0x7c>
jmp    126e <Permute+0x15e>
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<Permute>:
push   %r15
push   %r14
push   %rbx
mov    %rdx,%r15
mov    %rdi,%r14
test   %rsi,%rsi
je     11e2 <Permute+0xd2>
mov    %rsi,%rbx
mov    %r15,%rdi
xor    %esi,%esi
mov    $0x8,%edx
call   1030 <memset@plt>
mov    0x6(%r15),%dil
sub    $0xffffffffffffff80,%rbx
mov    $0xfffffffffffffffe,%rcx
cs nopw 0x0(%rax,%rax,1)
nop
movzbl (%r14),%esi
mov    %rsi,%rdx
shr    $0x4,%rdx
and    $0xf,%esi
movzbl (%rbx,%rsi,8),%eax
or     -0x80(%rbx,%rdx,8),%al
or     %al,(%r15)
movzbl 0x1(%rbx,%rsi,8),%eax
or     -0x7f(%rbx,%rdx,8),%al
or     %al,0x1(%r15)
movzbl 0x2(%rbx,%rsi,8),%eax
or     -0x7e(%rbx,%rdx,8),%al
or     %al,0x2(%r15)
movzbl 0x3(%rbx,%rsi,8),%eax
or     -0x7d(%rbx,%rdx,8),%al
or     %al,0x3(%r15)
movzbl 0x4(%rbx,%rsi,8),%eax
or     -0x7c(%rbx,%rdx,8),%al
or     %al,0x4(%r15)
movzbl 0x5(%rbx,%rsi,8),%eax
or     -0x7b(%rbx,%rdx,8),%al
or     %al,0x5(%r15)
movzbl 0x6(%rbx,%rsi,8),%eax
or     -0x7a(%rbx,%rdx,8),%al
or     %al,%dil
mov    %dil,0x6(%r15)
movzbl 0x7(%rbx,%rsi,8),%eax
or     -0x79(%rbx,%rdx,8),%al
or     %al,0x7(%r15)
add    $0x1,%r14
add    $0x100,%rbx
add    $0x2,%rcx
cmp    $0xe,%rcx
jb     1150 <Permute+0x40>
jmp    1220 <Permute+0x110>
mov    (%r14),%al
mov    %al,(%r15)
mov    0x1(%r14),%al
mov    %al,0x1(%r15)
mov    0x2(%r14),%al
mov    %al,0x2(%r15)
mov    0x3(%r14),%al
mov    %al,0x3(%r15)
mov    0x4(%r14),%al
mov    %al,0x4(%r15)
mov    0x5(%r14),%al
mov    %al,0x5(%r15)
mov    0x6(%r14),%al
mov    %al,0x6(%r15)
mov    0x7(%r14),%al
mov    %al,0x7(%r15)
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define void @Permute(i8* %0, [16 x [8 x i8]]* %1, i8* %2) {
%4 = alloca i8*
%5 = alloca [16 x [8 x i8]]*
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i8*
%10 = alloca i8*
%11 = alloca i8*
store i8* %0, i8** %4
store [16 x [8 x i8]]* %1, [16 x [8 x i8]]** %5
store i8* %2, i8** %6
%12 = load [16 x [8 x i8]]*, [16 x [8 x i8]]** %5
%13 = icmp eq [16 x [8 x i8]]* %12, null
br i1 %13, label %14, label %28
14: ; preds = %3
store i32 8, i32* %7
br label %15
15: ; preds = %24, %14
%16 = load i32, i32* %7
%17 = icmp ne i32 %16, 0
br i1 %17, label %18, label %27
18: ; preds = %15
%19 = load i8*, i8** %4
%20 = getelementptr inbounds i8, i8* %19, i32 1
store i8* %20, i8** %4
%21 = load i8, i8* %19
%22 = load i8*, i8** %6
%23 = getelementptr inbounds i8, i8* %22, i32 1
store i8* %23, i8** %6
store i8 %21, i8* %22
br label %24
24: ; preds = %18
%25 = load i32, i32* %7
%26 = add nsw i32 %25, -1
store i32 %26, i32* %7
br label %15
27: ; preds = %15
br label %89
28: ; preds = %3
%29 = load i8*, i8** %6
%30 = call i32 @memset(i8* %29, i32 0, i32 8)
store i32 0, i32* %8
br label %31
31: ; preds = %85, %28
%32 = load i32, i32* %8
%33 = icmp slt i32 %32, 16
br i1 %33, label %34, label %88
34: ; preds = %31
%35 = load i8*, i8** %6
store i8* %35, i8** %11
%36 = load [16 x [8 x i8]]*, [16 x [8 x i8]]** %5
%37 = load i32, i32* %8
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds [16 x [8 x i8]], [16 x [8 x i8]]* %36, i64 %38
%40 = load i8*, i8** %4
%41 = load i8, i8* %40
%42 = zext i8 %41 to i32
%43 = ashr i32 %42, 4
%44 = and i32 %43, 15
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds [16 x [8 x i8]], [16 x [8 x i8]]* %39, i64 0, i64 %45
%47 = getelementptr inbounds [8 x i8], [8 x i8]* %46, i64 0, i64 0
store i8* %47, i8** %9
%48 = load [16 x [8 x i8]]*, [16 x [8 x i8]]** %5
%49 = load i32, i32* %8
%50 = add nsw i32 %49, 1
%51 = sext i32 %50 to i64
%52 = getelementptr inbounds [16 x [8 x i8]], [16 x [8 x i8]]* %48, i64 %51
%53 = load i8*, i8** %4
%54 = load i8, i8* %53
%55 = zext i8 %54 to i32
%56 = and i32 %55, 15
%57 = sext i32 %56 to i64
%58 = getelementptr inbounds [16 x [8 x i8]], [16 x [8 x i8]]* %52, i64 0, i64 %57
%59 = getelementptr inbounds [8 x i8], [8 x i8]* %58, i64 0, i64 0
store i8* %59, i8** %10
store i32 8, i32* %7
br label %60
60: ; preds = %79, %34
%61 = load i32, i32* %7
%62 = icmp ne i32 %61, 0
br i1 %62, label %63, label %82
63: ; preds = %60
%64 = load i8*, i8** %9
%65 = getelementptr inbounds i8, i8* %64, i32 1
store i8* %65, i8** %9
%66 = load i8, i8* %64
%67 = sext i8 %66 to i32
%68 = load i8*, i8** %10
%69 = getelementptr inbounds i8, i8* %68, i32 1
store i8* %69, i8** %10
%70 = load i8, i8* %68
%71 = sext i8 %70 to i32
%72 = or i32 %67, %71
%73 = load i8*, i8** %11
%74 = getelementptr inbounds i8, i8* %73, i32 1
store i8* %74, i8** %11
%75 = load i8, i8* %73
%76 = zext i8 %75 to i32
%77 = or i32 %76, %72
%78 = trunc i32 %77 to i8
store i8 %78, i8* %73
br label %79
79: ; preds = %63
%80 = load i32, i32* %7
%81 = add nsw i32 %80, -1
store i32 %81, i32* %7
br label %60
82: ; preds = %60
%83 = load i8*, i8** %4
%84 = getelementptr inbounds i8, i8* %83, i32 1
store i8* %84, i8** %4
br label %85
85: ; preds = %82
%86 = load i32, i32* %8
%87 = add nsw i32 %86, 2
store i32 %87, i32* %8
br label %31
88: ; preds = %31
br label %89
89: ; preds = %88, %27
ret void
}

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