#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 */
long long abs(long long);
long long pow(long long a, long long b) {
  if (b < 0)
    return -1;
  if (b == 0)
    return 1;
  int sign = 0;
  if (a < 0)
    sign = 1;
  a = abs(a);
  const long long a_orig = a;
  for (long long i = 0; i < b; i++)
    for (long long j = 0; j < a_orig; j++)
      a += a_orig;
  if (sign && (b & 1))
    return -a;
  return a;
}


x86 assembly (clang, -O0):
<pow>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
cmpq   $0x0,-0x18(%rbp)
jge    1138 <pow+0x28>
movq   $0xffffffffffffffff,-0x8(%rbp)
ff
jmp    1210 <pow+0x100>
cmpq   $0x0,-0x18(%rbp)
jne    1150 <pow+0x40>
movq   $0x1,-0x8(%rbp)
jmp    1210 <pow+0x100>
movl   $0x0,-0x1c(%rbp)
cmpq   $0x0,-0x10(%rbp)
jge    1169 <pow+0x59>
movl   $0x1,-0x1c(%rbp)
mov    -0x10(%rbp),%rdi
call   1030 <abs@plt>
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x28(%rbp)
movq   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%rax
cmp    -0x18(%rbp),%rax
jge    11dd <pow+0xcd>
movq   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%rax
cmp    -0x28(%rbp),%rax
jge    11c7 <pow+0xb7>
mov    -0x28(%rbp),%rax
add    -0x10(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
jmp    119c <pow+0x8c>
jmp    11cc <pow+0xbc>
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
jmp    1186 <pow+0x76>
cmpl   $0x0,-0x1c(%rbp)
je     1208 <pow+0xf8>
mov    -0x18(%rbp),%rax
and    $0x1,%rax
cmp    $0x0,%rax
je     1208 <pow+0xf8>
xor    %eax,%eax
sub    -0x10(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    1210 <pow+0x100>
mov    -0x10(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<pow>:
test   %rsi,%rsi
js     1130 <pow+0x30>
je     1138 <pow+0x38>
mov    %rdi,%rdx
neg    %rdx
cmovs  %rdi,%rdx
cmp    $0x2,%rdx
mov    $0x1,%eax
cmovae %rdx,%rax
imul   %rdx,%rax
cmp    $0x4,%rsi
jae    113e <pow+0x3e>
xor    %r8d,%r8d
jmp    11f5 <pow+0xf5>
mov    $0xffffffffffffffff,%rax
ret
mov    $0x1,%eax
ret
mov    %rsi,%r8
and    $0xfffffffffffffffc,%r8
movq   %rdx,%xmm0
movq   %rax,%xmm1
pshufd $0x44,%xmm1,%xmm2
lea    -0x4(%r8),%r9
mov    %r9,%rdx
shr    $0x2,%rdx
add    $0x1,%rdx
mov    %edx,%ecx
and    $0x3,%ecx
pxor   %xmm1,%xmm1
cmp    $0xc,%r9
jb     11b6 <pow+0xb6>
pxor   %xmm3,%xmm3
pxor   %xmm4,%xmm4
test   %rdi,%rdi
je     1187 <pow+0x87>
movdqa %xmm2,%xmm3
movdqa %xmm2,%xmm4
and    $0xfffffffffffffffc,%rdx
nopl   0x0(%rax,%rax,1)
paddq  %xmm3,%xmm0
paddq  %xmm4,%xmm1
paddq  %xmm3,%xmm0
paddq  %xmm4,%xmm1
paddq  %xmm3,%xmm0
paddq  %xmm4,%xmm1
paddq  %xmm3,%xmm0
paddq  %xmm4,%xmm1
add    $0xfffffffffffffffc,%rdx
jne    1190 <pow+0x90>
test   %rcx,%rcx
je     11de <pow+0xde>
pxor   %xmm3,%xmm3
test   %rdi,%rdi
je     11d0 <pow+0xd0>
movdqa %xmm2,%xmm3
nopl   0x0(%rax,%rax,1)
paddq  %xmm3,%xmm1
paddq  %xmm3,%xmm0
add    $0xffffffffffffffff,%rcx
jne    11d0 <pow+0xd0>
paddq  %xmm1,%xmm0
pshufd $0xee,%xmm0,%xmm1
paddq  %xmm0,%xmm1
movq   %xmm1,%rdx
cmp    %rsi,%r8
je     1219 <pow+0x119>
test   %rdi,%rdi
cmove  %rdi,%rax
mov    %rsi,%rcx
sub    %r8,%rcx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
add    %rax,%rdx
add    $0xffffffffffffffff,%rcx
jne    1210 <pow+0x110>
mov    %rdx,%rax
neg    %rax
test   $0x1,%sil
cmove  %rdx,%rax
test   %rdi,%rdi
cmovns %rdx,%rax
ret

LLVM IR (-O0):
define i64 @pow(i64 %0, i64 %1) {
%3 = alloca i64
%4 = alloca i64
%5 = alloca i64
%6 = alloca i32
%7 = alloca i64
%8 = alloca i64
%9 = alloca i64
store i64 %0, i64* %4
store i64 %1, i64* %5
%10 = load i64, i64* %5
%11 = icmp slt i64 %10, 0
br i1 %11, label %12, label %13
12: ; preds = %2
store i64 -1, i64* %3
br label %57
13: ; preds = %2
%14 = load i64, i64* %5
%15 = icmp eq i64 %14, 0
br i1 %15, label %16, label %17
16: ; preds = %13
store i64 1, i64* %3
br label %57
17: ; preds = %13
store i32 0, i32* %6
%18 = load i64, i64* %4
%19 = icmp slt i64 %18, 0
br i1 %19, label %20, label %21
20: ; preds = %17
store i32 1, i32* %6
br label %21
21: ; preds = %20, %17
%22 = load i64, i64* %4
%23 = call i64 @abs(i64 %22)
store i64 %23, i64* %4
%24 = load i64, i64* %4
store i64 %24, i64* %7
store i64 0, i64* %8
br label %25
25: ; preds = %42, %21
%26 = load i64, i64* %8
%27 = load i64, i64* %5
%28 = icmp slt i64 %26, %27
br i1 %28, label %29, label %45
29: ; preds = %25
store i64 0, i64* %9
br label %30
30: ; preds = %38, %29
%31 = load i64, i64* %9
%32 = load i64, i64* %7
%33 = icmp slt i64 %31, %32
br i1 %33, label %34, label %41
34: ; preds = %30
%35 = load i64, i64* %7
%36 = load i64, i64* %4
%37 = add nsw i64 %36, %35
store i64 %37, i64* %4
br label %38
38: ; preds = %34
%39 = load i64, i64* %9
%40 = add nsw i64 %39, 1
store i64 %40, i64* %9
br label %30
41: ; preds = %30
br label %42
42: ; preds = %41
%43 = load i64, i64* %8
%44 = add nsw i64 %43, 1
store i64 %44, i64* %8
br label %25
45: ; preds = %25
%46 = load i32, i32* %6
%47 = icmp ne i32 %46, 0
br i1 %47, label %48, label %55
48: ; preds = %45
%49 = load i64, i64* %5
%50 = and i64 %49, 1
%51 = icmp ne i64 %50, 0
br i1 %51, label %52, label %55
52: ; preds = %48
%53 = load i64, i64* %4
%54 = sub nsw i64 0, %53
store i64 %54, i64* %3
br label %57
55: ; preds = %48, %45
%56 = load i64, i64* %4
store i64 %56, i64* %3
br label %57
57: ; preds = %55, %52, %16, %12
%58 = load i64, i64* %3
ret i64 %58
}

LLVM IR (-O2):
define i64 @pow(i64 %0, i64 %1) {
%3 = icmp slt i64 %1, 0
br i1 %3, label %89, label %4
4: ; preds = %2
%5 = icmp eq i64 %1, 0
br i1 %5, label %89, label %6
6: ; preds = %4
%7 = icmp sgt i64 %0, -1
%8 = tail call i64 @llvm.abs.i64(i64 %0, i1 true)
%9 = icmp eq i64 %0, 0
%10 = call i64 @llvm.umax.i64(i64 %8, i64 1)
%11 = mul i64 %8, %10
%12 = icmp ult i64 %1, 4
br i1 %12, label %72, label %13
13: ; preds = %6
%14 = and i64 %1, -4
%15 = insertelement <2 x i64> <i64 poison, i64 0>, i64 %8, i64 0
%16 = insertelement <2 x i64> poison, i64 %11, i64 0
%17 = shufflevector <2 x i64> %16, <2 x i64> poison, <2 x i32> zeroinitializer
%18 = insertelement <2 x i64> poison, i64 %11, i64 0
%19 = shufflevector <2 x i64> %18, <2 x i64> poison, <2 x i32> zeroinitializer
%20 = add i64 %14, -4
%21 = lshr exact i64 %20, 2
%22 = add nuw nsw i64 %21, 1
%23 = and i64 %22, 3
%24 = icmp ult i64 %20, 12
br i1 %24, label %49, label %25
25: ; preds = %13
%26 = and i64 %22, 9223372036854775804
%27 = select i1 %9, <2 x i64> zeroinitializer, <2 x i64> %17
%28 = select i1 %9, <2 x i64> zeroinitializer, <2 x i64> %19
%29 = select i1 %9, <2 x i64> zeroinitializer, <2 x i64> %17
%30 = select i1 %9, <2 x i64> zeroinitializer, <2 x i64> %19
%31 = select i1 %9, <2 x i64> zeroinitializer, <2 x i64> %17
%32 = select i1 %9, <2 x i64> zeroinitializer, <2 x i64> %19
%33 = select i1 %9, <2 x i64> zeroinitializer, <2 x i64> %17
%34 = select i1 %9, <2 x i64> zeroinitializer, <2 x i64> %19
br label %35
35: ; preds = %35, %25
%36 = phi <2 x i64> [ %15, %25 ], [ %45, %35 ]
%37 = phi <2 x i64> [ zeroinitializer, %25 ], [ %46, %35 ]
%38 = phi i64 [ 0, %25 ], [ %47, %35 ]
%39 = add <2 x i64> %36, %27
%40 = add <2 x i64> %37, %28
%41 = add <2 x i64> %39, %29
%42 = add <2 x i64> %40, %30
%43 = add <2 x i64> %41, %31
%44 = add <2 x i64> %42, %32
%45 = add <2 x i64> %43, %33
%46 = add <2 x i64> %44, %34
%47 = add nuw i64 %38, 4
%48 = icmp eq i64 %47, %26
br i1 %48, label %49, label %35
49: ; preds = %35, %13
%50 = phi <2 x i64> [ undef, %13 ], [ %45, %35 ]
%51 = phi <2 x i64> [ undef, %13 ], [ %46, %35 ]
%52 = phi <2 x i64> [ %15, %13 ], [ %45, %35 ]
%53 = phi <2 x i64> [ zeroinitializer, %13 ], [ %46, %35 ]
%54 = icmp eq i64 %23, 0
br i1 %54, label %66, label %55
55: ; preds = %49
%56 = select i1 %9, <2 x i64> zeroinitializer, <2 x i64> %17
%57 = select i1 %9, <2 x i64> zeroinitializer, <2 x i64> %19
br label %58
58: ; preds = %58, %55
%59 = phi <2 x i64> [ %52, %55 ], [ %62, %58 ]
%60 = phi <2 x i64> [ %53, %55 ], [ %63, %58 ]
%61 = phi i64 [ 0, %55 ], [ %64, %58 ]
%62 = add <2 x i64> %59, %56
%63 = add <2 x i64> %60, %57
%64 = add i64 %61, 1
%65 = icmp eq i64 %64, %23
br i1 %65, label %66, label %58
66: ; preds = %58, %49
%67 = phi <2 x i64> [ %50, %49 ], [ %62, %58 ]
%68 = phi <2 x i64> [ %51, %49 ], [ %63, %58 ]
%69 = add <2 x i64> %68, %67
%70 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %69)
%71 = icmp eq i64 %14, %1
br i1 %71, label %82, label %72
72: ; preds = %6, %66
%73 = phi i64 [ 0, %6 ], [ %14, %66 ]
%74 = phi i64 [ %8, %6 ], [ %70, %66 ]
%75 = select i1 %9, i64 0, i64 %11
br label %76
76: ; preds = %72, %76
%77 = phi i64 [ %80, %76 ], [ %73, %72 ]
%78 = phi i64 [ %79, %76 ], [ %74, %72 ]
%79 = add i64 %78, %75
%80 = add nuw nsw i64 %77, 1
%81 = icmp eq i64 %80, %1
br i1 %81, label %82, label %76
82: ; preds = %76, %66
%83 = phi i64 [ %70, %66 ], [ %79, %76 ]
%84 = and i64 %1, 1
%85 = icmp eq i64 %84, 0
%86 = or i1 %7, %85
%87 = sub nsw i64 0, %83
%88 = select i1 %86, i64 %83, i64 %87
br label %89
89: ; preds = %4, %2, %82
%90 = phi i64 [ %88, %82 ], [ -1, %2 ], [ 1, %4 ]
ret i64 %90
}