#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 */
size_t INT_MAX;
int /*<<< orphan*/ free(unsigned char *);
unsigned char *reallocarray(int /*<<< orphan*/ *, size_t, int);
size_t strlen(char const *);
unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni,
                               int *unilen) {
  size_t ulen, i;
  unsigned char *unitmp;
  if (asclen < 0)
    ulen = strlen(asc);
  else
    ulen = (size_t)asclen;
  ulen++;
  if (ulen == 0)
    return NULL;
  if ((unitmp = reallocarray(NULL, ulen, 2)) == NULL)
    return NULL;
  ulen *= 2;
  if (ulen > INT_MAX) {
    free(unitmp);
    return NULL;
  }
  for (i = 0; i < ulen - 2; i += 2) {
    unitmp[i] = 0;
    unitmp[i + 1] = *asc++;
  }
  unitmp[ulen - 2] = 0;
  unitmp[ulen - 1] = 0;
  if (unilen)
    *unilen = ulen;
  if (uni)
    *uni = unitmp;
  return unitmp;
}


x86 assembly (clang, -O0):
<OPENSSL_asc2uni>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
cmpl   $0x0,-0x14(%rbp)
jge    1163 <OPENSSL_asc2uni+0x33>
mov    -0x10(%rbp),%rdi
call   1050 <strlen@plt>
mov    %rax,-0x30(%rbp)
jmp    116b <OPENSSL_asc2uni+0x3b>
movslq -0x14(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
cmpq   $0x0,-0x30(%rbp)
jne    118f <OPENSSL_asc2uni+0x5f>
movq   $0x0,-0x8(%rbp)
jmp    129e <OPENSSL_asc2uni+0x16e>
mov    -0x30(%rbp),%rsi
xor    %eax,%eax
mov    %eax,%edi
mov    $0x2,%edx
call   1040 <reallocarray@plt>
mov    %rax,-0x40(%rbp)
cmp    $0x0,%rax
jne    11bc <OPENSSL_asc2uni+0x8c>
movq   $0x0,-0x8(%rbp)
jmp    129e <OPENSSL_asc2uni+0x16e>
mov    -0x30(%rbp),%rax
shl    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
mov    0x2e15(%rip),%rcx
cmp    (%rcx),%rax
jbe    11f2 <OPENSSL_asc2uni+0xc2>
mov    -0x40(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x8(%rbp)
jmp    129e <OPENSSL_asc2uni+0x16e>
movq   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%rax
mov    -0x30(%rbp),%rcx
sub    $0x2,%rcx
cmp    %rcx,%rax
jae    1249 <OPENSSL_asc2uni+0x119>
mov    -0x40(%rbp),%rax
mov    -0x38(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
mov    (%rax),%dl
mov    -0x40(%rbp),%rax
mov    -0x38(%rbp),%rcx
mov    %dl,0x1(%rax,%rcx,1)
mov    -0x38(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x38(%rbp)
jmp    11fa <OPENSSL_asc2uni+0xca>
mov    -0x40(%rbp),%rax
mov    -0x30(%rbp),%rcx
sub    $0x2,%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x40(%rbp),%rax
mov    -0x30(%rbp),%rcx
sub    $0x1,%rcx
movb   $0x0,(%rax,%rcx,1)
cmpq   $0x0,-0x28(%rbp)
je     1280 <OPENSSL_asc2uni+0x150>
mov    -0x30(%rbp),%rax
mov    %eax,%ecx
mov    -0x28(%rbp),%rax
mov    %ecx,(%rax)
cmpq   $0x0,-0x20(%rbp)
je     1296 <OPENSSL_asc2uni+0x166>
mov    -0x40(%rbp),%rcx
mov    -0x20(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x40(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<OPENSSL_asc2uni>:
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %rcx,%r15
mov    %rdx,%r14
mov    %rdi,%rbx
test   %esi,%esi
js     114b <OPENSSL_asc2uni+0x1b>
mov    %esi,%r12d
jmp    1156 <OPENSSL_asc2uni+0x26>
mov    %rbx,%rdi
call   1050 <strlen@plt>
mov    %rax,%r12
xor    %r13d,%r13d
inc    %r12
je     12e3 <OPENSSL_asc2uni+0x1b3>
xor    %edi,%edi
mov    %r12,%rsi
mov    $0x2,%edx
call   1040 <reallocarray@plt>
test   %rax,%rax
je     12e3 <OPENSSL_asc2uni+0x1b3>
add    %r12,%r12
mov    0x2e64(%rip),%rcx
cmp    (%rcx),%r12
jbe    1199 <OPENSSL_asc2uni+0x69>
mov    %rax,%rdi
call   1030 <free@plt>
xor    %r13d,%r13d
jmp    12e3 <OPENSSL_asc2uni+0x1b3>
mov    %r12,%r10
add    $0xfffffffffffffffe,%r10
je     12c8 <OPENSSL_asc2uni+0x198>
lea    -0x3(%r12),%r9
cmp    $0x1e,%r9
jae    11b8 <OPENSSL_asc2uni+0x88>
xor    %edx,%edx
jmp    12b0 <OPENSSL_asc2uni+0x180>
shr    %r9
lea    (%r9,%rbx,1),%rdx
add    $0x1,%rdx
cmp    %rdx,%rax
jae    11e3 <OPENSSL_asc2uni+0xb3>
lea    -0x1(%r12),%rdx
and    $0xfffffffffffffffe,%rdx
mov    %rax,%rsi
add    %rdx,%rsi
cmp    %rbx,%rsi
jbe    11e3 <OPENSSL_asc2uni+0xb3>
xor    %edx,%edx
jmp    12b0 <OPENSSL_asc2uni+0x180>
add    $0x1,%r9
mov    %r9,%rdx
and    $0xfffffffffffffff0,%rdx
lea    -0x10(%rdx),%rsi
mov    %rsi,%r8
shr    $0x4,%r8
add    $0x1,%r8
test   %rsi,%rsi
je     126a <OPENSSL_asc2uni+0x13a>
mov    %r8,%rsi
and    $0xfffffffffffffffe,%rsi
xor    %edi,%edi
nopl   0x0(%rax,%rax,1)
movq   (%rbx,%rdi,1),%xmm0
movq   0x8(%rbx,%rdi,1),%xmm1
pxor   %xmm2,%xmm2
punpcklbw %xmm0,%xmm2
movdqu %xmm2,(%rax,%rdi,2)
pxor   %xmm0,%xmm0
punpcklbw %xmm1,%xmm0
movdqu %xmm0,0x10(%rax,%rdi,2)
movq   0x10(%rbx,%rdi,1),%xmm0
movq   0x18(%rbx,%rdi,1),%xmm1
pxor   %xmm2,%xmm2
punpcklbw %xmm0,%xmm2
movdqu %xmm2,0x20(%rax,%rdi,2)
pxor   %xmm0,%xmm0
punpcklbw %xmm1,%xmm0
movdqu %xmm0,0x30(%rax,%rdi,2)
add    $0x20,%rdi
add    $0xfffffffffffffffe,%rsi
jne    1210 <OPENSSL_asc2uni+0xe0>
jmp    126c <OPENSSL_asc2uni+0x13c>
xor    %edi,%edi
test   $0x1,%r8b
je     12a0 <OPENSSL_asc2uni+0x170>
lea    (%rdi,%rdi,1),%rsi
movq   (%rbx,%rdi,1),%xmm0
movq   0x8(%rbx,%rdi,1),%xmm1
or     $0x11,%rsi
pxor   %xmm2,%xmm2
pxor   %xmm3,%xmm3
punpcklbw %xmm0,%xmm3
movdqu %xmm3,(%rax,%rdi,2)
punpcklbw %xmm1,%xmm2
movdqu %xmm2,-0x1(%rax,%rsi,1)
cmp    %rdx,%r9
je     12c8 <OPENSSL_asc2uni+0x198>
add    %rdx,%rbx
add    %rdx,%rdx
nopl   0x0(%rax,%rax,1)
movb   $0x0,(%rax,%rdx,1)
movzbl (%rbx),%ecx
add    $0x1,%rbx
mov    %cl,0x1(%rax,%rdx,1)
add    $0x2,%rdx
cmp    %r10,%rdx
jb     12b0 <OPENSSL_asc2uni+0x180>
movw   $0x0,-0x2(%rax,%r12,1)
test   %r15,%r15
je     12d8 <OPENSSL_asc2uni+0x1a8>
mov    %r12d,(%r15)
test   %r14,%r14
je     12e0 <OPENSSL_asc2uni+0x1b0>
mov    %rax,(%r14)
mov    %rax,%r13
mov    %r13,%rax
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@INT_MAX = global i64 0
define i8* @OPENSSL_asc2uni(i8* %0, i32 %1, i8** %2, i32* %3) {
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i8**
%9 = alloca i32*
%10 = alloca i64
%11 = alloca i64
%12 = alloca i8*
store i8* %0, i8** %6
store i32 %1, i32* %7
store i8** %2, i8*** %8
store i32* %3, i32** %9
%13 = load i32, i32* %7
%14 = icmp slt i32 %13, 0
br i1 %14, label %15, label %18
15: ; preds = %4
%16 = load i8*, i8** %6
%17 = call i64 @strlen(i8* %16)
store i64 %17, i64* %10
br label %21
18: ; preds = %4
%19 = load i32, i32* %7
%20 = sext i32 %19 to i64
store i64 %20, i64* %10
br label %21
21: ; preds = %18, %15
%22 = load i64, i64* %10
%23 = add i64 %22, 1
store i64 %23, i64* %10
%24 = load i64, i64* %10
%25 = icmp eq i64 %24, 0
br i1 %25, label %26, label %27
26: ; preds = %21
store i8* null, i8** %5
br label %84
27: ; preds = %21
%28 = load i64, i64* %10
%29 = call i8* @reallocarray(i32* null, i64 %28, i32 2)
store i8* %29, i8** %12
%30 = icmp eq i8* %29, null
br i1 %30, label %31, label %32
31: ; preds = %27
store i8* null, i8** %5
br label %84
32: ; preds = %27
%33 = load i64, i64* %10
%34 = mul i64 %33, 2
store i64 %34, i64* %10
%35 = load i64, i64* %10
%36 = load i64, i64* @INT_MAX
%37 = icmp ugt i64 %35, %36
br i1 %37, label %38, label %41
38: ; preds = %32
%39 = load i8*, i8** %12
%40 = call i32 @free(i8* %39)
store i8* null, i8** %5
br label %84
41: ; preds = %32
store i64 0, i64* %11
br label %42
42: ; preds = %58, %41
%43 = load i64, i64* %11
%44 = load i64, i64* %10
%45 = sub i64 %44, 2
%46 = icmp ult i64 %43, %45
br i1 %46, label %47, label %61
47: ; preds = %42
%48 = load i8*, i8** %12
%49 = load i64, i64* %11
%50 = getelementptr inbounds i8, i8* %48, i64 %49
store i8 0, i8* %50
%51 = load i8*, i8** %6
%52 = getelementptr inbounds i8, i8* %51, i32 1
store i8* %52, i8** %6
%53 = load i8, i8* %51
%54 = load i8*, i8** %12
%55 = load i64, i64* %11
%56 = add i64 %55, 1
%57 = getelementptr inbounds i8, i8* %54, i64 %56
store i8 %53, i8* %57
br label %58
58: ; preds = %47
%59 = load i64, i64* %11
%60 = add i64 %59, 2
store i64 %60, i64* %11
br label %42
61: ; preds = %42
%62 = load i8*, i8** %12
%63 = load i64, i64* %10
%64 = sub i64 %63, 2
%65 = getelementptr inbounds i8, i8* %62, i64 %64
store i8 0, i8* %65
%66 = load i8*, i8** %12
%67 = load i64, i64* %10
%68 = sub i64 %67, 1
%69 = getelementptr inbounds i8, i8* %66, i64 %68
store i8 0, i8* %69
%70 = load i32*, i32** %9
%71 = icmp ne i32* %70, null
br i1 %71, label %72, label %76
72: ; preds = %61
%73 = load i64, i64* %10
%74 = trunc i64 %73 to i32
%75 = load i32*, i32** %9
store i32 %74, i32* %75
br label %76
76: ; preds = %72, %61
%77 = load i8**, i8*** %8
%78 = icmp ne i8** %77, null
br i1 %78, label %79, label %82
79: ; preds = %76
%80 = load i8*, i8** %12
%81 = load i8**, i8*** %8
store i8* %80, i8** %81
br label %82
82: ; preds = %79, %76
%83 = load i8*, i8** %12
store i8* %83, i8** %5
br label %84
84: ; preds = %82, %38, %31, %26
%85 = load i8*, i8** %5
ret i8* %85
}

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