#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 */
typedef struct TYPE_6__ TYPE_2__;
typedef struct TYPE_5__ TYPE_1__;

/* Type definitions */
struct TYPE_5__ {
  int boolean;
  scalar_t__ ptr;
  int /*<<< orphan*/ object;
};
struct TYPE_6__ {
  int type;
  TYPE_1__ value;
};
typedef TYPE_2__ ASN1_TYPE;
typedef int /*<<< orphan*/ ASN1_STRING;

/* Variables and functions */
int ASN1_STRING_cmp(int /*<<< orphan*/ *, int /*<<< orphan*/ *);
int OBJ_cmp(int /*<<< orphan*/, int /*<<< orphan*/);
#define V_ASN1_BIT_STRING 150
#define V_ASN1_BMPSTRING 149
#define V_ASN1_BOOLEAN 148
#define V_ASN1_ENUMERATED 147
#define V_ASN1_GENERALIZEDTIME 146
#define V_ASN1_GENERALSTRING 145
#define V_ASN1_GRAPHICSTRING 144
#define V_ASN1_IA5STRING 143
#define V_ASN1_INTEGER 142
#define V_ASN1_NULL 141
#define V_ASN1_NUMERICSTRING 140
#define V_ASN1_OBJECT 139
#define V_ASN1_OCTET_STRING 138
#define V_ASN1_OTHER 137
#define V_ASN1_PRINTABLESTRING 136
#define V_ASN1_SEQUENCE 135
#define V_ASN1_SET 134
#define V_ASN1_T61STRING 133
#define V_ASN1_UNIVERSALSTRING 132
#define V_ASN1_UTCTIME 131
#define V_ASN1_UTF8STRING 130
#define V_ASN1_VIDEOTEXSTRING 129
#define V_ASN1_VISIBLESTRING 128
int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b) {
  int result = -1;
  if (!a || !b || a->type != b->type)
    return -1;
  switch (a->type) {
  case V_ASN1_OBJECT:
    result = OBJ_cmp(a->value.object, b->value.object);
    break;
  case V_ASN1_BOOLEAN:
    result = a->value.boolean - b->value.boolean;
    break;
  case V_ASN1_NULL:
    result = 0;
    break;
  case V_ASN1_INTEGER:
  case V_ASN1_ENUMERATED:
  case V_ASN1_BIT_STRING:
  case V_ASN1_OCTET_STRING:
  case V_ASN1_SEQUENCE:
  case V_ASN1_SET:
  case V_ASN1_NUMERICSTRING:
  case V_ASN1_PRINTABLESTRING:
  case V_ASN1_T61STRING:
  case V_ASN1_VIDEOTEXSTRING:
  case V_ASN1_IA5STRING:
  case V_ASN1_UTCTIME:
  case V_ASN1_GENERALIZEDTIME:
  case V_ASN1_GRAPHICSTRING:
  case V_ASN1_VISIBLESTRING:
  case V_ASN1_GENERALSTRING:
  case V_ASN1_UNIVERSALSTRING:
  case V_ASN1_BMPSTRING:
  case V_ASN1_UTF8STRING:
  case V_ASN1_OTHER:
  default:
    result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr,
                             (ASN1_STRING *)b->value.ptr);
    break;
  }
  return result;
}


x86 assembly (clang, -O0):
<ASN1_TYPE_cmp>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
movl   $0xffffffff,-0x1c(%rbp)
cmpq   $0x0,-0x10(%rbp)
je     115f <ASN1_TYPE_cmp+0x3f>
cmpq   $0x0,-0x18(%rbp)
je     115f <ASN1_TYPE_cmp+0x3f>
mov    -0x10(%rbp),%rax
mov    (%rax),%eax
mov    -0x18(%rbp),%rcx
cmp    (%rcx),%eax
je     116b <ASN1_TYPE_cmp+0x4b>
movl   $0xffffffff,-0x4(%rbp)
jmp    11f7 <ASN1_TYPE_cmp+0xd7>
mov    -0x10(%rbp),%rax
mov    (%rax),%eax
add    $0xffffff80,%eax
mov    %eax,%ecx
mov    %rcx,-0x28(%rbp)
sub    $0x16,%eax
ja     11d9 <ASN1_TYPE_cmp+0xb9>
mov    -0x28(%rbp),%rax
lea    0xe72(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x10(%rbp),%rax
mov    0x18(%rax),%edi
mov    -0x18(%rbp),%rax
mov    0x18(%rax),%esi
call   1040 <OBJ_cmp@plt>
mov    %eax,-0x1c(%rbp)
jmp    11f1 <ASN1_TYPE_cmp+0xd1>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%eax
mov    -0x18(%rbp),%rcx
sub    0x8(%rcx),%eax
mov    %eax,-0x1c(%rbp)
jmp    11f1 <ASN1_TYPE_cmp+0xd1>
movl   $0x0,-0x1c(%rbp)
jmp    11f1 <ASN1_TYPE_cmp+0xd1>
jmp    11d9 <ASN1_TYPE_cmp+0xb9>
mov    -0x10(%rbp),%rax
mov    0x10(%rax),%rdi
mov    -0x18(%rbp),%rax
mov    0x10(%rax),%rsi
call   1030 <ASN1_STRING_cmp@plt>
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ASN1_TYPE_cmp>:
mov    $0xffffffff,%eax
test   %rdi,%rdi
je     115e <ASN1_TYPE_cmp+0x3e>
test   %rsi,%rsi
je     115e <ASN1_TYPE_cmp+0x3e>
mov    (%rdi),%ecx
cmp    (%rsi),%ecx
jne    115e <ASN1_TYPE_cmp+0x3e>
cmp    $0x94,%ecx
je     1158 <ASN1_TYPE_cmp+0x38>
cmp    $0x8d,%ecx
je     115f <ASN1_TYPE_cmp+0x3f>
cmp    $0x8b,%ecx
jne    1162 <ASN1_TYPE_cmp+0x42>
mov    0x18(%rdi),%edi
mov    0x18(%rsi),%esi
jmp    1040 <OBJ_cmp@plt>
mov    0x8(%rdi),%eax
sub    0x8(%rsi),%eax
ret
xor    %eax,%eax
ret
mov    0x10(%rdi),%rdi
mov    0x10(%rsi),%rsi
jmp    1030 <ASN1_STRING_cmp@plt>

LLVM IR (-O0):
%struct.TYPE_6__ = type { i32, %struct.TYPE_5__ }
%struct.TYPE_5__ = type { i32, i64, i32 }
define i32 @ASN1_TYPE_cmp(%struct.TYPE_6__* %0, %struct.TYPE_6__* %1) {
%3 = alloca i32
%4 = alloca %struct.TYPE_6__*
%5 = alloca %struct.TYPE_6__*
%6 = alloca i32
store %struct.TYPE_6__* %0, %struct.TYPE_6__** %4
store %struct.TYPE_6__* %1, %struct.TYPE_6__** %5
store i32 -1, i32* %6
%7 = load %struct.TYPE_6__*, %struct.TYPE_6__** %4
%8 = icmp ne %struct.TYPE_6__* %7, null
br i1 %8, label %9, label %20
9: ; preds = %2
%10 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%11 = icmp ne %struct.TYPE_6__* %10, null
br i1 %11, label %12, label %20
12: ; preds = %9
%13 = load %struct.TYPE_6__*, %struct.TYPE_6__** %4
%14 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %13, i32 0, i32 0
%15 = load i32, i32* %14
%16 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%17 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %16, i32 0, i32 0
%18 = load i32, i32* %17
%19 = icmp ne i32 %15, %18
br i1 %19, label %20, label %21
20: ; preds = %12, %9, %2
store i32 -1, i32* %3
br label %61
21: ; preds = %12
%22 = load %struct.TYPE_6__*, %struct.TYPE_6__** %4
%23 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %22, i32 0, i32 0
%24 = load i32, i32* %23
switch i32 %24, label %47 [
i32 139, label %25
i32 148, label %35
i32 141, label %45
i32 142, label %46
i32 147, label %46
i32 150, label %46
i32 138, label %46
i32 135, label %46
i32 134, label %46
i32 140, label %46
i32 136, label %46
i32 133, label %46
i32 129, label %46
i32 143, label %46
i32 131, label %46
i32 146, label %46
i32 144, label %46
i32 128, label %46
i32 145, label %46
i32 132, label %46
i32 149, label %46
i32 130, label %46
i32 137, label %46
]
25: ; preds = %21
%26 = load %struct.TYPE_6__*, %struct.TYPE_6__** %4
%27 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %26, i32 0, i32 1
%28 = getelementptr inbounds %struct.TYPE_5__, %struct.TYPE_5__* %27, i32 0, i32 2
%29 = load i32, i32* %28
%30 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%31 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %30, i32 0, i32 1
%32 = getelementptr inbounds %struct.TYPE_5__, %struct.TYPE_5__* %31, i32 0, i32 2
%33 = load i32, i32* %32
%34 = call i32 @OBJ_cmp(i32 %29, i32 %33)
store i32 %34, i32* %6
br label %59
35: ; preds = %21
%36 = load %struct.TYPE_6__*, %struct.TYPE_6__** %4
%37 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %36, i32 0, i32 1
%38 = getelementptr inbounds %struct.TYPE_5__, %struct.TYPE_5__* %37, i32 0, i32 0
%39 = load i32, i32* %38
%40 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%41 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %40, i32 0, i32 1
%42 = getelementptr inbounds %struct.TYPE_5__, %struct.TYPE_5__* %41, i32 0, i32 0
%43 = load i32, i32* %42
%44 = sub nsw i32 %39, %43
store i32 %44, i32* %6
br label %59
45: ; preds = %21
store i32 0, i32* %6
br label %59
46: ; preds = %21, %21, %21, %21, %21, %21, %21, %21, %21, %21, %21, %21, %21, %21, %21, %21, %21, %21, %21, %21
br label %47
47: ; preds = %21, %46
%48 = load %struct.TYPE_6__*, %struct.TYPE_6__** %4
%49 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %48, i32 0, i32 1
%50 = getelementptr inbounds %struct.TYPE_5__, %struct.TYPE_5__* %49, i32 0, i32 1
%51 = load i64, i64* %50
%52 = inttoptr i64 %51 to i32*
%53 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%54 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %53, i32 0, i32 1
%55 = getelementptr inbounds %struct.TYPE_5__, %struct.TYPE_5__* %54, i32 0, i32 1
%56 = load i64, i64* %55
%57 = inttoptr i64 %56 to i32*
%58 = call i32 @ASN1_STRING_cmp(i32* %52, i32* %57)
store i32 %58, i32* %6
br label %59
59: ; preds = %47, %45, %35, %25
%60 = load i32, i32* %6
store i32 %60, i32* %3
br label %61
61: ; preds = %59, %20
%62 = load i32, i32* %3
ret i32 %62
}

LLVM IR (-O2):
%struct.TYPE_6__ = type { i32, %struct.TYPE_5__ }
%struct.TYPE_5__ = type { i32, i64, i32 }
define i32 @ASN1_TYPE_cmp(%struct.TYPE_6__* %0, %struct.TYPE_6__* %1) {
%3 = icmp ne %struct.TYPE_6__* %0, null
%4 = icmp ne %struct.TYPE_6__* %1, null
%5 = and i1 %3, %4
br i1 %5, label %6, label %33
6: ; preds = %2
%7 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %0, i64 0, i32 0
%8 = load i32, i32* %7
%9 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %1, i64 0, i32 0
%10 = load i32, i32* %9
%11 = icmp eq i32 %8, %10
br i1 %11, label %12, label %33
12: ; preds = %6
switch i32 %8, label %25 [
i32 139, label %13
i32 148, label %19
i32 141, label %33
]
13: ; preds = %12
%14 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %0, i64 0, i32 1, i32 2
%15 = load i32, i32* %14
%16 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %1, i64 0, i32 1, i32 2
%17 = load i32, i32* %16
%18 = tail call i32 @OBJ_cmp(i32 %15, i32 %17)
br label %33
19: ; preds = %12
%20 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %0, i64 0, i32 1, i32 0
%21 = load i32, i32* %20
%22 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %1, i64 0, i32 1, i32 0
%23 = load i32, i32* %22
%24 = sub nsw i32 %21, %23
br label %33
25: ; preds = %12
%26 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %0, i64 0, i32 1, i32 1
%27 = load i64, i64* %26
%28 = inttoptr i64 %27 to i32*
%29 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %1, i64 0, i32 1, i32 1
%30 = load i64, i64* %29
%31 = inttoptr i64 %30 to i32*
%32 = tail call i32 @ASN1_STRING_cmp(i32* %28, i32* %31)
br label %33
33: ; preds = %13, %19, %25, %12, %2, %6
%34 = phi i32 [ -1, %6 ], [ -1, %2 ], [ %32, %25 ], [ %24, %19 ], [ %18, %13 ], [ 0, %12 ]
ret i32 %34
}