#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 */
scalar_t__ st_asn1_tlv_find_tag(unsigned short, unsigned char *, unsigned short,
                                unsigned char **, unsigned short *);
unsigned short st_asn1_tlv_parse(unsigned char **, unsigned short *,
                                 unsigned char **, unsigned short *);
int _find_tag(unsigned short tag, unsigned char **data,
              unsigned short *data_length, unsigned char **value,
              unsigned short *value_length) {
  unsigned short t;
  while ((t = st_asn1_tlv_parse(data, data_length, value, value_length)) != 0) {
    if (t == tag)
      return 1;
    else if (((t < 0x0100) && (t & 0x20)) || ((t > 0x00ff) && (t & 0x2000)))
      if (st_asn1_tlv_find_tag(tag, *value, *value_length, value, value_length))
        return 1;
  }
  return 0;
}


x86 assembly (clang, -O0):
<_find_tag>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %di,%ax
mov    %ax,-0x6(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
mov    -0x20(%rbp),%rdx
mov    -0x28(%rbp),%rcx
call   1030 <st_asn1_tlv_parse@plt>
mov    %ax,-0x2a(%rbp)
movzwl %ax,%eax
cmp    $0x0,%eax
je     120a <_find_tag+0xea>
movzwl -0x2a(%rbp),%eax
movzwl -0x6(%rbp),%ecx
cmp    %ecx,%eax
jne    1180 <_find_tag+0x60>
movl   $0x1,-0x4(%rbp)
jmp    1211 <_find_tag+0xf1>
movzwl -0x2a(%rbp),%eax
cmp    $0x100,%eax
jge    119f <_find_tag+0x7f>
movzwl -0x2a(%rbp),%eax
and    $0x20,%eax
cmp    $0x0,%eax
jne    11c0 <_find_tag+0xa0>
movzwl -0x2a(%rbp),%eax
cmp    $0xff,%eax
jle    1200 <_find_tag+0xe0>
movzwl -0x2a(%rbp),%eax
and    $0x2000,%eax
cmp    $0x0,%eax
je     1200 <_find_tag+0xe0>
mov    -0x6(%rbp),%dx
mov    -0x20(%rbp),%rax
mov    (%rax),%rsi
mov    -0x28(%rbp),%rax
mov    (%rax),%ax
mov    -0x20(%rbp),%rcx
mov    -0x28(%rbp),%r8
movzwl %dx,%edi
movzwl %ax,%edx
call   1040 <st_asn1_tlv_find_tag@plt>
cmp    $0x0,%rax
je     11fb <_find_tag+0xdb>
movl   $0x1,-0x4(%rbp)
jmp    1211 <_find_tag+0xf1>
jmp    1200 <_find_tag+0xe0>
jmp    1205 <_find_tag+0xe5>
jmp    113f <_find_tag+0x1f>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<_find_tag>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %r8,%r14
mov    %rcx,%rbx
mov    %rdx,%r15
mov    %rsi,%r12
mov    %edi,%r13d
mov    %rsi,%rdi
mov    %rdx,%rsi
mov    %rcx,%rdx
mov    %r8,%rcx
call   1030 <st_asn1_tlv_parse@plt>
test   %ax,%ax
je     11b8 <_find_tag+0x98>
mov    $0x1,%ebp
jmp    1191 <_find_tag+0x71>
nopw   0x0(%rax,%rax,1)
mov    (%rbx),%rsi
movzwl (%r14),%edx
movzwl %r13w,%edi
mov    %rbx,%rcx
mov    %r14,%r8
call   1040 <st_asn1_tlv_find_tag@plt>
test   %rax,%rax
jne    11ba <_find_tag+0x9a>
mov    %r12,%rdi
mov    %r15,%rsi
mov    %rbx,%rdx
mov    %r14,%rcx
call   1030 <st_asn1_tlv_parse@plt>
test   %ax,%ax
je     11b8 <_find_tag+0x98>
cmp    %r13w,%ax
je     11ba <_find_tag+0x9a>
movzwl %ax,%eax
cmp    $0xff,%eax
ja     11a8 <_find_tag+0x88>
mov    %eax,%ecx
and    $0x20,%ecx
jne    1160 <_find_tag+0x40>
cmp    $0x100,%eax
jb     117b <_find_tag+0x5b>
and    $0x2000,%eax
jne    1160 <_find_tag+0x40>
jmp    117b <_find_tag+0x5b>
xor    %ebp,%ebp
mov    %ebp,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32 @_find_tag(i16 zeroext %0, i8** %1, i16* %2, i8** %3, i16* %4) {
%6 = alloca i32
%7 = alloca i16
%8 = alloca i8**
%9 = alloca i16*
%10 = alloca i8**
%11 = alloca i16*
%12 = alloca i16
store i16 %0, i16* %7
store i8** %1, i8*** %8
store i16* %2, i16** %9
store i8** %3, i8*** %10
store i16* %4, i16** %11
br label %13
13: ; preds = %59, %5
%14 = load i8**, i8*** %8
%15 = load i16*, i16** %9
%16 = load i8**, i8*** %10
%17 = load i16*, i16** %11
%18 = call zeroext i16 @st_asn1_tlv_parse(i8** %14, i16* %15, i8** %16, i16* %17)
store i16 %18, i16* %12
%19 = zext i16 %18 to i32
%20 = icmp ne i32 %19, 0
br i1 %20, label %21, label %60
21: ; preds = %13
%22 = load i16, i16* %12
%23 = zext i16 %22 to i32
%24 = load i16, i16* %7
%25 = zext i16 %24 to i32
%26 = icmp eq i32 %23, %25
br i1 %26, label %27, label %28
27: ; preds = %21
store i32 1, i32* %6
br label %61
28: ; preds = %21
%29 = load i16, i16* %12
%30 = zext i16 %29 to i32
%31 = icmp slt i32 %30, 256
br i1 %31, label %32, label %37
32: ; preds = %28
%33 = load i16, i16* %12
%34 = zext i16 %33 to i32
%35 = and i32 %34, 32
%36 = icmp ne i32 %35, 0
br i1 %36, label %46, label %37
37: ; preds = %32, %28
%38 = load i16, i16* %12
%39 = zext i16 %38 to i32
%40 = icmp sgt i32 %39, 255
br i1 %40, label %41, label %58
41: ; preds = %37
%42 = load i16, i16* %12
%43 = zext i16 %42 to i32
%44 = and i32 %43, 8192
%45 = icmp ne i32 %44, 0
br i1 %45, label %46, label %58
46: ; preds = %41, %32
%47 = load i16, i16* %7
%48 = load i8**, i8*** %10
%49 = load i8*, i8** %48
%50 = load i16*, i16** %11
%51 = load i16, i16* %50
%52 = load i8**, i8*** %10
%53 = load i16*, i16** %11
%54 = call i64 @st_asn1_tlv_find_tag(i16 zeroext %47, i8* %49, i16 zeroext %51, i8** %52, i16* %53)
%55 = icmp ne i64 %54, 0
br i1 %55, label %56, label %57
56: ; preds = %46
store i32 1, i32* %6
br label %61
57: ; preds = %46
br label %58
58: ; preds = %57, %41, %37
br label %59
59: ; preds = %58
br label %13
60: ; preds = %13
store i32 0, i32* %6
br label %61
61: ; preds = %60, %56, %27
%62 = load i32, i32* %6
ret i32 %62
}

LLVM IR (-O2):
define i32 @_find_tag(i16 zeroext %0, i8** %1, i16* %2, i8** %3, i16* %4) {
%6 = tail call zeroext i16 @st_asn1_tlv_parse(i8** %1, i16* %2, i8** %3, i16* %4)
%7 = icmp eq i16 %6, 0
br i1 %7, label %30, label %8
8: ; preds = %5, %27
%9 = phi i16 [ %28, %27 ], [ %6, %5 ]
%10 = zext i16 %9 to i32
%11 = icmp eq i16 %9, %0
br i1 %11, label %30, label %12
12: ; preds = %8
%13 = icmp ugt i16 %9, 255
%14 = and i32 %10, 32
%15 = icmp eq i32 %14, 0
%16 = select i1 %13, i1 true, i1 %15
br i1 %16, label %17, label %22
17: ; preds = %12
%18 = icmp ult i16 %9, 256
%19 = and i32 %10, 8192
%20 = icmp eq i32 %19, 0
%21 = select i1 %18, i1 true, i1 %20
br i1 %21, label %27, label %22
22: ; preds = %17, %12
%23 = load i8*, i8** %3
%24 = load i16, i16* %4
%25 = tail call i64 @st_asn1_tlv_find_tag(i16 zeroext %0, i8* %23, i16 zeroext %24, i8** %3, i16* %4)
%26 = icmp eq i64 %25, 0
br i1 %26, label %27, label %30
27: ; preds = %17, %22
%28 = tail call zeroext i16 @st_asn1_tlv_parse(i8** %1, i16* %2, i8** %3, i16* %4)
%29 = icmp eq i16 %28, 0
br i1 %29, label %30, label %8
30: ; preds = %8, %22, %27, %5
%31 = phi i32 [ 0, %5 ], [ 0, %27 ], [ 1, %22 ], [ 1, %8 ]
ret i32 %31
}