#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 uint32_t;

/* Variables and functions */
int /*<<< orphan*/ assert(int /*<<< orphan*/);
int /*<<< orphan*/ f2m_is_equal(int, int *, int *);
int /*<<< orphan*/ f2m_square(int, int *, int *);
int /*<<< orphan*/ initZero(int, int *);
int /*<<< orphan*/ printf(char *);
void testSquaring() {
  printf("Testing squaring\n");
  uint32_t input1[6] = {0xA9, 0x100, 0x0, 0x0, 0x0, 0x0};
  uint32_t result1[12];
  f2m_square(6, input1, result1);
  uint32_t validResult1[12] = {0x4441, 0x0, 0x10000, 0x0, 0x0, 0x0,
                               0x0,    0x0, 0x0,     0x0, 0x0, 0x0};
  assert(f2m_is_equal(12, result1, validResult1));
  uint32_t input2[6] = {0x10116, 0x1, 0x0, 0x10000, 0x0, 0x0};
  uint32_t result2[12];
  f2m_square(6, input2, result2);
  uint32_t validResult2[12] = {0x10114, 0x1, 0x1, 0x0, 0x0, 0x0,
                               0x0,     0x1, 0x0, 0x0, 0x0, 0x0};
  assert(f2m_is_equal(12, result2, validResult2));
  uint32_t input3[6] = {0x6CA670CF, 0x1, 0x0, 0x10000, 0x0, 0x80000000};
  uint32_t result3[12];
  f2m_square(6, input3, result3);
  uint32_t validResult3[12] = {0x15005055, 0x14504414, 0x1, 0x0,
                               0x0,        0x0,        0x0, 0x1,
                               0x0,        0x0,        0x0, 0x40000000};
  assert(f2m_is_equal(12, result3, validResult3));
  uint32_t r24[24];
  initZero(24, r24);
  f2m_square(12, validResult3, r24);
  uint32_t vr24[24] = {
      0x11001111, 0x1110000, 0x10100110, 0x1101100, 0x1, 0x0, 0x0, 0x0,
      0x0,        0x0,       0x0,        0x0,       0x0, 0x0, 0x1, 0x0,
      0x0,        0x0,       0x0,        0x0,       0x0, 0x0, 0x0, 0x10000000};
  printf("Tests squaring passed\n");
}


x86 assembly (clang, -O0):
<testSquaring>:
push   %rbp
mov    %rsp,%rbp
sub    $0x240,%rsp
lea    0xe7e(%rip),%rdi
call   1050 <printf@plt>
mov    0xea2(%rip),%rax
mov    %rax,-0x20(%rbp)
mov    0xe9f(%rip),%rax
mov    %rax,-0x18(%rbp)
mov    0xe9c(%rip),%rax
mov    %rax,-0x10(%rbp)
lea    -0x20(%rbp),%rsi
lea    -0x50(%rbp),%rdx
mov    $0x6,%edi
call   1090 <f2m_square@plt>
lea    -0x80(%rbp),%rdi
xor    %esi,%esi
mov    $0x30,%edx
call   1060 <memset@plt>
movl   $0x4441,-0x80(%rbp)
movl   $0x10000,-0x78(%rbp)
lea    -0x50(%rbp),%rsi
lea    -0x80(%rbp),%rdx
mov    $0xc,%edi
call   1030 <f2m_is_equal@plt>
mov    %eax,%edi
call   1070 <assert@plt>
mov    0xe58(%rip),%rax
mov    %rax,-0xa0(%rbp)
mov    0xe52(%rip),%rax
mov    %rax,-0x98(%rbp)
mov    0xe4c(%rip),%rax
mov    %rax,-0x90(%rbp)
lea    -0xa0(%rbp),%rsi
lea    -0xd0(%rbp),%rdx
mov    $0x6,%edi
call   1090 <f2m_square@plt>
lea    -0x100(%rbp),%rdi
xor    %esi,%esi
mov    $0x30,%edx
call   1060 <memset@plt>
movl   $0x10114,-0x100(%rbp)
movl   $0x1,-0xfc(%rbp)
movl   $0x1,-0xf8(%rbp)
movl   $0x1,-0xe4(%rbp)
lea    -0xd0(%rbp),%rsi
lea    -0x100(%rbp),%rdx
mov    $0xc,%edi
call   1030 <f2m_is_equal@plt>
mov    %eax,%edi
call   1070 <assert@plt>
mov    0xddc(%rip),%rax
mov    %rax,-0x120(%rbp)
mov    0xdd6(%rip),%rax
mov    %rax,-0x118(%rbp)
mov    0xdd0(%rip),%rax
mov    %rax,-0x110(%rbp)
lea    -0x120(%rbp),%rsi
lea    -0x150(%rbp),%rdx
mov    $0x6,%edi
call   1090 <f2m_square@plt>
lea    -0x180(%rbp),%rdi
xor    %esi,%esi
mov    $0x30,%edx
call   1060 <memset@plt>
movl   $0x15005055,-0x180(%rbp)
movl   $0x14504414,-0x17c(%rbp)
44 50 14
movl   $0x1,-0x178(%rbp)
movl   $0x1,-0x164(%rbp)
movl   $0x40000000,-0x154(%rbp)
lea    -0x150(%rbp),%rsi
lea    -0x180(%rbp),%rdx
mov    $0xc,%edi
call   1030 <f2m_is_equal@plt>
mov    %eax,%edi
call   1070 <assert@plt>
lea    -0x1e0(%rbp),%rsi
mov    $0x18,%edi
call   1040 <initZero@plt>
lea    -0x180(%rbp),%rsi
lea    -0x1e0(%rbp),%rdx
mov    $0xc,%edi
call   1090 <f2m_square@plt>
lea    -0x240(%rbp),%rdi
lea    0xd26(%rip),%rsi
mov    $0x60,%edx
call   1080 <memcpy@plt>
lea    0xc97(%rip),%rdi
call   1050 <printf@plt>
add    $0x240,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<testSquaring>:
push   %r14
push   %rbx
sub    $0x1e8,%rsp
lea    0xef7(%rip),%rdi
call   1030 <puts@plt>
mov    0xea3(%rip),%rax
mov    %rax,0xe0(%rsp)
movaps 0xe84(%rip),%xmm0
movaps %xmm0,0xd0(%rsp)
lea    0xd0(%rsp),%rsi
lea    0x150(%rsp),%rbx
mov    $0x6,%edi
mov    %rbx,%rdx
call   1070 <f2m_square@plt>
xorps  %xmm0,%xmm0
movaps %xmm0,0xa0(%rsp)
movaps %xmm0,0xc0(%rsp)
movaps %xmm0,0xb0(%rsp)
movl   $0x4441,0xa0(%rsp)
movl   $0x10000,0xa8(%rsp)
lea    0xa0(%rsp),%rdx
mov    $0xc,%edi
mov    %rbx,%rsi
call   1040 <f2m_is_equal@plt>
mov    %eax,%edi
call   1060 <assert@plt>
mov    0xe3b(%rip),%rax
mov    %rax,0x90(%rsp)
movaps 0xe1c(%rip),%xmm0
movaps %xmm0,0x80(%rsp)
lea    0x80(%rsp),%rsi
lea    0x120(%rsp),%rbx
mov    $0x6,%edi
mov    %rbx,%rdx
call   1070 <f2m_square@plt>
xorps  %xmm0,%xmm0
movaps %xmm0,0x30(%rsp)
movaps %xmm0,0x40(%rsp)
movaps %xmm0,0x50(%rsp)
movabs $0x100010114,%rax
mov    %rax,0x30(%rsp)
movl   $0x1,0x38(%rsp)
movl   $0x1,0x4c(%rsp)
lea    0x30(%rsp),%rdx
mov    $0xc,%edi
mov    %rbx,%rsi
call   1040 <f2m_is_equal@plt>
mov    %eax,%edi
call   1060 <assert@plt>
mov    0xdd6(%rip),%rax
mov    %rax,0x70(%rsp)
movaps 0xdba(%rip),%xmm0
movaps %xmm0,0x60(%rsp)
lea    0x60(%rsp),%rsi
lea    0xf0(%rsp),%rbx
mov    $0x6,%edi
mov    %rbx,%rdx
call   1070 <f2m_square@plt>
xorps  %xmm0,%xmm0
movaps %xmm0,(%rsp)
movaps %xmm0,0x10(%rsp)
movaps %xmm0,0x20(%rsp)
movabs $0x1450441415005055,%rax
44 50 14
mov    %rax,(%rsp)
movl   $0x1,0x8(%rsp)
movl   $0x1,0x1c(%rsp)
movl   $0x40000000,0x2c(%rsp)
40
mov    %rsp,%r14
mov    $0xc,%edi
mov    %rbx,%rsi
mov    %r14,%rdx
call   1040 <f2m_is_equal@plt>
mov    %eax,%edi
call   1060 <assert@plt>
lea    0x180(%rsp),%rbx
mov    $0x18,%edi
mov    %rbx,%rsi
call   1050 <initZero@plt>
mov    $0xc,%edi
mov    %r14,%rsi
mov    %rbx,%rdx
call   1070 <f2m_square@plt>
lea    0xd47(%rip),%rdi
call   1030 <puts@plt>
add    $0x1e8,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
@.str = [18 x i8] c"Testing squaring\0A\00"
@__const.testSquaring.input1 = [6 x i32] [i32 169, i32 256, i32 0, i32 0, i32 0, i32 0]
@__const.testSquaring.input2 = [6 x i32] [i32 65814, i32 1, i32 0, i32 65536, i32 0, i32 0]
@__const.testSquaring.input3 = [6 x i32] [i32 1822847183, i32 1, i32 0, i32 65536, i32 0, i32 -2147483648]
@__const.testSquaring.vr24 = [24 x i32] [i32 285217041, i32 17891328, i32 269484304, i32 17830144, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 268435456]
@.str.1 = [23 x i8] c"Tests squaring passed\0A\00"
define void @testSquaring() {
%1 = alloca [6 x i32]
%2 = alloca [12 x i32]
%3 = alloca [12 x i32]
%4 = alloca [6 x i32]
%5 = alloca [12 x i32]
%6 = alloca [12 x i32]
%7 = alloca [6 x i32]
%8 = alloca [12 x i32]
%9 = alloca [12 x i32]
%10 = alloca [24 x i32]
%11 = alloca [24 x i32]
%12 = call i32 @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str, i64 0, i64 0))
%13 = bitcast [6 x i32]* %1 to i8*
%14 = getelementptr inbounds [6 x i32], [6 x i32]* %1, i64 0, i64 0
%15 = getelementptr inbounds [12 x i32], [12 x i32]* %2, i64 0, i64 0
%16 = call i32 @f2m_square(i32 6, i32* %14, i32* %15)
%17 = bitcast [12 x i32]* %3 to i8*
%18 = bitcast i8* %17 to <{ i32, i32, i32, [9 x i32] }>*
%19 = getelementptr inbounds <{ i32, i32, i32, [9 x i32] }>, <{ i32, i32, i32, [9 x i32] }>* %18, i32 0, i32 0
store i32 17473, i32* %19
%20 = getelementptr inbounds <{ i32, i32, i32, [9 x i32] }>, <{ i32, i32, i32, [9 x i32] }>* %18, i32 0, i32 2
store i32 65536, i32* %20
%21 = getelementptr inbounds [12 x i32], [12 x i32]* %2, i64 0, i64 0
%22 = getelementptr inbounds [12 x i32], [12 x i32]* %3, i64 0, i64 0
%23 = call i32 @f2m_is_equal(i32 12, i32* %21, i32* %22)
%24 = call i32 @assert(i32 %23)
%25 = bitcast [6 x i32]* %4 to i8*
%26 = getelementptr inbounds [6 x i32], [6 x i32]* %4, i64 0, i64 0
%27 = getelementptr inbounds [12 x i32], [12 x i32]* %5, i64 0, i64 0
%28 = call i32 @f2m_square(i32 6, i32* %26, i32* %27)
%29 = bitcast [12 x i32]* %6 to i8*
%30 = bitcast i8* %29 to [12 x i32]*
%31 = getelementptr inbounds [12 x i32], [12 x i32]* %30, i32 0, i32 0
store i32 65812, i32* %31
%32 = getelementptr inbounds [12 x i32], [12 x i32]* %30, i32 0, i32 1
store i32 1, i32* %32
%33 = getelementptr inbounds [12 x i32], [12 x i32]* %30, i32 0, i32 2
store i32 1, i32* %33
%34 = getelementptr inbounds [12 x i32], [12 x i32]* %30, i32 0, i32 7
store i32 1, i32* %34
%35 = getelementptr inbounds [12 x i32], [12 x i32]* %5, i64 0, i64 0
%36 = getelementptr inbounds [12 x i32], [12 x i32]* %6, i64 0, i64 0
%37 = call i32 @f2m_is_equal(i32 12, i32* %35, i32* %36)
%38 = call i32 @assert(i32 %37)
%39 = bitcast [6 x i32]* %7 to i8*
%40 = getelementptr inbounds [6 x i32], [6 x i32]* %7, i64 0, i64 0
%41 = getelementptr inbounds [12 x i32], [12 x i32]* %8, i64 0, i64 0
%42 = call i32 @f2m_square(i32 6, i32* %40, i32* %41)
%43 = bitcast [12 x i32]* %9 to i8*
%44 = bitcast i8* %43 to [12 x i32]*
%45 = getelementptr inbounds [12 x i32], [12 x i32]* %44, i32 0, i32 0
store i32 352342101, i32* %45
%46 = getelementptr inbounds [12 x i32], [12 x i32]* %44, i32 0, i32 1
store i32 340804628, i32* %46
%47 = getelementptr inbounds [12 x i32], [12 x i32]* %44, i32 0, i32 2
store i32 1, i32* %47
%48 = getelementptr inbounds [12 x i32], [12 x i32]* %44, i32 0, i32 7
store i32 1, i32* %48
%49 = getelementptr inbounds [12 x i32], [12 x i32]* %44, i32 0, i32 11
store i32 1073741824, i32* %49
%50 = getelementptr inbounds [12 x i32], [12 x i32]* %8, i64 0, i64 0
%51 = getelementptr inbounds [12 x i32], [12 x i32]* %9, i64 0, i64 0
%52 = call i32 @f2m_is_equal(i32 12, i32* %50, i32* %51)
%53 = call i32 @assert(i32 %52)
%54 = getelementptr inbounds [24 x i32], [24 x i32]* %10, i64 0, i64 0
%55 = call i32 @initZero(i32 24, i32* %54)
%56 = getelementptr inbounds [12 x i32], [12 x i32]* %9, i64 0, i64 0
%57 = getelementptr inbounds [24 x i32], [24 x i32]* %10, i64 0, i64 0
%58 = call i32 @f2m_square(i32 12, i32* %56, i32* %57)
%59 = bitcast [24 x i32]* %11 to i8*
%60 = call i32 @printf(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.1, i64 0, i64 0))
ret void
}

LLVM IR (-O2):
@__const.testSquaring.input1 = [6 x i32] [i32 169, i32 256, i32 0, i32 0, i32 0, i32 0]
@__const.testSquaring.input2 = [6 x i32] [i32 65814, i32 1, i32 0, i32 65536, i32 0, i32 0]
@__const.testSquaring.input3 = [6 x i32] [i32 1822847183, i32 1, i32 0, i32 65536, i32 0, i32 -2147483648]
@str = [17 x i8] c"Testing squaring\00"
@str.2 = [22 x i8] c"Tests squaring passed\00"
define void @testSquaring() {
%1 = alloca [6 x i32]
%2 = alloca [12 x i32]
%3 = alloca [12 x i32]
%4 = alloca [6 x i32]
%5 = alloca [12 x i32]
%6 = alloca [12 x i32]
%7 = alloca [6 x i32]
%8 = alloca [12 x i32]
%9 = alloca [12 x i32]
%10 = alloca [24 x i32]
%11 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([17 x i8], [17 x i8]* @str, i64 0, i64 0))
%12 = bitcast [6 x i32]* %1 to i8*
%13 = bitcast [12 x i32]* %2 to i8*
%14 = getelementptr inbounds [6 x i32], [6 x i32]* %1, i64 0, i64 0
%15 = getelementptr inbounds [12 x i32], [12 x i32]* %2, i64 0, i64 0
%16 = call i32 @f2m_square(i32 6, i32* %14, i32* %15)
%17 = bitcast [12 x i32]* %3 to i8*
%18 = getelementptr inbounds [12 x i32], [12 x i32]* %3, i64 0, i64 0
store i32 17473, i32* %18
%19 = getelementptr inbounds [12 x i32], [12 x i32]* %3, i64 0, i64 2
store i32 65536, i32* %19
%20 = call i32 @f2m_is_equal(i32 12, i32* %15, i32* %18)
%21 = call i32 @assert(i32 %20)
%22 = bitcast [6 x i32]* %4 to i8*
%23 = bitcast [12 x i32]* %5 to i8*
%24 = getelementptr inbounds [6 x i32], [6 x i32]* %4, i64 0, i64 0
%25 = getelementptr inbounds [12 x i32], [12 x i32]* %5, i64 0, i64 0
%26 = call i32 @f2m_square(i32 6, i32* %24, i32* %25)
%27 = bitcast [12 x i32]* %6 to i8*
%28 = getelementptr inbounds [12 x i32], [12 x i32]* %6, i64 0, i64 0
store i32 65812, i32* %28
%29 = getelementptr inbounds [12 x i32], [12 x i32]* %6, i64 0, i64 1
store i32 1, i32* %29
%30 = getelementptr inbounds [12 x i32], [12 x i32]* %6, i64 0, i64 2
store i32 1, i32* %30
%31 = getelementptr inbounds [12 x i32], [12 x i32]* %6, i64 0, i64 7
store i32 1, i32* %31
%32 = call i32 @f2m_is_equal(i32 12, i32* %25, i32* %28)
%33 = call i32 @assert(i32 %32)
%34 = bitcast [6 x i32]* %7 to i8*
%35 = bitcast [12 x i32]* %8 to i8*
%36 = getelementptr inbounds [6 x i32], [6 x i32]* %7, i64 0, i64 0
%37 = getelementptr inbounds [12 x i32], [12 x i32]* %8, i64 0, i64 0
%38 = call i32 @f2m_square(i32 6, i32* %36, i32* %37)
%39 = bitcast [12 x i32]* %9 to i8*
%40 = getelementptr inbounds [12 x i32], [12 x i32]* %9, i64 0, i64 0
store i32 352342101, i32* %40
%41 = getelementptr inbounds [12 x i32], [12 x i32]* %9, i64 0, i64 1
store i32 340804628, i32* %41
%42 = getelementptr inbounds [12 x i32], [12 x i32]* %9, i64 0, i64 2
store i32 1, i32* %42
%43 = getelementptr inbounds [12 x i32], [12 x i32]* %9, i64 0, i64 7
store i32 1, i32* %43
%44 = getelementptr inbounds [12 x i32], [12 x i32]* %9, i64 0, i64 11
store i32 1073741824, i32* %44
%45 = call i32 @f2m_is_equal(i32 12, i32* %37, i32* %40)
%46 = call i32 @assert(i32 %45)
%47 = bitcast [24 x i32]* %10 to i8*
%48 = getelementptr inbounds [24 x i32], [24 x i32]* %10, i64 0, i64 0
%49 = call i32 @initZero(i32 24, i32* %48)
%50 = call i32 @f2m_square(i32 12, i32* %40, i32* %48)
%51 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([22 x i8], [22 x i8]* @str.2, i64 0, i64 0))
ret void
}