#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 */
struct swp {
  int /*<<< orphan*/ int16_tw;
  char *charv;
};
typedef int /*<<< orphan*/ int16_t;

/* Variables and functions */
void swap(void *p, int ct) {
  register char c;
  union swp {
    int16_t int16_tw;
    char charv[2];
  } *buf = p;
  ct = (ct + 1) >> 1;
  while (ct--) {
    c = buf->charv[0];
    buf->charv[0] = buf->charv[1];
    buf->charv[1] = c;
    ++buf;
  }
}


x86 assembly (clang, -O0):
<swap>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
sar    $0x1,%eax
mov    %eax,-0xc(%rbp)
mov    -0xc(%rbp),%eax
mov    %eax,%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0xc(%rbp)
cmp    $0x0,%eax
je     1164 <swap+0x64>
mov    -0x18(%rbp),%rax
mov    (%rax),%al
mov    %al,-0xd(%rbp)
mov    -0x18(%rbp),%rax
mov    0x1(%rax),%cl
mov    -0x18(%rbp),%rax
mov    %cl,(%rax)
mov    -0xd(%rbp),%cl
mov    -0x18(%rbp),%rax
mov    %cl,0x1(%rax)
mov    -0x18(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x18(%rbp)
jmp    111f <swap+0x1f>
pop    %rbp
ret

x86 assembly (clang, -O2):
<swap>:
add    $0x1,%esi
cmp    $0x2,%esi
jb     115f <swap+0x5f>
sar    %esi
lea    -0x1(%rsi),%eax
test   $0x3,%sil
je     1132 <swap+0x32>
mov    %esi,%edx
and    $0x3,%edx
xor    %ecx,%ecx
nopw   0x0(%rax,%rax,1)
rolw   $0x8,(%rdi)
add    $0x4,%rdi
add    $0x1,%rcx
cmp    %ecx,%edx
jne    1120 <swap+0x20>
sub    %ecx,%esi
cmp    $0x3,%eax
jb     115f <swap+0x5f>
mov    %esi,%eax
xor    %ecx,%ecx
nopl   0x0(%rax,%rax,1)
rolw   $0x8,(%rdi,%rcx,4)
rolw   $0x8,0x4(%rdi,%rcx,4)
rolw   $0x8,0x8(%rdi,%rcx,4)
rolw   $0x8,0xc(%rdi,%rcx,4)
add    $0x4,%rcx
cmp    %ecx,%eax
jne    1140 <swap+0x40>
ret

LLVM IR (-O0):
%union.swp = type { i32 }
define void @swap(i8* %0, i32 %1) {
%3 = alloca i8*
%4 = alloca i32
%5 = alloca i8
%6 = alloca %union.swp*
store i8* %0, i8** %3
store i32 %1, i32* %4
%7 = load i8*, i8** %3
%8 = bitcast i8* %7 to %union.swp*
store %union.swp* %8, %union.swp** %6
%9 = load i32, i32* %4
%10 = add nsw i32 %9, 1
%11 = ashr i32 %10, 1
store i32 %11, i32* %4
br label %12
12: ; preds = %16, %2
%13 = load i32, i32* %4
%14 = add nsw i32 %13, -1
store i32 %14, i32* %4
%15 = icmp ne i32 %13, 0
br i1 %15, label %16, label %34
16: ; preds = %12
%17 = load %union.swp*, %union.swp** %6
%18 = bitcast %union.swp* %17 to [2 x i8]*
%19 = getelementptr inbounds [2 x i8], [2 x i8]* %18, i64 0, i64 0
%20 = load i8, i8* %19
store i8 %20, i8* %5
%21 = load %union.swp*, %union.swp** %6
%22 = bitcast %union.swp* %21 to [2 x i8]*
%23 = getelementptr inbounds [2 x i8], [2 x i8]* %22, i64 0, i64 1
%24 = load i8, i8* %23
%25 = load %union.swp*, %union.swp** %6
%26 = bitcast %union.swp* %25 to [2 x i8]*
%27 = getelementptr inbounds [2 x i8], [2 x i8]* %26, i64 0, i64 0
store i8 %24, i8* %27
%28 = load i8, i8* %5
%29 = load %union.swp*, %union.swp** %6
%30 = bitcast %union.swp* %29 to [2 x i8]*
%31 = getelementptr inbounds [2 x i8], [2 x i8]* %30, i64 0, i64 1
store i8 %28, i8* %31
%32 = load %union.swp*, %union.swp** %6
%33 = getelementptr inbounds %union.swp, %union.swp* %32, i32 1
store %union.swp* %33, %union.swp** %6
br label %12
34: ; preds = %12
ret void
}

LLVM IR (-O2):
%union.swp = type { i32 }
define void @swap(i8* nocapture %0, i32 %1) {
%3 = add nsw i32 %1, 1
%4 = icmp ult i32 %3, 2
br i1 %4, label %57, label %5
5: ; preds = %2
%6 = ashr i32 %3, 1
%7 = bitcast i8* %0 to %union.swp*
%8 = add nsw i32 %6, -1
%9 = and i32 %6, 3
%10 = icmp eq i32 %9, 0
br i1 %10, label %24, label %11
11: ; preds = %5, %11
%12 = phi %union.swp* [ %21, %11 ], [ %7, %5 ]
%13 = phi i32 [ %15, %11 ], [ %6, %5 ]
%14 = phi i32 [ %22, %11 ], [ 0, %5 ]
%15 = add nsw i32 %13, -1
%16 = bitcast %union.swp* %12 to [2 x i8]*
%17 = bitcast %union.swp* %12 to i8*
%18 = load i8, i8* %17
%19 = getelementptr inbounds [2 x i8], [2 x i8]* %16, i64 0, i64 1
%20 = load i8, i8* %19
store i8 %20, i8* %17
store i8 %18, i8* %19
%21 = getelementptr inbounds %union.swp, %union.swp* %12, i64 1
%22 = add i32 %14, 1
%23 = icmp eq i32 %22, %9
br i1 %23, label %24, label %11
24: ; preds = %11, %5
%25 = phi %union.swp* [ %7, %5 ], [ %21, %11 ]
%26 = phi i32 [ %6, %5 ], [ %15, %11 ]
%27 = icmp ult i32 %8, 3
br i1 %27, label %57, label %28
28: ; preds = %24, %28
%29 = phi %union.swp* [ %55, %28 ], [ %25, %24 ]
%30 = phi i32 [ %49, %28 ], [ %26, %24 ]
%31 = bitcast %union.swp* %29 to [2 x i8]*
%32 = bitcast %union.swp* %29 to i8*
%33 = load i8, i8* %32
%34 = getelementptr inbounds [2 x i8], [2 x i8]* %31, i64 0, i64 1
%35 = load i8, i8* %34
store i8 %35, i8* %32
store i8 %33, i8* %34
%36 = getelementptr inbounds %union.swp, %union.swp* %29, i64 1
%37 = bitcast %union.swp* %36 to [2 x i8]*
%38 = bitcast %union.swp* %36 to i8*
%39 = load i8, i8* %38
%40 = getelementptr inbounds [2 x i8], [2 x i8]* %37, i64 0, i64 1
%41 = load i8, i8* %40
store i8 %41, i8* %38
store i8 %39, i8* %40
%42 = getelementptr inbounds %union.swp, %union.swp* %29, i64 2
%43 = bitcast %union.swp* %42 to [2 x i8]*
%44 = bitcast %union.swp* %42 to i8*
%45 = load i8, i8* %44
%46 = getelementptr inbounds [2 x i8], [2 x i8]* %43, i64 0, i64 1
%47 = load i8, i8* %46
store i8 %47, i8* %44
store i8 %45, i8* %46
%48 = getelementptr inbounds %union.swp, %union.swp* %29, i64 3
%49 = add nsw i32 %30, -4
%50 = bitcast %union.swp* %48 to [2 x i8]*
%51 = bitcast %union.swp* %48 to i8*
%52 = load i8, i8* %51
%53 = getelementptr inbounds [2 x i8], [2 x i8]* %50, i64 0, i64 1
%54 = load i8, i8* %53
store i8 %54, i8* %51
store i8 %52, i8* %53
%55 = getelementptr inbounds %union.swp, %union.swp* %29, i64 4
%56 = icmp eq i32 %49, 0
br i1 %56, label %57, label %28
57: ; preds = %24, %28, %2
ret void
}