#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 */

/* Variables and functions */
unsigned char UCHAR_MAX;
void ucminmax(unsigned char *in, size_t size, unsigned char *min,
              unsigned char *max) {
  unsigned char tmin = UCHAR_MAX, tmax = 0, *fpt;
  {
    fpt = in + size;
    do {
      if (*in > tmax)
        tmax = *in;
      if (*in < tmin)
        tmin = *in;
    } while (++in < fpt);
    *max = tmax;
    *min = tmin;
  }
}


x86 assembly (clang, -O0):
<ucminmax>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    0x2ed5(%rip),%rax
mov    (%rax),%al
mov    %al,-0x21(%rbp)
movb   $0x0,-0x22(%rbp)
mov    -0x8(%rbp),%rax
add    -0x10(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x8(%rbp),%rax
movzbl (%rax),%eax
movzbl -0x22(%rbp),%ecx
cmp    %ecx,%eax
jle    114c <ucminmax+0x4c>
mov    -0x8(%rbp),%rax
mov    (%rax),%al
mov    %al,-0x22(%rbp)
mov    -0x8(%rbp),%rax
movzbl (%rax),%eax
movzbl -0x21(%rbp),%ecx
cmp    %ecx,%eax
jge    1168 <ucminmax+0x68>
mov    -0x8(%rbp),%rax
mov    (%rax),%al
mov    %al,-0x21(%rbp)
jmp    116d <ucminmax+0x6d>
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
cmp    -0x30(%rbp),%rax
jb     1130 <ucminmax+0x30>
mov    -0x22(%rbp),%cl
mov    -0x20(%rbp),%rax
mov    %cl,(%rax)
mov    -0x21(%rbp),%cl
mov    -0x18(%rbp),%rax
mov    %cl,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<ucminmax>:
push   %rbx
add    %rdi,%rsi
lea    0x1(%rdi),%r8
cmp    %r8,%rsi
mov    %r8,%r9
cmova  %rsi,%r9
mov    0x2ed7(%rip),%rax
mov    (%rax),%al
sub    %rdi,%r9
cmp    $0x8,%r9
jae    112f <ucminmax+0x2f>
xor    %r11d,%r11d
mov    %rdi,%r9
jmp    1320 <ucminmax+0x220>
cmp    $0x20,%r9
jae    1140 <ucminmax+0x40>
xor    %r11d,%r11d
xor    %r10d,%r10d
jmp    126e <ucminmax+0x16e>
mov    %r9,%r10
and    $0xffffffffffffffe0,%r10
movzbl %al,%eax
movd   %eax,%xmm0
punpcklbw %xmm0,%xmm0
pshuflw $0x0,%xmm0,%xmm0
pshufd $0x0,%xmm0,%xmm0
lea    -0x20(%r10),%rax
mov    %rax,%r11
shr    $0x5,%r11
add    $0x1,%r11
test   %rax,%rax
je     1348 <ucminmax+0x248>
mov    %r11,%rbx
and    $0xfffffffffffffffe,%rbx
pxor   %xmm1,%xmm1
xor    %eax,%eax
movdqa %xmm0,%xmm2
pxor   %xmm3,%xmm3
nopl   0x0(%rax)
movdqu (%rdi,%rax,1),%xmm4
movdqu 0x10(%rdi,%rax,1),%xmm5
movdqu 0x20(%rdi,%rax,1),%xmm6
movdqu 0x30(%rdi,%rax,1),%xmm7
pmaxub %xmm4,%xmm1
pmaxub %xmm5,%xmm3
pminub %xmm4,%xmm0
pminub %xmm5,%xmm2
pmaxub %xmm6,%xmm1
pmaxub %xmm7,%xmm3
pminub %xmm6,%xmm0
pminub %xmm7,%xmm2
add    $0x40,%rax
add    $0xfffffffffffffffe,%rbx
jne    1190 <ucminmax+0x90>
test   $0x1,%r11b
je     11f2 <ucminmax+0xf2>
movdqu (%rdi,%rax,1),%xmm4
movdqu 0x10(%rdi,%rax,1),%xmm5
pmaxub %xmm4,%xmm1
pmaxub %xmm5,%xmm3
pminub %xmm4,%xmm0
pminub %xmm5,%xmm2
pminub %xmm2,%xmm0
pmaxub %xmm3,%xmm1
pshufd $0xee,%xmm1,%xmm2
pmaxub %xmm1,%xmm2
pshufd $0x55,%xmm2,%xmm1
pmaxub %xmm2,%xmm1
movdqa %xmm1,%xmm2
psrld  $0x10,%xmm2
pmaxub %xmm1,%xmm2
movdqa %xmm2,%xmm1
psrlw  $0x8,%xmm1
pmaxub %xmm2,%xmm1
movd   %xmm1,%r11d
pshufd $0xee,%xmm0,%xmm1
pminub %xmm0,%xmm1
pshufd $0x55,%xmm1,%xmm0
pminub %xmm1,%xmm0
movdqa %xmm0,%xmm1
psrld  $0x10,%xmm1
pminub %xmm0,%xmm1
movdqa %xmm1,%xmm0
psrlw  $0x8,%xmm0
pminub %xmm1,%xmm0
movd   %xmm0,%eax
cmp    %r10,%r9
je     1341 <ucminmax+0x241>
test   $0x18,%r9b
je     1365 <ucminmax+0x265>
cmp    %r8,%rsi
cmova  %rsi,%r8
sub    %rdi,%r8
mov    %r8,%rbx
and    $0xfffffffffffffff8,%rbx
lea    (%rdi,%rbx,1),%r9
movzbl %al,%eax
movd   %eax,%xmm0
punpcklbw %xmm0,%xmm0
pshuflw $0x0,%xmm0,%xmm0
movzbl %r11b,%eax
movd   %eax,%xmm1
punpcklbw %xmm1,%xmm1
pshuflw $0x0,%xmm1,%xmm1
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movq   (%rdi,%r10,1),%xmm2
pmaxub %xmm2,%xmm1
pminub %xmm2,%xmm0
add    $0x8,%r10
cmp    %r10,%rbx
jne    12b0 <ucminmax+0x1b0>
pshufd $0x55,%xmm1,%xmm2
pmaxub %xmm1,%xmm2
movdqa %xmm2,%xmm1
psrld  $0x10,%xmm1
pmaxub %xmm2,%xmm1
movdqa %xmm1,%xmm2
psrlw  $0x8,%xmm2
pmaxub %xmm1,%xmm2
movd   %xmm2,%r11d
pshufd $0x55,%xmm0,%xmm1
pminub %xmm0,%xmm1
movdqa %xmm1,%xmm0
psrld  $0x10,%xmm0
pminub %xmm1,%xmm0
movdqa %xmm0,%xmm1
psrlw  $0x8,%xmm1
pminub %xmm0,%xmm1
movd   %xmm1,%eax
cmp    %rbx,%r8
je     1341 <ucminmax+0x241>
nopl   0x0(%rax,%rax,1)
movzbl (%r9),%edi
cmp    %r11b,%dil
movzbl %r11b,%r11d
cmova  %edi,%r11d
cmp    %al,%dil
movzbl %al,%eax
cmovb  %edi,%eax
add    $0x1,%r9
cmp    %rsi,%r9
jb     1320 <ucminmax+0x220>
mov    %r11b,(%rcx)
mov    %al,(%rdx)
pop    %rbx
ret
pxor   %xmm1,%xmm1
xor    %eax,%eax
movdqa %xmm0,%xmm2
pxor   %xmm3,%xmm3
test   $0x1,%r11b
jne    11d7 <ucminmax+0xd7>
jmp    11f2 <ucminmax+0xf2>
add    %r10,%rdi
jmp    1127 <ucminmax+0x27>

LLVM IR (-O0):
@UCHAR_MAX = global i8 0
define void @ucminmax(i8* %0, i64 %1, i8* %2, i8* %3) {
%5 = alloca i8*
%6 = alloca i64
%7 = alloca i8*
%8 = alloca i8*
%9 = alloca i8
%10 = alloca i8
%11 = alloca i8*
store i8* %0, i8** %5
store i64 %1, i64* %6
store i8* %2, i8** %7
store i8* %3, i8** %8
%12 = load i8, i8* @UCHAR_MAX
store i8 %12, i8* %9
store i8 0, i8* %10
%13 = load i8*, i8** %5
%14 = load i64, i64* %6
%15 = getelementptr inbounds i8, i8* %13, i64 %14
store i8* %15, i8** %11
br label %16
16: ; preds = %37, %4
%17 = load i8*, i8** %5
%18 = load i8, i8* %17
%19 = zext i8 %18 to i32
%20 = load i8, i8* %10
%21 = zext i8 %20 to i32
%22 = icmp sgt i32 %19, %21
br i1 %22, label %23, label %26
23: ; preds = %16
%24 = load i8*, i8** %5
%25 = load i8, i8* %24
store i8 %25, i8* %10
br label %26
26: ; preds = %23, %16
%27 = load i8*, i8** %5
%28 = load i8, i8* %27
%29 = zext i8 %28 to i32
%30 = load i8, i8* %9
%31 = zext i8 %30 to i32
%32 = icmp slt i32 %29, %31
br i1 %32, label %33, label %36
33: ; preds = %26
%34 = load i8*, i8** %5
%35 = load i8, i8* %34
store i8 %35, i8* %9
br label %36
36: ; preds = %33, %26
br label %37
37: ; preds = %36
%38 = load i8*, i8** %5
%39 = getelementptr inbounds i8, i8* %38, i32 1
store i8* %39, i8** %5
%40 = load i8*, i8** %11
%41 = icmp ult i8* %39, %40
br i1 %41, label %16, label %42
42: ; preds = %37
%43 = load i8, i8* %10
%44 = load i8*, i8** %8
store i8 %43, i8* %44
%45 = load i8, i8* %9
%46 = load i8*, i8** %7
store i8 %45, i8* %46
ret void
}

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