#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 */
typedef int /*<<< orphan*/ odd_dividers;
typedef int /*<<< orphan*/ even_dividers;
typedef int /*<<< orphan*/ dividers;

/* Variables and functions */
int /*<<< orphan*/ assert(int);
int /*<<< orphan*/ skl_wrpll_get_multipliers(unsigned int, unsigned int *,
                                             unsigned int *, unsigned int *);
void test_multipliers(void) {
  static const int even_dividers[] = {
      4,  6,  8,  10, 12, 14, 16, 18, 20, 24, 28, 30, 32, 36, 40, 42, 44, 48,
      52, 54, 56, 60, 64, 66, 68, 70, 72, 76, 78, 80, 84, 88, 90, 92, 96, 98};
  static const int odd_dividers[] = {3, 5, 7, 9, 15, 21, 35};
  static const struct {
    const int *list;
    int n_dividers;
  } dividers[] = {
      {even_dividers, (sizeof(even_dividers) / sizeof(even_dividers[0]))},
      {odd_dividers, (sizeof(odd_dividers) / sizeof(odd_dividers[0]))},
  };
  unsigned int d, i;
  for (d = 0; d < (sizeof(dividers) / sizeof(dividers[0])); d++) {
    for (i = 0; i < dividers[d].n_dividers; i++) {
      unsigned int p = dividers[d].list[i];
      unsigned p0, p1, p2;
      p0 = p1 = p2 = 0;
      skl_wrpll_get_multipliers(p, &p0, &p1, &p2);
      assert(p0);
      assert(p1);
      assert(p2);
      assert(p == p0 * p1 * p2);
    }
  }
}


x86 assembly (clang, -O0):
<test_multipliers>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
cmp    $0x2,%rax
jae    1200 <test_multipliers+0xe0>
movl   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%eax
mov    -0x4(%rbp),%ecx
mov    %ecx,%edx
lea    0x2cae(%rip),%rcx
shl    $0x4,%rdx
add    %rdx,%rcx
cmp    0x8(%rcx),%eax
jae    11ed <test_multipliers+0xcd>
mov    -0x4(%rbp),%eax
mov    %eax,%ecx
lea    0x2c92(%rip),%rax
shl    $0x4,%rcx
add    %rcx,%rax
mov    (%rax),%rax
mov    -0x8(%rbp),%ecx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0xc(%rbp)
movl   $0x0,-0x18(%rbp)
movl   $0x0,-0x14(%rbp)
movl   $0x0,-0x10(%rbp)
mov    -0xc(%rbp),%edi
lea    -0x10(%rbp),%rsi
lea    -0x14(%rbp),%rdx
lea    -0x18(%rbp),%rcx
call   1030 <skl_wrpll_get_multipliers@plt>
mov    -0x10(%rbp),%edi
call   1040 <assert@plt>
mov    -0x14(%rbp),%edi
call   1040 <assert@plt>
mov    -0x18(%rbp),%edi
call   1040 <assert@plt>
mov    -0xc(%rbp),%eax
mov    -0x10(%rbp),%ecx
imul   -0x14(%rbp),%ecx
imul   -0x18(%rbp),%ecx
cmp    %ecx,%eax
sete   %al
and    $0x1,%al
movzbl %al,%edi
call   1040 <assert@plt>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    1143 <test_multipliers+0x23>
jmp    11f2 <test_multipliers+0xd2>
mov    -0x4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x4(%rbp)
jmp    112f <test_multipliers+0xf>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<test_multipliers>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
xor    %ebx,%ebx
lea    0xec9(%rip),%r13
lea    0x14(%rsp),%r14
lea    0x10(%rsp),%r15
lea    0xc(%rsp),%r12
cs nopw 0x0(%rax,%rax,1)
mov    (%rbx,%r13,1),%ebp
movl   $0x0,0xc(%rsp)
movl   $0x0,0x10(%rsp)
movl   $0x0,0x14(%rsp)
mov    %ebp,%edi
mov    %r14,%rsi
mov    %r15,%rdx
mov    %r12,%rcx
call   1030 <skl_wrpll_get_multipliers@plt>
mov    0x14(%rsp),%edi
call   1040 <assert@plt>
mov    0x10(%rsp),%edi
call   1040 <assert@plt>
mov    0xc(%rsp),%edi
call   1040 <assert@plt>
mov    0x10(%rsp),%eax
imul   0x14(%rsp),%eax
imul   0xc(%rsp),%eax
xor    %edi,%edi
cmp    %eax,%ebp
sete   %dil
call   1040 <assert@plt>
add    $0x4,%rbx
cmp    $0x90,%rbx
jne    1150 <test_multipliers+0x30>
xor    %ebx,%ebx
lea    0xec8(%rip),%r13
lea    0x14(%rsp),%r14
lea    0x10(%rsp),%r15
lea    0xc(%rsp),%r12
nopw   0x0(%rax,%rax,1)
mov    (%rbx,%r13,1),%ebp
movl   $0x0,0xc(%rsp)
movl   $0x0,0x10(%rsp)
movl   $0x0,0x14(%rsp)
mov    %ebp,%edi
mov    %r14,%rsi
mov    %r15,%rdx
mov    %r12,%rcx
call   1030 <skl_wrpll_get_multipliers@plt>
mov    0x14(%rsp),%edi
call   1040 <assert@plt>
mov    0x10(%rsp),%edi
call   1040 <assert@plt>
mov    0xc(%rsp),%edi
call   1040 <assert@plt>
mov    0x10(%rsp),%eax
imul   0x14(%rsp),%eax
imul   0xc(%rsp),%eax
xor    %edi,%edi
cmp    %eax,%ebp
sete   %dil
call   1040 <assert@plt>
add    $0x4,%rbx
cmp    $0x1c,%rbx
jne    11e0 <test_multipliers+0xc0>
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.anon = type { i32*, i32 }
@test_multipliers.even_dividers = internal constant [36 x i32] [i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 16, i32 18, i32 20, i32 24, i32 28, i32 30, i32 32, i32 36, i32 40, i32 42, i32 44, i32 48, i32 52, i32 54, i32 56, i32 60, i32 64, i32 66, i32 68, i32 70, i32 72, i32 76, i32 78, i32 80, i32 84, i32 88, i32 90, i32 92, i32 96, i32 98]
@test_multipliers.odd_dividers = internal constant [7 x i32] [i32 3, i32 5, i32 7, i32 9, i32 15, i32 21, i32 35]
@test_multipliers.dividers = internal constant [2 x %struct.anon] [%struct.anon { i32* getelementptr inbounds ([36 x i32], [36 x i32]* @test_multipliers.even_dividers, i32 0, i32 0), i32 36 }, %struct.anon { i32* getelementptr inbounds ([7 x i32], [7 x i32]* @test_multipliers.odd_dividers, i32 0, i32 0), i32 7 }]
define void @test_multipliers() {
%1 = alloca i32
%2 = alloca i32
%3 = alloca i32
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
store i32 0, i32* %1
br label %7
7: ; preds = %51, %0
%8 = load i32, i32* %1
%9 = zext i32 %8 to i64
%10 = icmp ult i64 %9, 2
br i1 %10, label %11, label %54
11: ; preds = %7
store i32 0, i32* %2
br label %12
12: ; preds = %47, %11
%13 = load i32, i32* %2
%14 = load i32, i32* %1
%15 = zext i32 %14 to i64
%16 = getelementptr inbounds [2 x %struct.anon], [2 x %struct.anon]* @test_multipliers.dividers, i64 0, i64 %15
%17 = getelementptr inbounds %struct.anon, %struct.anon* %16, i32 0, i32 1
%18 = load i32, i32* %17
%19 = icmp ult i32 %13, %18
br i1 %19, label %20, label %50
20: ; preds = %12
%21 = load i32, i32* %1
%22 = zext i32 %21 to i64
%23 = getelementptr inbounds [2 x %struct.anon], [2 x %struct.anon]* @test_multipliers.dividers, i64 0, i64 %22
%24 = getelementptr inbounds %struct.anon, %struct.anon* %23, i32 0, i32 0
%25 = load i32*, i32** %24
%26 = load i32, i32* %2
%27 = zext i32 %26 to i64
%28 = getelementptr inbounds i32, i32* %25, i64 %27
%29 = load i32, i32* %28
store i32 %29, i32* %3
store i32 0, i32* %6
store i32 0, i32* %5
store i32 0, i32* %4
%30 = load i32, i32* %3
%31 = call i32 @skl_wrpll_get_multipliers(i32 %30, i32* %4, i32* %5, i32* %6)
%32 = load i32, i32* %4
%33 = call i32 @assert(i32 %32)
%34 = load i32, i32* %5
%35 = call i32 @assert(i32 %34)
%36 = load i32, i32* %6
%37 = call i32 @assert(i32 %36)
%38 = load i32, i32* %3
%39 = load i32, i32* %4
%40 = load i32, i32* %5
%41 = mul i32 %39, %40
%42 = load i32, i32* %6
%43 = mul i32 %41, %42
%44 = icmp eq i32 %38, %43
%45 = zext i1 %44 to i32
%46 = call i32 @assert(i32 %45)
br label %47
47: ; preds = %20
%48 = load i32, i32* %2
%49 = add i32 %48, 1
store i32 %49, i32* %2
br label %12
50: ; preds = %12
br label %51
51: ; preds = %50
%52 = load i32, i32* %1
%53 = add i32 %52, 1
store i32 %53, i32* %1
br label %7
54: ; preds = %7
ret void
}

LLVM IR (-O2):
@test_multipliers.even_dividers = internal unnamed_addr constant [36 x i32] [i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 16, i32 18, i32 20, i32 24, i32 28, i32 30, i32 32, i32 36, i32 40, i32 42, i32 44, i32 48, i32 52, i32 54, i32 56, i32 60, i32 64, i32 66, i32 68, i32 70, i32 72, i32 76, i32 78, i32 80, i32 84, i32 88, i32 90, i32 92, i32 96, i32 98]
@test_multipliers.odd_dividers = internal unnamed_addr constant [7 x i32] [i32 3, i32 5, i32 7, i32 9, i32 15, i32 21, i32 35]
define void @test_multipliers() {
%1 = alloca i32
%2 = alloca i32
%3 = alloca i32
%4 = bitcast i32* %1 to i8*
%5 = bitcast i32* %2 to i8*
%6 = bitcast i32* %3 to i8*
br label %7
7: ; preds = %0, %7
%8 = phi i64 [ 0, %0 ], [ %26, %7 ]
%9 = getelementptr inbounds [36 x i32], [36 x i32]* @test_multipliers.even_dividers, i64 0, i64 %8
%10 = load i32, i32* %9
store i32 0, i32* %3
store i32 0, i32* %2
store i32 0, i32* %1
%11 = call i32 @skl_wrpll_get_multipliers(i32 %10, i32* %1, i32* %2, i32* %3)
%12 = load i32, i32* %1
%13 = call i32 @assert(i32 %12)
%14 = load i32, i32* %2
%15 = call i32 @assert(i32 %14)
%16 = load i32, i32* %3
%17 = call i32 @assert(i32 %16)
%18 = load i32, i32* %1
%19 = load i32, i32* %2
%20 = mul i32 %19, %18
%21 = load i32, i32* %3
%22 = mul i32 %20, %21
%23 = icmp eq i32 %10, %22
%24 = zext i1 %23 to i32
%25 = call i32 @assert(i32 %24)
%26 = add nuw nsw i64 %8, 1
%27 = icmp eq i64 %26, 36
br i1 %27, label %28, label %7
28: ; preds = %7, %28
%29 = phi i64 [ %47, %28 ], [ 0, %7 ]
%30 = getelementptr inbounds [7 x i32], [7 x i32]* @test_multipliers.odd_dividers, i64 0, i64 %29
%31 = load i32, i32* %30
store i32 0, i32* %3
store i32 0, i32* %2
store i32 0, i32* %1
%32 = call i32 @skl_wrpll_get_multipliers(i32 %31, i32* %1, i32* %2, i32* %3)
%33 = load i32, i32* %1
%34 = call i32 @assert(i32 %33)
%35 = load i32, i32* %2
%36 = call i32 @assert(i32 %35)
%37 = load i32, i32* %3
%38 = call i32 @assert(i32 %37)
%39 = load i32, i32* %1
%40 = load i32, i32* %2
%41 = mul i32 %40, %39
%42 = load i32, i32* %3
%43 = mul i32 %41, %42
%44 = icmp eq i32 %31, %43
%45 = zext i1 %44 to i32
%46 = call i32 @assert(i32 %45)
%47 = add nuw nsw i64 %29, 1
%48 = icmp eq i64 %47, 7
br i1 %48, label %49, label %28
49: ; preds = %28
ret void
}