#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 */
scalar_t__ floor(int);
int log(int);
unsigned long long pow(int, int);
scalar_t__ sqrt(int);
unsigned long long smallest_multiple_efficient(int num) {
  unsigned long long multiple = 1;
  int limit = (int)sqrt(num);
  bool check = true;
  int primes[25] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53};
  int count[25];
  int i = 0;
  while (primes[i] <= num) {
    count[i] = 1;
    if (check) {
      if (primes[i] <= limit) {
        count[i] = (int)floor(log(num) / log(primes[i]));
      } else {
        check = false;
      }
    }
    multiple *= pow(primes[i], count[i]);
    i++;
  }
  return multiple;
}


x86 assembly (clang, -O0):
<smallest_multiple_efficient>:
push   %rbp
mov    %rsp,%rbp
sub    $0x100,%rsp
mov    %edi,-0x4(%rbp)
movq   $0x1,-0x10(%rbp)
mov    -0x4(%rbp),%edi
call   1060 <sqrt@plt>
mov    %eax,-0x14(%rbp)
movl   $0x1,-0x18(%rbp)
lea    -0x80(%rbp),%rdi
lea    0xe7d(%rip),%rsi
mov    $0x64,%edx
call   1030 <memcpy@plt>
movl   $0x0,-0xf4(%rbp)
movslq -0xf4(%rbp),%rax
mov    -0x80(%rbp,%rax,4),%eax
cmp    -0x4(%rbp),%eax
jg     1267 <smallest_multiple_efficient+0x117>
movslq -0xf4(%rbp),%rax
movl   $0x1,-0xf0(%rbp,%rax,4)
cmpl   $0x0,-0x18(%rbp)
je     122c <smallest_multiple_efficient+0xdc>
movslq -0xf4(%rbp),%rax
mov    -0x80(%rbp,%rax,4),%eax
cmp    -0x14(%rbp),%eax
jg     1220 <smallest_multiple_efficient+0xd0>
mov    -0x4(%rbp),%edi
call   1040 <log@plt>
mov    %eax,-0xf8(%rbp)
movslq -0xf4(%rbp),%rax
mov    -0x80(%rbp,%rax,4),%edi
call   1040 <log@plt>
mov    %eax,%ecx
mov    -0xf8(%rbp),%eax
cltd
idiv   %ecx
mov    %eax,%edi
call   1070 <floor@plt>
mov    %eax,%ecx
movslq -0xf4(%rbp),%rax
mov    %ecx,-0xf0(%rbp,%rax,4)
jmp    1227 <smallest_multiple_efficient+0xd7>
movl   $0x0,-0x18(%rbp)
jmp    122c <smallest_multiple_efficient+0xdc>
movslq -0xf4(%rbp),%rax
mov    -0x80(%rbp,%rax,4),%edi
movslq -0xf4(%rbp),%rax
mov    -0xf0(%rbp,%rax,4),%esi
call   1050 <pow@plt>
imul   -0x10(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0xf4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xf4(%rbp)
jmp    1197 <smallest_multiple_efficient+0x47>
mov    -0x10(%rbp),%rax
add    $0x100,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<smallest_multiple_efficient>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %edi,%r15d
call   1050 <sqrt@plt>
mov    $0x1,%r13d
cmp    $0x2,%r15d
jge    1171 <smallest_multiple_efficient+0x31>
mov    %r13,%rax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
mov    %rax,%r14
mov    $0x1,%r13d
mov    $0x1,%r12d
mov    $0x2,%ebp
lea    0xe78(%rip),%rbx
jmp    11a6 <smallest_multiple_efficient+0x66>
xchg   %ax,%ax
mov    %ebp,%edi
call   1040 <pow@plt>
imul   %rax,%r13
mov    (%rbx),%ebp
add    $0x4,%rbx
cmp    %r15d,%ebp
jg     115f <smallest_multiple_efficient+0x1f>
mov    %r12d,%eax
xor    %r12d,%r12d
mov    $0x1,%esi
test   %eax,%eax
je     1190 <smallest_multiple_efficient+0x50>
cmp    %r14d,%ebp
jg     1190 <smallest_multiple_efficient+0x50>
mov    %r15d,%edi
call   1030 <log@plt>
mov    %eax,%r12d
mov    %ebp,%edi
call   1030 <log@plt>
mov    %eax,%ecx
mov    %r12d,%eax
cltd
idiv   %ecx
mov    %eax,%edi
call   1060 <floor@plt>
mov    %rax,%rsi
mov    $0x1,%r12d
jmp    1190 <smallest_multiple_efficient+0x50>

LLVM IR (-O0):
@__const.smallest_multiple_efficient.primes = <{ [16 x i32], [9 x i32] }> <{ [16 x i32] [i32 2, i32 3, i32 5, i32 7, i32 11, i32 13, i32 17, i32 19, i32 23, i32 29, i32 31, i32 37, i32 41, i32 43, i32 47, i32 53], [9 x i32] zeroinitializer }>
define i64 @smallest_multiple_efficient(i32 %0) {
%2 = alloca i32
%3 = alloca i64
%4 = alloca i32
%5 = alloca i32
%6 = alloca [25 x i32]
%7 = alloca [25 x i32]
%8 = alloca i32
store i32 %0, i32* %2
store i64 1, i64* %3
%9 = load i32, i32* %2
%10 = call i64 @sqrt(i32 %9)
%11 = trunc i64 %10 to i32
store i32 %11, i32* %4
store i32 1, i32* %5
%12 = bitcast [25 x i32]* %6 to i8*
store i32 0, i32* %8
br label %13
13: ; preds = %49, %1
%14 = load i32, i32* %8
%15 = sext i32 %14 to i64
%16 = getelementptr inbounds [25 x i32], [25 x i32]* %6, i64 0, i64 %15
%17 = load i32, i32* %16
%18 = load i32, i32* %2
%19 = icmp sle i32 %17, %18
br i1 %19, label %20, label %63
20: ; preds = %13
%21 = load i32, i32* %8
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds [25 x i32], [25 x i32]* %7, i64 0, i64 %22
store i32 1, i32* %23
%24 = load i32, i32* %5
%25 = icmp ne i32 %24, 0
br i1 %25, label %26, label %49
26: ; preds = %20
%27 = load i32, i32* %8
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds [25 x i32], [25 x i32]* %6, i64 0, i64 %28
%30 = load i32, i32* %29
%31 = load i32, i32* %4
%32 = icmp sle i32 %30, %31
br i1 %32, label %33, label %47
33: ; preds = %26
%34 = load i32, i32* %2
%35 = call i32 @log(i32 %34)
%36 = load i32, i32* %8
%37 = sext i32 %36 to i64
%38 = getelementptr inbounds [25 x i32], [25 x i32]* %6, i64 0, i64 %37
%39 = load i32, i32* %38
%40 = call i32 @log(i32 %39)
%41 = sdiv i32 %35, %40
%42 = call i64 @floor(i32 %41)
%43 = trunc i64 %42 to i32
%44 = load i32, i32* %8
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds [25 x i32], [25 x i32]* %7, i64 0, i64 %45
store i32 %43, i32* %46
br label %48
47: ; preds = %26
store i32 0, i32* %5
br label %48
48: ; preds = %47, %33
br label %49
49: ; preds = %48, %20
%50 = load i32, i32* %8
%51 = sext i32 %50 to i64
%52 = getelementptr inbounds [25 x i32], [25 x i32]* %6, i64 0, i64 %51
%53 = load i32, i32* %52
%54 = load i32, i32* %8
%55 = sext i32 %54 to i64
%56 = getelementptr inbounds [25 x i32], [25 x i32]* %7, i64 0, i64 %55
%57 = load i32, i32* %56
%58 = call i64 @pow(i32 %53, i32 %57)
%59 = load i64, i64* %3
%60 = mul i64 %59, %58
store i64 %60, i64* %3
%61 = load i32, i32* %8
%62 = add nsw i32 %61, 1
store i32 %62, i32* %8
br label %13
63: ; preds = %13
%64 = load i64, i64* %3
ret i64 %64
}

LLVM IR (-O2):
@__const.smallest_multiple_efficient.primes = <{ [16 x i32], [9 x i32] }> <{ [16 x i32] [i32 2, i32 3, i32 5, i32 7, i32 11, i32 13, i32 17, i32 19, i32 23, i32 29, i32 31, i32 37, i32 41, i32 43, i32 47, i32 53], [9 x i32] zeroinitializer }>
define i64 @smallest_multiple_efficient(i32 %0) {
%2 = tail call i64 @sqrt(i32 %0)
%3 = trunc i64 %2 to i32
%4 = icmp slt i32 %0, 2
br i1 %4, label %28, label %5
5: ; preds = %1, %19
%6 = phi i64 [ %24, %19 ], [ 0, %1 ]
%7 = phi i32 [ %26, %19 ], [ 2, %1 ]
%8 = phi i32 [ %21, %19 ], [ 1, %1 ]
%9 = phi i64 [ %23, %19 ], [ 1, %1 ]
%10 = icmp eq i32 %8, 0
%11 = icmp sgt i32 %7, %3
%12 = select i1 %10, i1 true, i1 %11
br i1 %12, label %19, label %13
13: ; preds = %5
%14 = tail call i32 @log(i32 %0)
%15 = tail call i32 @log(i32 %7)
%16 = sdiv i32 %14, %15
%17 = tail call i64 @floor(i32 %16)
%18 = trunc i64 %17 to i32
br label %19
19: ; preds = %13, %5
%20 = phi i32 [ %18, %13 ], [ 1, %5 ]
%21 = phi i32 [ 1, %13 ], [ 0, %5 ]
%22 = tail call i64 @pow(i32 %7, i32 %20)
%23 = mul i64 %22, %9
%24 = add nuw i64 %6, 1
%25 = getelementptr inbounds [25 x i32], [25 x i32]* bitcast (<{ [16 x i32], [9 x i32] }>* @__const.smallest_multiple_efficient.primes to [25 x i32]*), i64 0, i64 %24
%26 = load i32, i32* %25
%27 = icmp sgt i32 %26, %0
br i1 %27, label %28, label %5
28: ; preds = %19, %1
%29 = phi i64 [ 1, %1 ], [ %23, %19 ]
ret i64 %29
}