#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 void *u_char;

/* Variables and functions */
void swap(void *x, void *y, short l) {
  u_char *a = x, *b = y, c;
  l--;
  do {
    c = *a;
    *a++ = *b;
    *b++ = c;
  } while (--l != -1);
}


x86 assembly (clang, -O0):
<swap>:
push   %rbp
mov    %rsp,%rbp
mov    %dx,%ax
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %ax,-0x12(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x12(%rbp),%ax
add    $0xffff,%ax
mov    %ax,-0x12(%rbp)
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
mov    (%rax),%rcx
mov    -0x20(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x20(%rbp)
mov    %rcx,(%rax)
mov    -0x30(%rbp),%rcx
mov    -0x28(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x28(%rbp)
mov    %rcx,(%rax)
mov    -0x12(%rbp),%ax
add    $0xffff,%ax
mov    %ax,-0x12(%rbp)
cwtl
cmp    $0xffffffff,%eax
jne    112f <swap+0x2f>
pop    %rbp
ret

x86 assembly (clang, -O2):
<swap>:
mov    %edx,%eax
add    $0xffffffff,%eax
cmp    $0x3,%ax
jb     1204 <swap+0x104>
lea    -0x1(%rdx),%ecx
movzwl %cx,%r8d
lea    (%rsi,%r8,8),%rcx
add    $0x8,%rcx
cmp    %rdi,%rcx
jbe    1134 <swap+0x34>
lea    (%rdi,%r8,8),%rcx
add    $0x8,%rcx
cmp    %rsi,%rcx
ja     1204 <swap+0x104>
movzwl %ax,%r8d
add    $0x1,%r8
mov    %r8d,%r9d
and    $0xfffffffc,%r9d
lea    -0x4(%r9),%rax
mov    %rax,%r10
shr    $0x2,%r10
add    $0x1,%r10
test   %rax,%rax
je     12a7 <swap+0x1a7>
mov    %r10,%rax
and    $0xfffffffffffffffe,%rax
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movups (%rdi,%rcx,8),%xmm0
movups 0x10(%rdi,%rcx,8),%xmm1
movups (%rsi,%rcx,8),%xmm2
movups 0x10(%rsi,%rcx,8),%xmm3
movups %xmm2,(%rdi,%rcx,8)
movups %xmm3,0x10(%rdi,%rcx,8)
movups %xmm0,(%rsi,%rcx,8)
movups %xmm1,0x10(%rsi,%rcx,8)
movups 0x20(%rdi,%rcx,8),%xmm0
movups 0x30(%rdi,%rcx,8),%xmm1
movups 0x20(%rsi,%rcx,8),%xmm2
movups 0x30(%rsi,%rcx,8),%xmm3
movups %xmm2,0x20(%rdi,%rcx,8)
movups %xmm3,0x30(%rdi,%rcx,8)
movups %xmm0,0x20(%rsi,%rcx,8)
movups %xmm1,0x30(%rsi,%rcx,8)
add    $0x8,%rcx
add    $0xfffffffffffffffe,%rax
jne    1170 <swap+0x70>
test   $0x1,%r10b
je     11f0 <swap+0xf0>
movups (%rdi,%rcx,8),%xmm0
movups 0x10(%rdi,%rcx,8),%xmm1
movups (%rsi,%rcx,8),%xmm2
movups 0x10(%rsi,%rcx,8),%xmm3
movups %xmm2,(%rdi,%rcx,8)
movups %xmm3,0x10(%rdi,%rcx,8)
movups %xmm0,(%rsi,%rcx,8)
movups %xmm1,0x10(%rsi,%rcx,8)
cmp    %r9,%r8
je     12a6 <swap+0x1a6>
sub    %r9d,%edx
lea    (%rdi,%r9,8),%rdi
lea    (%rsi,%r9,8),%rsi
lea    -0x1(%rdx),%r8d
test   $0x3,%dl
je     1240 <swap+0x140>
movzwl %dx,%r9d
and    $0x3,%r9d
xor    %eax,%eax
nopw   0x0(%rax,%rax,1)
mov    (%rdi),%r10
mov    (%rsi),%rcx
mov    %rcx,(%rdi)
add    $0x8,%rdi
mov    %r10,(%rsi)
add    $0x8,%rsi
add    $0x1,%rax
cmp    %ax,%r9w
jne    1220 <swap+0x120>
sub    %eax,%edx
cmp    $0x3,%r8w
jb     12a6 <swap+0x1a6>
movzwl %dx,%r8d
xor    %ecx,%ecx
nopl   (%rax)
mov    (%rdi,%rcx,8),%rdx
mov    (%rsi,%rcx,8),%rax
mov    %rax,(%rdi,%rcx,8)
mov    %rdx,(%rsi,%rcx,8)
mov    0x8(%rdi,%rcx,8),%rax
mov    0x8(%rsi,%rcx,8),%rdx
mov    %rdx,0x8(%rdi,%rcx,8)
mov    %rax,0x8(%rsi,%rcx,8)
mov    0x10(%rdi,%rcx,8),%rax
mov    0x10(%rsi,%rcx,8),%rdx
mov    %rdx,0x10(%rdi,%rcx,8)
mov    %rax,0x10(%rsi,%rcx,8)
mov    0x18(%rdi,%rcx,8),%rax
mov    0x18(%rsi,%rcx,8),%rdx
mov    %rdx,0x18(%rdi,%rcx,8)
mov    %rax,0x18(%rsi,%rcx,8)
add    $0x4,%rcx
cmp    %cx,%r8w
jne    1250 <swap+0x150>
ret
xor    %ecx,%ecx
test   $0x1,%r10b
jne    11cc <swap+0xcc>
jmp    11f0 <swap+0xf0>

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

LLVM IR (-O2):
define void @swap(i8* nocapture %0, i8* nocapture %1, i16 signext %2) {
%4 = bitcast i8* %0 to i8**
%5 = bitcast i8* %1 to i8**
%6 = add i16 %2, -1
%7 = zext i16 %6 to i64
%8 = add nuw nsw i64 %7, 1
%9 = icmp ult i16 %6, 3
br i1 %9, label %94, label %10
10: ; preds = %3
%11 = add i16 %2, -1
%12 = zext i16 %11 to i64
%13 = shl nuw nsw i64 %12, 3
%14 = add nuw nsw i64 %13, 8
%15 = getelementptr i8, i8* %0, i64 %14
%16 = getelementptr i8, i8* %1, i64 %14
%17 = icmp ugt i8* %16, %0
%18 = icmp ugt i8* %15, %1
%19 = and i1 %17, %18
br i1 %19, label %94, label %20
20: ; preds = %10
%21 = and i64 %8, 131068
%22 = getelementptr i8*, i8** %4, i64 %21
%23 = getelementptr i8*, i8** %5, i64 %21
%24 = trunc i64 %21 to i16
%25 = sub i16 %2, %24
%26 = add nsw i64 %21, -4
%27 = lshr exact i64 %26, 2
%28 = add nuw nsw i64 %27, 1
%29 = and i64 %28, 1
%30 = icmp eq i64 %26, 0
br i1 %30, label %72, label %31
31: ; preds = %20
%32 = and i64 %28, 9223372036854775806
br label %33
33: ; preds = %33, %31
%34 = phi i64 [ 0, %31 ], [ %69, %33 ]
%35 = phi i64 [ 0, %31 ], [ %70, %33 ]
%36 = getelementptr i8*, i8** %4, i64 %34
%37 = getelementptr i8*, i8** %5, i64 %34
%38 = bitcast i8** %36 to <2 x i8*>*
%39 = load <2 x i8*>, <2 x i8*>* %38
%40 = getelementptr i8*, i8** %36, i64 2
%41 = bitcast i8** %40 to <2 x i8*>*
%42 = load <2 x i8*>, <2 x i8*>* %41
%43 = bitcast i8** %37 to <2 x i8*>*
%44 = load <2 x i8*>, <2 x i8*>* %43
%45 = getelementptr i8*, i8** %37, i64 2
%46 = bitcast i8** %45 to <2 x i8*>*
%47 = load <2 x i8*>, <2 x i8*>* %46
%48 = bitcast i8** %36 to <2 x i8*>*
store <2 x i8*> %44, <2 x i8*>* %48
%49 = bitcast i8** %40 to <2 x i8*>*
store <2 x i8*> %47, <2 x i8*>* %49
%50 = bitcast i8** %37 to <2 x i8*>*
store <2 x i8*> %39, <2 x i8*>* %50
%51 = bitcast i8** %45 to <2 x i8*>*
store <2 x i8*> %42, <2 x i8*>* %51
%52 = or i64 %34, 4
%53 = getelementptr i8*, i8** %4, i64 %52
%54 = getelementptr i8*, i8** %5, i64 %52
%55 = bitcast i8** %53 to <2 x i8*>*
%56 = load <2 x i8*>, <2 x i8*>* %55
%57 = getelementptr i8*, i8** %53, i64 2
%58 = bitcast i8** %57 to <2 x i8*>*
%59 = load <2 x i8*>, <2 x i8*>* %58
%60 = bitcast i8** %54 to <2 x i8*>*
%61 = load <2 x i8*>, <2 x i8*>* %60
%62 = getelementptr i8*, i8** %54, i64 2
%63 = bitcast i8** %62 to <2 x i8*>*
%64 = load <2 x i8*>, <2 x i8*>* %63
%65 = bitcast i8** %53 to <2 x i8*>*
store <2 x i8*> %61, <2 x i8*>* %65
%66 = bitcast i8** %57 to <2 x i8*>*
store <2 x i8*> %64, <2 x i8*>* %66
%67 = bitcast i8** %54 to <2 x i8*>*
store <2 x i8*> %56, <2 x i8*>* %67
%68 = bitcast i8** %62 to <2 x i8*>*
store <2 x i8*> %59, <2 x i8*>* %68
%69 = add nuw i64 %34, 8
%70 = add i64 %35, 2
%71 = icmp eq i64 %70, %32
br i1 %71, label %72, label %33
72: ; preds = %33, %20
%73 = phi i64 [ 0, %20 ], [ %69, %33 ]
%74 = icmp eq i64 %29, 0
br i1 %74, label %92, label %75
75: ; preds = %72
%76 = getelementptr i8*, i8** %4, i64 %73
%77 = getelementptr i8*, i8** %5, i64 %73
%78 = bitcast i8** %76 to <2 x i8*>*
%79 = load <2 x i8*>, <2 x i8*>* %78
%80 = getelementptr i8*, i8** %76, i64 2
%81 = bitcast i8** %80 to <2 x i8*>*
%82 = load <2 x i8*>, <2 x i8*>* %81
%83 = bitcast i8** %77 to <2 x i8*>*
%84 = load <2 x i8*>, <2 x i8*>* %83
%85 = getelementptr i8*, i8** %77, i64 2
%86 = bitcast i8** %85 to <2 x i8*>*
%87 = load <2 x i8*>, <2 x i8*>* %86
%88 = bitcast i8** %76 to <2 x i8*>*
store <2 x i8*> %84, <2 x i8*>* %88
%89 = bitcast i8** %80 to <2 x i8*>*
store <2 x i8*> %87, <2 x i8*>* %89
%90 = bitcast i8** %77 to <2 x i8*>*
store <2 x i8*> %79, <2 x i8*>* %90
%91 = bitcast i8** %85 to <2 x i8*>*
store <2 x i8*> %82, <2 x i8*>* %91
br label %92
92: ; preds = %72, %75
%93 = icmp eq i64 %8, %21
br i1 %93, label %140, label %94
94: ; preds = %10, %3, %92
%95 = phi i8** [ %4, %10 ], [ %4, %3 ], [ %22, %92 ]
%96 = phi i8** [ %5, %10 ], [ %5, %3 ], [ %23, %92 ]
%97 = phi i16 [ %2, %10 ], [ %2, %3 ], [ %25, %92 ]
%98 = add i16 %97, -1
%99 = and i16 %97, 3
%100 = icmp eq i16 %99, 0
br i1 %100, label %113, label %101
101: ; preds = %94, %101
%102 = phi i8** [ %109, %101 ], [ %95, %94 ]
%103 = phi i8** [ %110, %101 ], [ %96, %94 ]
%104 = phi i16 [ %106, %101 ], [ %97, %94 ]
%105 = phi i16 [ %111, %101 ], [ 0, %94 ]
%106 = add i16 %104, -1
%107 = load i8*, i8** %102
%108 = load i8*, i8** %103
%109 = getelementptr inbounds i8*, i8** %102, i64 1
store i8* %108, i8** %102
%110 = getelementptr inbounds i8*, i8** %103, i64 1
store i8* %107, i8** %103
%111 = add i16 %105, 1
%112 = icmp eq i16 %111, %99
br i1 %112, label %113, label %101
113: ; preds = %101, %94
%114 = phi i8** [ %95, %94 ], [ %109, %101 ]
%115 = phi i8** [ %96, %94 ], [ %110, %101 ]
%116 = phi i16 [ %97, %94 ], [ %106, %101 ]
%117 = icmp ult i16 %98, 3
br i1 %117, label %140, label %118
118: ; preds = %113, %118
%119 = phi i8** [ %137, %118 ], [ %114, %113 ]
%120 = phi i8** [ %138, %118 ], [ %115, %113 ]
%121 = phi i16 [ %134, %118 ], [ %116, %113 ]
%122 = load i8*, i8** %119
%123 = load i8*, i8** %120
%124 = getelementptr inbounds i8*, i8** %119, i64 1
store i8* %123, i8** %119
%125 = getelementptr inbounds i8*, i8** %120, i64 1
store i8* %122, i8** %120
%126 = load i8*, i8** %124
%127 = load i8*, i8** %125
%128 = getelementptr inbounds i8*, i8** %119, i64 2
store i8* %127, i8** %124
%129 = getelementptr inbounds i8*, i8** %120, i64 2
store i8* %126, i8** %125
%130 = load i8*, i8** %128
%131 = load i8*, i8** %129
%132 = getelementptr inbounds i8*, i8** %119, i64 3
store i8* %131, i8** %128
%133 = getelementptr inbounds i8*, i8** %120, i64 3
store i8* %130, i8** %129
%134 = add i16 %121, -4
%135 = load i8*, i8** %132
%136 = load i8*, i8** %133
%137 = getelementptr inbounds i8*, i8** %119, i64 4
store i8* %136, i8** %132
%138 = getelementptr inbounds i8*, i8** %120, i64 4
store i8* %135, i8** %133
%139 = icmp eq i16 %134, 0
br i1 %139, label %140, label %118
140: ; preds = %113, %118, %92
ret void
}