#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*/ free(long *);
scalar_t__ malloc(long);
void ComposePerm(long *PERM1, long *PERM2, long n) {
  long i, *PERM3;
  PERM3 = (long *)malloc((n + 1) * sizeof(long));
  for (i = 0; i < n; i++)
    PERM3[i] = PERM1[PERM2[i]];
  for (i = 0; i < n; i++)
    PERM1[i] = PERM3[i];
  free(PERM3);
}


x86 assembly (clang, -O0):
<ComposePerm>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x18(%rbp),%rdi
add    $0x1,%rdi
shl    $0x3,%rdi
call   1040 <malloc@plt>
mov    %rax,-0x28(%rbp)
movq   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x18(%rbp),%rax
jge    1190 <ComposePerm+0x70>
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rcx,%rdx,8),%rcx
mov    (%rax,%rcx,8),%rdx
mov    -0x28(%rbp),%rax
mov    -0x20(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
jmp    1151 <ComposePerm+0x31>
movq   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x18(%rbp),%rax
jge    11cf <ComposePerm+0xaf>
mov    -0x28(%rbp),%rax
mov    -0x20(%rbp),%rcx
mov    (%rax,%rcx,8),%rdx
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
jmp    1198 <ComposePerm+0x78>
mov    -0x28(%rbp),%rdi
call   1030 <free@plt>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ComposePerm>:
push   %r15
push   %r14
push   %rbx
mov    %rdx,%r14
mov    %rsi,%rbx
mov    %rdi,%r15
lea    0x8(,%rdx,8),%rdi
call   1040 <malloc@plt>
test   %r14,%r14
jle    1334 <ComposePerm+0x214>
lea    -0x1(%r14),%rdx
mov    %r14d,%ecx
and    $0x3,%ecx
cmp    $0x3,%rdx
jae    1158 <ComposePerm+0x38>
xor    %edx,%edx
jmp    11af <ComposePerm+0x8f>
mov    %r14,%rsi
and    $0xfffffffffffffffc,%rsi
xor    %edx,%edx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    (%rbx,%rdx,8),%rdi
mov    (%r15,%rdi,8),%rdi
mov    %rdi,(%rax,%rdx,8)
mov    0x8(%rbx,%rdx,8),%rdi
mov    (%r15,%rdi,8),%rdi
mov    %rdi,0x8(%rax,%rdx,8)
mov    0x10(%rbx,%rdx,8),%rdi
mov    (%r15,%rdi,8),%rdi
mov    %rdi,0x10(%rax,%rdx,8)
mov    0x18(%rbx,%rdx,8),%rdi
mov    (%r15,%rdi,8),%rdi
mov    %rdi,0x18(%rax,%rdx,8)
add    $0x4,%rdx
cmp    %rdx,%rsi
jne    1170 <ComposePerm+0x50>
test   %rcx,%rcx
je     11d5 <ComposePerm+0xb5>
lea    (%rax,%rdx,8),%rsi
lea    (%rbx,%rdx,8),%rdx
xor    %edi,%edi
xchg   %ax,%ax
mov    (%rdx,%rdi,8),%rbx
mov    (%r15,%rbx,8),%rbx
mov    %rbx,(%rsi,%rdi,8)
add    $0x1,%rdi
cmp    %rdi,%rcx
jne    11c0 <ComposePerm+0xa0>
test   %r14,%r14
jle    1334 <ComposePerm+0x214>
cmp    $0x4,%r14
jb     11f6 <ComposePerm+0xd6>
lea    (%rax,%r14,8),%rcx
cmp    %r15,%rcx
jbe    1264 <ComposePerm+0x144>
lea    (%r15,%r14,8),%rcx
cmp    %rcx,%rax
jae    1264 <ComposePerm+0x144>
xor    %ecx,%ecx
mov    %rcx,%rdx
not    %rdx
add    %r14,%rdx
mov    %r14,%rsi
and    $0x3,%rsi
je     1222 <ComposePerm+0x102>
nopw   0x0(%rax,%rax,1)
mov    (%rax,%rcx,8),%rdi
mov    %rdi,(%r15,%rcx,8)
add    $0x1,%rcx
add    $0xffffffffffffffff,%rsi
jne    1210 <ComposePerm+0xf0>
cmp    $0x3,%rdx
jb     1334 <ComposePerm+0x214>
nopl   0x0(%rax)
mov    (%rax,%rcx,8),%rdx
mov    %rdx,(%r15,%rcx,8)
mov    0x8(%rax,%rcx,8),%rdx
mov    %rdx,0x8(%r15,%rcx,8)
mov    0x10(%rax,%rcx,8),%rdx
mov    %rdx,0x10(%r15,%rcx,8)
mov    0x18(%rax,%rcx,8),%rdx
mov    %rdx,0x18(%r15,%rcx,8)
add    $0x4,%rcx
cmp    %rcx,%r14
jne    1230 <ComposePerm+0x110>
jmp    1334 <ComposePerm+0x214>
mov    %r14,%rcx
and    $0xfffffffffffffffc,%rcx
lea    -0x4(%rcx),%rdi
mov    %rdi,%rsi
shr    $0x2,%rsi
add    $0x1,%rsi
mov    %esi,%edx
and    $0x3,%edx
cmp    $0xc,%rdi
jae    1289 <ComposePerm+0x169>
xor    %edi,%edi
jmp    12f0 <ComposePerm+0x1d0>
and    $0xfffffffffffffffc,%rsi
xor    %edi,%edi
nop
movups (%rax,%rdi,8),%xmm0
movups 0x10(%rax,%rdi,8),%xmm1
movups %xmm0,(%r15,%rdi,8)
movups %xmm1,0x10(%r15,%rdi,8)
movups 0x20(%rax,%rdi,8),%xmm0
movups 0x30(%rax,%rdi,8),%xmm1
movups %xmm0,0x20(%r15,%rdi,8)
movups %xmm1,0x30(%r15,%rdi,8)
movups 0x40(%rax,%rdi,8),%xmm0
movups 0x50(%rax,%rdi,8),%xmm1
movups %xmm0,0x40(%r15,%rdi,8)
movups %xmm1,0x50(%r15,%rdi,8)
movups 0x60(%rax,%rdi,8),%xmm0
movups 0x70(%rax,%rdi,8),%xmm1
movups %xmm0,0x60(%r15,%rdi,8)
movups %xmm1,0x70(%r15,%rdi,8)
add    $0x10,%rdi
add    $0xfffffffffffffffc,%rsi
jne    1290 <ComposePerm+0x170>
test   %rdx,%rdx
je     132b <ComposePerm+0x20b>
lea    (%r15,%rdi,8),%rsi
add    $0x10,%rsi
lea    (%rax,%rdi,8),%rdi
add    $0x10,%rdi
shl    $0x5,%rdx
xor    %ebx,%ebx
nopl   0x0(%rax,%rax,1)
movups -0x10(%rdi,%rbx,1),%xmm0
movups (%rdi,%rbx,1),%xmm1
movups %xmm0,-0x10(%rsi,%rbx,1)
movups %xmm1,(%rsi,%rbx,1)
add    $0x20,%rbx
cmp    %rbx,%rdx
jne    1310 <ComposePerm+0x1f0>
cmp    %r14,%rcx
jne    11f8 <ComposePerm+0xd8>
mov    %rax,%rdi
pop    %rbx
pop    %r14
pop    %r15
jmp    1030 <free@plt>

LLVM IR (-O0):
define void @ComposePerm(i64* %0, i64* %1, i64 %2) {
%4 = alloca i64*
%5 = alloca i64*
%6 = alloca i64
%7 = alloca i64
%8 = alloca i64*
store i64* %0, i64** %4
store i64* %1, i64** %5
store i64 %2, i64* %6
%9 = load i64, i64* %6
%10 = add nsw i64 %9, 1
%11 = mul i64 %10, 8
%12 = call i64 @malloc(i64 %11)
%13 = inttoptr i64 %12 to i64*
store i64* %13, i64** %8
store i64 0, i64* %7
br label %14
14: ; preds = %29, %3
%15 = load i64, i64* %7
%16 = load i64, i64* %6
%17 = icmp slt i64 %15, %16
br i1 %17, label %18, label %32
18: ; preds = %14
%19 = load i64*, i64** %4
%20 = load i64*, i64** %5
%21 = load i64, i64* %7
%22 = getelementptr inbounds i64, i64* %20, i64 %21
%23 = load i64, i64* %22
%24 = getelementptr inbounds i64, i64* %19, i64 %23
%25 = load i64, i64* %24
%26 = load i64*, i64** %8
%27 = load i64, i64* %7
%28 = getelementptr inbounds i64, i64* %26, i64 %27
store i64 %25, i64* %28
br label %29
29: ; preds = %18
%30 = load i64, i64* %7
%31 = add nsw i64 %30, 1
store i64 %31, i64* %7
br label %14
32: ; preds = %14
store i64 0, i64* %7
br label %33
33: ; preds = %45, %32
%34 = load i64, i64* %7
%35 = load i64, i64* %6
%36 = icmp slt i64 %34, %35
br i1 %36, label %37, label %48
37: ; preds = %33
%38 = load i64*, i64** %8
%39 = load i64, i64* %7
%40 = getelementptr inbounds i64, i64* %38, i64 %39
%41 = load i64, i64* %40
%42 = load i64*, i64** %4
%43 = load i64, i64* %7
%44 = getelementptr inbounds i64, i64* %42, i64 %43
store i64 %41, i64* %44
br label %45
45: ; preds = %37
%46 = load i64, i64* %7
%47 = add nsw i64 %46, 1
store i64 %47, i64* %7
br label %33
48: ; preds = %33
%49 = load i64*, i64** %8
%50 = call i32 @free(i64* %49)
ret void
}

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