#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 size_t uint;
typedef int /*<<< orphan*/ __m128;

/* Variables and functions */
scalar_t__ _mm_comilt_ss(int /*<<< orphan*/, int /*<<< orphan*/);
int /*<<< orphan*/ sse_bitonic_merge_4(int /*<<< orphan*/, int /*<<< orphan*/,
                                       int /*<<< orphan*/ *,
                                       int /*<<< orphan*/ *);
void sse_merge_aligned_32bit(void *a, void *b, void *dest, size_t size_a,
                             size_t size_b) {
  size_t size_a_128 = size_a >> 2;
  size_t size_b_128 = size_b >> 2;
  __m128 *a128 = (__m128 *)a;
  __m128 *b128 = (__m128 *)b;
  __m128 *dest128 = (__m128 *)dest;
  uint crt_a = 0;
  uint crt_b = 0;
  uint next_val = 0;
  __m128 next;
  __m128 last;
  if (_mm_comilt_ss(*a128, *b128)) {
    next = *b128;
    crt_b++;
  } else {
    next = *a128;
    crt_a++;
  }
  while ((crt_a < size_a_128) || (crt_b < size_b_128)) {
    if ((crt_a < size_a_128) &&
        ((crt_b >= size_b_128) ||
         (_mm_comilt_ss(*(a128 + crt_a), *(b128 + crt_b))))) {
      sse_bitonic_merge_4(next, a128[crt_a], &(dest128[next_val]), &last);
      crt_a++;
    } else {
      sse_bitonic_merge_4(next, b128[crt_b], &(dest128[next_val]), &last);
      crt_b++;
    }
    next_val++;
    next = last;
  }
  *(dest128 + next_val) = next;
}


x86 assembly (clang, -O0):
<sse_merge_aligned_32bit>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    -0x20(%rbp),%rax
shr    $0x2,%rax
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
shr    $0x2,%rax
mov    %rax,-0x38(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x48(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x50(%rbp)
movq   $0x0,-0x58(%rbp)
movq   $0x0,-0x60(%rbp)
movq   $0x0,-0x68(%rbp)
mov    -0x40(%rbp),%rax
mov    (%rax),%edi
mov    -0x48(%rbp),%rax
mov    (%rax),%esi
call   1030 <_mm_comilt_ss@plt>
cmp    $0x0,%rax
je     11bc <sse_merge_aligned_32bit+0x9c>
mov    -0x48(%rbp),%rax
mov    (%rax),%eax
mov    %eax,-0x6c(%rbp)
mov    -0x60(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x60(%rbp)
jmp    11d1 <sse_merge_aligned_32bit+0xb1>
mov    -0x40(%rbp),%rax
mov    (%rax),%eax
mov    %eax,-0x6c(%rbp)
mov    -0x58(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x58(%rbp)
jmp    11d6 <sse_merge_aligned_32bit+0xb6>
mov    -0x58(%rbp),%rcx
mov    $0x1,%al
cmp    -0x30(%rbp),%rcx
mov    %al,-0x71(%rbp)
jb     11f7 <sse_merge_aligned_32bit+0xd7>
mov    -0x60(%rbp),%rax
cmp    -0x38(%rbp),%rax
setb   %al
mov    %al,-0x71(%rbp)
mov    -0x71(%rbp),%al
test   $0x1,%al
jne    1207 <sse_merge_aligned_32bit+0xe7>
jmp    12c8 <sse_merge_aligned_32bit+0x1a8>
mov    -0x58(%rbp),%rax
cmp    -0x30(%rbp),%rax
jae    127f <sse_merge_aligned_32bit+0x15f>
mov    -0x60(%rbp),%rax
cmp    -0x38(%rbp),%rax
jae    1248 <sse_merge_aligned_32bit+0x128>
mov    -0x40(%rbp),%rax
mov    -0x58(%rbp),%rcx
mov    (%rax,%rcx,4),%edi
mov    -0x48(%rbp),%rax
mov    -0x60(%rbp),%rcx
mov    (%rax,%rcx,4),%esi
call   1030 <_mm_comilt_ss@plt>
cmp    $0x0,%rax
je     127f <sse_merge_aligned_32bit+0x15f>
mov    -0x6c(%rbp),%edi
mov    -0x40(%rbp),%rax
mov    -0x58(%rbp),%rcx
mov    (%rax,%rcx,4),%esi
mov    -0x50(%rbp),%rdx
mov    -0x68(%rbp),%rax
shl    $0x2,%rax
add    %rax,%rdx
lea    -0x70(%rbp),%rcx
call   1040 <sse_bitonic_merge_4@plt>
mov    -0x58(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x58(%rbp)
jmp    12b1 <sse_merge_aligned_32bit+0x191>
mov    -0x6c(%rbp),%edi
mov    -0x48(%rbp),%rax
mov    -0x60(%rbp),%rcx
mov    (%rax,%rcx,4),%esi
mov    -0x50(%rbp),%rdx
mov    -0x68(%rbp),%rax
shl    $0x2,%rax
add    %rax,%rdx
lea    -0x70(%rbp),%rcx
call   1040 <sse_bitonic_merge_4@plt>
mov    -0x60(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x60(%rbp)
mov    -0x68(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x68(%rbp)
mov    -0x70(%rbp),%eax
mov    %eax,-0x6c(%rbp)
jmp    11d6 <sse_merge_aligned_32bit+0xb6>
mov    -0x6c(%rbp),%edx
mov    -0x50(%rbp),%rax
mov    -0x68(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<sse_merge_aligned_32bit>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    %r8,%rbx
mov    %rcx,%r15
mov    %rdx,0x8(%rsp)
mov    %rsi,%rbp
mov    %rdi,%r14
shr    $0x2,%r15
shr    $0x2,%rbx
mov    (%rdi),%edi
mov    (%rsi),%esi
call   1030 <_mm_comilt_ss@plt>
xor    %r13d,%r13d
xor    %r12d,%r12d
test   %rax,%rax
setne  %r13b
mov    %rbp,0x18(%rsp)
mov    %r14,0x10(%rsp)
cmove  %r14,%rbp
sete   %r12b
cmp    %r13,%rbx
seta   %al
mov    0x0(%rbp),%ebp
mov    %r15,0x20(%rsp)
cmp    %r12,%r15
seta   %cl
ja     1192 <sse_merge_aligned_32bit+0x72>
cmp    %r13,%rbx
ja     1192 <sse_merge_aligned_32bit+0x72>
xor    %r15d,%r15d
jmp    1235 <sse_merge_aligned_32bit+0x115>
xor    %r15d,%r15d
mov    0x8(%rsp),%r14
nopw   0x0(%rax,%rax,1)
test   $0x1,%cl
je     11f0 <sse_merge_aligned_32bit+0xd0>
test   $0x1,%al
je     11c5 <sse_merge_aligned_32bit+0xa5>
mov    0x10(%rsp),%rax
mov    (%rax,%r12,4),%edi
mov    0x18(%rsp),%rax
mov    (%rax,%r13,4),%esi
call   1030 <_mm_comilt_ss@plt>
test   %rax,%rax
je     11f0 <sse_merge_aligned_32bit+0xd0>
mov    0x10(%rsp),%rax
mov    (%rax,%r12,4),%esi
mov    %ebp,%edi
mov    %r14,%rdx
lea    0x4(%rsp),%rcx
call   1040 <sse_bitonic_merge_4@plt>
add    $0x1,%r12
jmp    120c <sse_merge_aligned_32bit+0xec>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    0x18(%rsp),%rax
mov    (%rax,%r13,4),%esi
mov    %ebp,%edi
mov    %r14,%rdx
lea    0x4(%rsp),%rcx
call   1040 <sse_bitonic_merge_4@plt>
add    $0x1,%r13
add    $0x1,%r15
mov    0x4(%rsp),%ebp
cmp    %rbx,%r13
setb   %al
add    $0x4,%r14
cmp    0x20(%rsp),%r12
setb   %cl
jb     11a0 <sse_merge_aligned_32bit+0x80>
cmp    %rbx,%r13
jb     11a0 <sse_merge_aligned_32bit+0x80>
mov    0x8(%rsp),%rax
mov    %ebp,(%rax,%r15,4)
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @sse_merge_aligned_32bit(i8* %0, i8* %1, i8* %2, i64 %3, i64 %4) {
%6 = alloca i8*
%7 = alloca i8*
%8 = alloca i8*
%9 = alloca i64
%10 = alloca i64
%11 = alloca i64
%12 = alloca i64
%13 = alloca i32*
%14 = alloca i32*
%15 = alloca i32*
%16 = alloca i64
%17 = alloca i64
%18 = alloca i64
%19 = alloca i32
%20 = alloca i32
store i8* %0, i8** %6
store i8* %1, i8** %7
store i8* %2, i8** %8
store i64 %3, i64* %9
store i64 %4, i64* %10
%21 = load i64, i64* %9
%22 = lshr i64 %21, 2
store i64 %22, i64* %11
%23 = load i64, i64* %10
%24 = lshr i64 %23, 2
store i64 %24, i64* %12
%25 = load i8*, i8** %6
%26 = bitcast i8* %25 to i32*
store i32* %26, i32** %13
%27 = load i8*, i8** %7
%28 = bitcast i8* %27 to i32*
store i32* %28, i32** %14
%29 = load i8*, i8** %8
%30 = bitcast i8* %29 to i32*
store i32* %30, i32** %15
store i64 0, i64* %16
store i64 0, i64* %17
store i64 0, i64* %18
%31 = load i32*, i32** %13
%32 = load i32, i32* %31
%33 = load i32*, i32** %14
%34 = load i32, i32* %33
%35 = call i64 @_mm_comilt_ss(i32 %32, i32 %34)
%36 = icmp ne i64 %35, 0
br i1 %36, label %37, label %42
37: ; preds = %5
%38 = load i32*, i32** %14
%39 = load i32, i32* %38
store i32 %39, i32* %19
%40 = load i64, i64* %17
%41 = add i64 %40, 1
store i64 %41, i64* %17
br label %47
42: ; preds = %5
%43 = load i32*, i32** %13
%44 = load i32, i32* %43
store i32 %44, i32* %19
%45 = load i64, i64* %16
%46 = add i64 %45, 1
store i64 %46, i64* %16
br label %47
47: ; preds = %42, %37
br label %48
48: ; preds = %101, %47
%49 = load i64, i64* %16
%50 = load i64, i64* %11
%51 = icmp ult i64 %49, %50
br i1 %51, label %56, label %52
52: ; preds = %48
%53 = load i64, i64* %17
%54 = load i64, i64* %12
%55 = icmp ult i64 %53, %54
br label %56
56: ; preds = %52, %48
%57 = phi i1 [ true, %48 ], [ %55, %52 ]
br i1 %57, label %58, label %105
58: ; preds = %56
%59 = load i64, i64* %16
%60 = load i64, i64* %11
%61 = icmp ult i64 %59, %60
br i1 %61, label %62, label %89
62: ; preds = %58
%63 = load i64, i64* %17
%64 = load i64, i64* %12
%65 = icmp uge i64 %63, %64
br i1 %65, label %77, label %66
66: ; preds = %62
%67 = load i32*, i32** %13
%68 = load i64, i64* %16
%69 = getelementptr inbounds i32, i32* %67, i64 %68
%70 = load i32, i32* %69
%71 = load i32*, i32** %14
%72 = load i64, i64* %17
%73 = getelementptr inbounds i32, i32* %71, i64 %72
%74 = load i32, i32* %73
%75 = call i64 @_mm_comilt_ss(i32 %70, i32 %74)
%76 = icmp ne i64 %75, 0
br i1 %76, label %77, label %89
77: ; preds = %66, %62
%78 = load i32, i32* %19
%79 = load i32*, i32** %13
%80 = load i64, i64* %16
%81 = getelementptr inbounds i32, i32* %79, i64 %80
%82 = load i32, i32* %81
%83 = load i32*, i32** %15
%84 = load i64, i64* %18
%85 = getelementptr inbounds i32, i32* %83, i64 %84
%86 = call i32 @sse_bitonic_merge_4(i32 %78, i32 %82, i32* %85, i32* %20)
%87 = load i64, i64* %16
%88 = add i64 %87, 1
store i64 %88, i64* %16
br label %101
89: ; preds = %66, %58
%90 = load i32, i32* %19
%91 = load i32*, i32** %14
%92 = load i64, i64* %17
%93 = getelementptr inbounds i32, i32* %91, i64 %92
%94 = load i32, i32* %93
%95 = load i32*, i32** %15
%96 = load i64, i64* %18
%97 = getelementptr inbounds i32, i32* %95, i64 %96
%98 = call i32 @sse_bitonic_merge_4(i32 %90, i32 %94, i32* %97, i32* %20)
%99 = load i64, i64* %17
%100 = add i64 %99, 1
store i64 %100, i64* %17
br label %101
101: ; preds = %89, %77
%102 = load i64, i64* %18
%103 = add i64 %102, 1
store i64 %103, i64* %18
%104 = load i32, i32* %20
store i32 %104, i32* %19
br label %48
105: ; preds = %56
%106 = load i32, i32* %19
%107 = load i32*, i32** %15
%108 = load i64, i64* %18
%109 = getelementptr inbounds i32, i32* %107, i64 %108
store i32 %106, i32* %109
ret void
}

LLVM IR (-O2):
define void @sse_merge_aligned_32bit(i8* nocapture %0, i8* nocapture %1, i8* %2, i64 %3, i64 %4) {
%6 = alloca i32
%7 = lshr i64 %3, 2
%8 = lshr i64 %4, 2
%9 = bitcast i8* %0 to i32*
%10 = bitcast i8* %1 to i32*
%11 = bitcast i8* %2 to i32*
%12 = bitcast i32* %6 to i8*
%13 = load i32, i32* %9
%14 = load i32, i32* %10
%15 = tail call i64 @_mm_comilt_ss(i32 %13, i32 %14)
%16 = icmp eq i64 %15, 0
%17 = zext i1 %16 to i64
%18 = xor i1 %16, true
%19 = zext i1 %18 to i64
%20 = select i1 %16, i32* %9, i32* %10
%21 = load i32, i32* %20
%22 = icmp ugt i64 %7, %17
%23 = icmp ugt i64 %8, %19
%24 = select i1 %22, i1 true, i1 %23
br i1 %24, label %25, label %60
25: ; preds = %5, %52
%26 = phi i1 [ %58, %52 ], [ %23, %5 ]
%27 = phi i1 [ %57, %52 ], [ %22, %5 ]
%28 = phi i32 [ %56, %52 ], [ %21, %5 ]
%29 = phi i64 [ %55, %52 ], [ 0, %5 ]
%30 = phi i64 [ %54, %52 ], [ %19, %5 ]
%31 = phi i64 [ %53, %52 ], [ %17, %5 ]
br i1 %27, label %32, label %46
32: ; preds = %25
br i1 %26, label %33, label %40
33: ; preds = %32
%34 = getelementptr inbounds i32, i32* %9, i64 %31
%35 = load i32, i32* %34
%36 = getelementptr inbounds i32, i32* %10, i64 %30
%37 = load i32, i32* %36
%38 = call i64 @_mm_comilt_ss(i32 %35, i32 %37)
%39 = icmp eq i64 %38, 0
br i1 %39, label %46, label %40
40: ; preds = %33, %32
%41 = getelementptr inbounds i32, i32* %9, i64 %31
%42 = load i32, i32* %41
%43 = getelementptr inbounds i32, i32* %11, i64 %29
%44 = call i32 @sse_bitonic_merge_4(i32 %28, i32 %42, i32* %43, i32* %6)
%45 = add nuw i64 %31, 1
br label %52
46: ; preds = %33, %25
%47 = getelementptr inbounds i32, i32* %10, i64 %30
%48 = load i32, i32* %47
%49 = getelementptr inbounds i32, i32* %11, i64 %29
%50 = call i32 @sse_bitonic_merge_4(i32 %28, i32 %48, i32* %49, i32* %6)
%51 = add i64 %30, 1
br label %52
52: ; preds = %46, %40
%53 = phi i64 [ %45, %40 ], [ %31, %46 ]
%54 = phi i64 [ %30, %40 ], [ %51, %46 ]
%55 = add i64 %29, 1
%56 = load i32, i32* %6
%57 = icmp ult i64 %53, %7
%58 = icmp ult i64 %54, %8
%59 = select i1 %57, i1 true, i1 %58
br i1 %59, label %25, label %60
60: ; preds = %52, %5
%61 = phi i64 [ 0, %5 ], [ %55, %52 ]
%62 = phi i32 [ %21, %5 ], [ %56, %52 ]
%63 = getelementptr inbounds i32, i32* %11, i64 %61
store i32 %62, i32* %63
ret void
}