#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 int /*<<< orphan*/ RSA;
typedef int /*<<< orphan*/ EVP_PKEY;

/* Variables and functions */
int /*<<< orphan*/ ERR_get_error();
int EVP_PKEY_assign_RSA(int /*<<< orphan*/ *, int /*<<< orphan*/);
int /*<<< orphan*/ EVP_PKEY_free(int /*<<< orphan*/ *);
int /*<<< orphan*/ *EVP_PKEY_new();
int /*<<< orphan*/ RSAPrivateKey_dup(int /*<<< orphan*/ *);
int /*<<< orphan*/ RSAPublicKey_dup(int /*<<< orphan*/ *);
int /*<<< orphan*/ RSA_F4;
int /*<<< orphan*/ RSA_free(int /*<<< orphan*/ *);
int /*<<< orphan*/ *RSA_generate_key(int, int /*<<< orphan*/,
                                     int /*<<< orphan*/ *,
                                     int /*<<< orphan*/ *);
int /*<<< orphan*/ assert(int);
int /*<<< orphan*/ printf(char *, int /*<<< orphan*/);
int make_keys(EVP_PKEY **skey, EVP_PKEY **vkey) {
  int result = -1;
  if (!skey || !vkey)
    return -1;
  if (*skey != NULL) {
    EVP_PKEY_free(*skey);
    *skey = NULL;
  }
  if (*vkey != NULL) {
    EVP_PKEY_free(*vkey);
    *vkey = NULL;
  }
  RSA *rsa = NULL;
  do {
    *skey = EVP_PKEY_new();
    assert(*skey != NULL);
    if (*skey == NULL) {
      printf("EVP_PKEY_new failed (1), error 0x%lx\n", ERR_get_error());
      break;
    }
    *vkey = EVP_PKEY_new();
    assert(*vkey != NULL);
    if (*vkey == NULL) {
      printf("EVP_PKEY_new failed (2), error 0x%lx\n", ERR_get_error());
      break;
    }
    rsa = RSA_generate_key(512, RSA_F4, NULL, NULL);
    assert(rsa != NULL);
    if (rsa == NULL) {
      printf("RSA_generate_key failed, error 0x%lx\n", ERR_get_error());
      break;
    }
    int rc = EVP_PKEY_assign_RSA(*skey, RSAPrivateKey_dup(rsa));
    assert(rc == 1);
    if (rc != 1) {
      printf("EVP_PKEY_assign_RSA (1) failed, error 0x%lx\n", ERR_get_error());
      break;
    }
    rc = EVP_PKEY_assign_RSA(*vkey, RSAPublicKey_dup(rsa));
    assert(rc == 1);
    if (rc != 1) {
      printf("EVP_PKEY_assign_RSA (2) failed, error 0x%lx\n", ERR_get_error());
      break;
    }
    result = 0;
  } while (0);
  if (rsa) {
    RSA_free(rsa);
    rsa = NULL;
  }
  return !!result;
}


x86 assembly (clang, -O0):
<make_keys>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
movl   $0xffffffff,-0x1c(%rbp)
cmpq   $0x0,-0x10(%rbp)
je     11cd <make_keys+0x2d>
cmpq   $0x0,-0x18(%rbp)
jne    11d9 <make_keys+0x39>
movl   $0xffffffff,-0x4(%rbp)
jmp    1400 <make_keys+0x260>
mov    -0x10(%rbp),%rax
cmpq   $0x0,(%rax)
je     11fe <make_keys+0x5e>
mov    -0x10(%rbp),%rax
mov    (%rax),%rdi
call   1060 <EVP_PKEY_free@plt>
mov    -0x10(%rbp),%rax
movq   $0x0,(%rax)
mov    -0x18(%rbp),%rax
cmpq   $0x0,(%rax)
je     1223 <make_keys+0x83>
mov    -0x18(%rbp),%rax
mov    (%rax),%rdi
call   1060 <EVP_PKEY_free@plt>
mov    -0x18(%rbp),%rax
movq   $0x0,(%rax)
movq   $0x0,-0x28(%rbp)
mov    $0x0,%al
call   10a0 <EVP_PKEY_new@plt>
mov    %rax,%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x10(%rbp),%rax
cmpq   $0x0,(%rax)
setne  %al
and    $0x1,%al
movzbl %al,%edi
call   1090 <assert@plt>
mov    -0x10(%rbp),%rax
cmpq   $0x0,(%rax)
jne    1279 <make_keys+0xd9>
mov    $0x0,%al
call   10b0 <ERR_get_error@plt>
mov    %eax,%esi
lea    0xd91(%rip),%rdi
call   1050 <printf@plt>
jmp    13d1 <make_keys+0x231>
mov    $0x0,%al
call   10a0 <EVP_PKEY_new@plt>
mov    %rax,%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x18(%rbp),%rax
cmpq   $0x0,(%rax)
setne  %al
and    $0x1,%al
movzbl %al,%edi
call   1090 <assert@plt>
mov    -0x18(%rbp),%rax
cmpq   $0x0,(%rax)
jne    12c7 <make_keys+0x127>
mov    $0x0,%al
call   10b0 <ERR_get_error@plt>
mov    %eax,%esi
lea    0xd69(%rip),%rdi
call   1050 <printf@plt>
jmp    13d1 <make_keys+0x231>
mov    0x2d12(%rip),%rax
mov    (%rax),%esi
mov    $0x200,%edi
xor    %eax,%eax
mov    %eax,%ecx
mov    %rcx,%rdx
call   10c0 <RSA_generate_key@plt>
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
setne  %al
and    $0x1,%al
movzbl %al,%edi
call   1090 <assert@plt>
cmpq   $0x0,-0x28(%rbp)
jne    131c <make_keys+0x17c>
mov    $0x0,%al
call   10b0 <ERR_get_error@plt>
mov    %eax,%esi
lea    0xd3a(%rip),%rdi
call   1050 <printf@plt>
jmp    13d1 <make_keys+0x231>
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x38(%rbp)
mov    -0x28(%rbp),%rdi
call   1070 <RSAPrivateKey_dup@plt>
mov    -0x38(%rbp),%rdi
mov    %eax,%esi
call   1030 <EVP_PKEY_assign_RSA@plt>
mov    %eax,-0x2c(%rbp)
cmpl   $0x1,-0x2c(%rbp)
sete   %al
and    $0x1,%al
movzbl %al,%edi
call   1090 <assert@plt>
cmpl   $0x1,-0x2c(%rbp)
je     1373 <make_keys+0x1d3>
mov    $0x0,%al
call   10b0 <ERR_get_error@plt>
mov    %eax,%esi
lea    0xd09(%rip),%rdi
call   1050 <printf@plt>
jmp    13d1 <make_keys+0x231>
mov    -0x18(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x40(%rbp)
mov    -0x28(%rbp),%rdi
call   1080 <RSAPublicKey_dup@plt>
mov    -0x40(%rbp),%rdi
mov    %eax,%esi
call   1030 <EVP_PKEY_assign_RSA@plt>
mov    %eax,-0x2c(%rbp)
cmpl   $0x1,-0x2c(%rbp)
sete   %al
and    $0x1,%al
movzbl %al,%edi
call   1090 <assert@plt>
cmpl   $0x1,-0x2c(%rbp)
je     13ca <make_keys+0x22a>
mov    $0x0,%al
call   10b0 <ERR_get_error@plt>
mov    %eax,%esi
lea    0xcdf(%rip),%rdi
call   1050 <printf@plt>
jmp    13d1 <make_keys+0x231>
movl   $0x0,-0x1c(%rbp)
cmpq   $0x0,-0x28(%rbp)
je     13ed <make_keys+0x24d>
mov    -0x28(%rbp),%rdi
call   1040 <RSA_free@plt>
movq   $0x0,-0x28(%rbp)
cmpl   $0x0,-0x1c(%rbp)
setne  %al
xor    $0xff,%al
xor    $0xff,%al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<make_keys>:
push   %rbp
push   %r15
push   %r14
push   %rbx
push   %rax
mov    $0xffffffff,%eax
test   %rdi,%rdi
je     1324 <make_keys+0x184>
mov    %rsi,%r14
test   %rsi,%rsi
je     1324 <make_keys+0x184>
mov    %rdi,%rbx
mov    (%rdi),%rdi
test   %rdi,%rdi
je     11d8 <make_keys+0x38>
call   1060 <EVP_PKEY_free@plt>
movq   $0x0,(%rbx)
mov    (%r14),%rdi
test   %rdi,%rdi
je     11ec <make_keys+0x4c>
call   1060 <EVP_PKEY_free@plt>
movq   $0x0,(%r14)
xor    %eax,%eax
call   10a0 <EVP_PKEY_new@plt>
mov    %rax,(%rbx)
xor    %edi,%edi
test   %rax,%rax
setne  %dil
call   1090 <assert@plt>
cmpq   $0x0,(%rbx)
je     12bc <make_keys+0x11c>
xor    %eax,%eax
call   10a0 <EVP_PKEY_new@plt>
mov    %rax,(%r14)
xor    %edi,%edi
test   %rax,%rax
setne  %dil
call   1090 <assert@plt>
cmpq   $0x0,(%r14)
je     12cc <make_keys+0x12c>
mov    0x2da9(%rip),%rax
mov    (%rax),%esi
mov    $0x200,%edi
xor    %edx,%edx
xor    %ecx,%ecx
call   10c0 <RSA_generate_key@plt>
mov    %rax,%r15
xor    %edi,%edi
test   %rax,%rax
setne  %dil
call   1090 <assert@plt>
test   %r15,%r15
je     12dc <make_keys+0x13c>
mov    (%rbx),%rbx
mov    %r15,%rdi
call   1070 <RSAPrivateKey_dup@plt>
mov    %rbx,%rdi
mov    %eax,%esi
call   1030 <EVP_PKEY_assign_RSA@plt>
mov    %eax,%ebx
xor    %edi,%edi
cmp    $0x1,%eax
sete   %dil
call   1090 <assert@plt>
cmp    $0x1,%ebx
jne    12f8 <make_keys+0x158>
mov    (%r14),%rbx
mov    %r15,%rdi
call   1080 <RSAPublicKey_dup@plt>
mov    %rbx,%rdi
mov    %eax,%esi
call   1030 <EVP_PKEY_assign_RSA@plt>
mov    %eax,%ebx
xor    %edi,%edi
cmp    $0x1,%eax
sete   %dil
call   1090 <assert@plt>
xor    %ebp,%ebp
cmp    $0x1,%ebx
je     1315 <make_keys+0x175>
lea    0xde5(%rip),%rbx
jmp    12ff <make_keys+0x15f>
xor    %eax,%eax
call   10b0 <ERR_get_error@plt>
lea    0xd36(%rip),%rdi
jmp    12ea <make_keys+0x14a>
xor    %eax,%eax
call   10b0 <ERR_get_error@plt>
lea    0xd4c(%rip),%rdi
jmp    12ea <make_keys+0x14a>
xor    %eax,%eax
call   10b0 <ERR_get_error@plt>
lea    0xd62(%rip),%rdi
mov    %eax,%esi
call   1050 <printf@plt>
mov    $0xffffffff,%ebp
jmp    131d <make_keys+0x17d>
lea    0xd73(%rip),%rbx
xor    %eax,%eax
call   10b0 <ERR_get_error@plt>
mov    %rbx,%rdi
mov    %eax,%esi
call   1050 <printf@plt>
mov    $0xffffffff,%ebp
mov    %r15,%rdi
call   1040 <RSA_free@plt>
xor    %eax,%eax
test   %ebp,%ebp
setne  %al
add    $0x8,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [38 x i8] c"EVP_PKEY_new failed (1), error 0x%lx\0A\00"
@.str.1 = [38 x i8] c"EVP_PKEY_new failed (2), error 0x%lx\0A\00"
@RSA_F4 = global i32 0
@.str.2 = [38 x i8] c"RSA_generate_key failed, error 0x%lx\0A\00"
@.str.3 = [45 x i8] c"EVP_PKEY_assign_RSA (1) failed, error 0x%lx\0A\00"
@.str.4 = [45 x i8] c"EVP_PKEY_assign_RSA (2) failed, error 0x%lx\0A\00"
define i32 @make_keys(i32** %0, i32** %1) {
%3 = alloca i32
%4 = alloca i32**
%5 = alloca i32**
%6 = alloca i32
%7 = alloca i32*
%8 = alloca i32
store i32** %0, i32*** %4
store i32** %1, i32*** %5
store i32 -1, i32* %6
%9 = load i32**, i32*** %4
%10 = icmp ne i32** %9, null
br i1 %10, label %11, label %14
11: ; preds = %2
%12 = load i32**, i32*** %5
%13 = icmp ne i32** %12, null
br i1 %13, label %15, label %14
14: ; preds = %11, %2
store i32 -1, i32* %3
br label %117
15: ; preds = %11
%16 = load i32**, i32*** %4
%17 = load i32*, i32** %16
%18 = icmp ne i32* %17, null
br i1 %18, label %19, label %24
19: ; preds = %15
%20 = load i32**, i32*** %4
%21 = load i32*, i32** %20
%22 = call i32 @EVP_PKEY_free(i32* %21)
%23 = load i32**, i32*** %4
store i32* null, i32** %23
br label %24
24: ; preds = %19, %15
%25 = load i32**, i32*** %5
%26 = load i32*, i32** %25
%27 = icmp ne i32* %26, null
br i1 %27, label %28, label %33
28: ; preds = %24
%29 = load i32**, i32*** %5
%30 = load i32*, i32** %29
%31 = call i32 @EVP_PKEY_free(i32* %30)
%32 = load i32**, i32*** %5
store i32* null, i32** %32
br label %33
33: ; preds = %28, %24
store i32* null, i32** %7
br label %34
34: ; preds = %33
%35 = call i32* (...) @EVP_PKEY_new()
%36 = load i32**, i32*** %4
store i32* %35, i32** %36
%37 = load i32**, i32*** %4
%38 = load i32*, i32** %37
%39 = icmp ne i32* %38, null
%40 = zext i1 %39 to i32
%41 = call i32 @assert(i32 %40)
%42 = load i32**, i32*** %4
%43 = load i32*, i32** %42
%44 = icmp eq i32* %43, null
br i1 %44, label %45, label %48
45: ; preds = %34
%46 = call i32 (...) @ERR_get_error()
%47 = call i32 @printf(i8* getelementptr inbounds ([38 x i8], [38 x i8]* @.str, i64 0, i64 0), i32 %46)
br label %105
48: ; preds = %34
%49 = call i32* (...) @EVP_PKEY_new()
%50 = load i32**, i32*** %5
store i32* %49, i32** %50
%51 = load i32**, i32*** %5
%52 = load i32*, i32** %51
%53 = icmp ne i32* %52, null
%54 = zext i1 %53 to i32
%55 = call i32 @assert(i32 %54)
%56 = load i32**, i32*** %5
%57 = load i32*, i32** %56
%58 = icmp eq i32* %57, null
br i1 %58, label %59, label %62
59: ; preds = %48
%60 = call i32 (...) @ERR_get_error()
%61 = call i32 @printf(i8* getelementptr inbounds ([38 x i8], [38 x i8]* @.str.1, i64 0, i64 0), i32 %60)
br label %105
62: ; preds = %48
%63 = load i32, i32* @RSA_F4
%64 = call i32* @RSA_generate_key(i32 512, i32 %63, i32* null, i32* null)
store i32* %64, i32** %7
%65 = load i32*, i32** %7
%66 = icmp ne i32* %65, null
%67 = zext i1 %66 to i32
%68 = call i32 @assert(i32 %67)
%69 = load i32*, i32** %7
%70 = icmp eq i32* %69, null
br i1 %70, label %71, label %74
71: ; preds = %62
%72 = call i32 (...) @ERR_get_error()
%73 = call i32 @printf(i8* getelementptr inbounds ([38 x i8], [38 x i8]* @.str.2, i64 0, i64 0), i32 %72)
br label %105
74: ; preds = %62
%75 = load i32**, i32*** %4
%76 = load i32*, i32** %75
%77 = load i32*, i32** %7
%78 = call i32 @RSAPrivateKey_dup(i32* %77)
%79 = call i32 @EVP_PKEY_assign_RSA(i32* %76, i32 %78)
store i32 %79, i32* %8
%80 = load i32, i32* %8
%81 = icmp eq i32 %80, 1
%82 = zext i1 %81 to i32
%83 = call i32 @assert(i32 %82)
%84 = load i32, i32* %8
%85 = icmp ne i32 %84, 1
br i1 %85, label %86, label %89
86: ; preds = %74
%87 = call i32 (...) @ERR_get_error()
%88 = call i32 @printf(i8* getelementptr inbounds ([45 x i8], [45 x i8]* @.str.3, i64 0, i64 0), i32 %87)
br label %105
89: ; preds = %74
%90 = load i32**, i32*** %5
%91 = load i32*, i32** %90
%92 = load i32*, i32** %7
%93 = call i32 @RSAPublicKey_dup(i32* %92)
%94 = call i32 @EVP_PKEY_assign_RSA(i32* %91, i32 %93)
store i32 %94, i32* %8
%95 = load i32, i32* %8
%96 = icmp eq i32 %95, 1
%97 = zext i1 %96 to i32
%98 = call i32 @assert(i32 %97)
%99 = load i32, i32* %8
%100 = icmp ne i32 %99, 1
br i1 %100, label %101, label %104
101: ; preds = %89
%102 = call i32 (...) @ERR_get_error()
%103 = call i32 @printf(i8* getelementptr inbounds ([45 x i8], [45 x i8]* @.str.4, i64 0, i64 0), i32 %102)
br label %105
104: ; preds = %89
store i32 0, i32* %6
br label %105
105: ; preds = %104, %101, %86, %71, %59, %45
%106 = load i32*, i32** %7
%107 = icmp ne i32* %106, null
br i1 %107, label %108, label %111
108: ; preds = %105
%109 = load i32*, i32** %7
%110 = call i32 @RSA_free(i32* %109)
store i32* null, i32** %7
br label %111
111: ; preds = %108, %105
%112 = load i32, i32* %6
%113 = icmp ne i32 %112, 0
%114 = xor i1 %113, true
%115 = xor i1 %114, true
%116 = zext i1 %115 to i32
store i32 %116, i32* %3
br label %117
117: ; preds = %111, %14
%118 = load i32, i32* %3
ret i32 %118
}

LLVM IR (-O2):
@.str = [38 x i8] c"EVP_PKEY_new failed (1), error 0x%lx\0A\00"
@.str.1 = [38 x i8] c"EVP_PKEY_new failed (2), error 0x%lx\0A\00"
@RSA_F4 = global i32 0
@.str.2 = [38 x i8] c"RSA_generate_key failed, error 0x%lx\0A\00"
@.str.3 = [45 x i8] c"EVP_PKEY_assign_RSA (1) failed, error 0x%lx\0A\00"
@.str.4 = [45 x i8] c"EVP_PKEY_assign_RSA (2) failed, error 0x%lx\0A\00"
define i32 @make_keys(i32** %0, i32** %1) {
%3 = icmp ne i32** %0, null
%4 = icmp ne i32** %1, null
%5 = and i1 %3, %4
br i1 %5, label %6, label %71
6: ; preds = %2
%7 = load i32*, i32** %0
%8 = icmp eq i32* %7, null
br i1 %8, label %11, label %9
9: ; preds = %6
%10 = tail call i32 @EVP_PKEY_free(i32* %7)
store i32* null, i32** %0
br label %11
11: ; preds = %9, %6
%12 = load i32*, i32** %1
%13 = icmp eq i32* %12, null
br i1 %13, label %16, label %14
14: ; preds = %11
%15 = tail call i32 @EVP_PKEY_free(i32* %12)
store i32* null, i32** %1
br label %16
16: ; preds = %14, %11
%17 = tail call i32* (...) @EVP_PKEY_new()
store i32* %17, i32** %0
%18 = icmp ne i32* %17, null
%19 = zext i1 %18 to i32
%20 = tail call i32 @assert(i32 %19)
%21 = load i32*, i32** %0
%22 = icmp eq i32* %21, null
br i1 %22, label %23, label %26
23: ; preds = %16
%24 = tail call i32 (...) @ERR_get_error()
%25 = tail call i32 @printf(i8* getelementptr inbounds ([38 x i8], [38 x i8]* @.str, i64 0, i64 0), i32 %24)
br label %67
26: ; preds = %16
%27 = tail call i32* (...) @EVP_PKEY_new()
store i32* %27, i32** %1
%28 = icmp ne i32* %27, null
%29 = zext i1 %28 to i32
%30 = tail call i32 @assert(i32 %29)
%31 = load i32*, i32** %1
%32 = icmp eq i32* %31, null
br i1 %32, label %33, label %36
33: ; preds = %26
%34 = tail call i32 (...) @ERR_get_error()
%35 = tail call i32 @printf(i8* getelementptr inbounds ([38 x i8], [38 x i8]* @.str.1, i64 0, i64 0), i32 %34)
br label %67
36: ; preds = %26
%37 = load i32, i32* @RSA_F4
%38 = tail call i32* @RSA_generate_key(i32 512, i32 %37, i32* null, i32* null)
%39 = icmp ne i32* %38, null
%40 = zext i1 %39 to i32
%41 = tail call i32 @assert(i32 %40)
%42 = icmp eq i32* %38, null
br i1 %42, label %43, label %46
43: ; preds = %36
%44 = tail call i32 (...) @ERR_get_error()
%45 = tail call i32 @printf(i8* getelementptr inbounds ([38 x i8], [38 x i8]* @.str.2, i64 0, i64 0), i32 %44)
br label %67
46: ; preds = %36
%47 = load i32*, i32** %0
%48 = tail call i32 @RSAPrivateKey_dup(i32* %38)
%49 = tail call i32 @EVP_PKEY_assign_RSA(i32* %47, i32 %48)
%50 = icmp eq i32 %49, 1
%51 = zext i1 %50 to i32
%52 = tail call i32 @assert(i32 %51)
br i1 %50, label %53, label %60
53: ; preds = %46
%54 = load i32*, i32** %1
%55 = tail call i32 @RSAPublicKey_dup(i32* %38)
%56 = tail call i32 @EVP_PKEY_assign_RSA(i32* %54, i32 %55)
%57 = icmp eq i32 %56, 1
%58 = zext i1 %57 to i32
%59 = tail call i32 @assert(i32 %58)
br i1 %57, label %64, label %60
60: ; preds = %53, %46
%61 = phi i8* [ getelementptr inbounds ([45 x i8], [45 x i8]* @.str.3, i64 0, i64 0), %46 ], [ getelementptr inbounds ([45 x i8], [45 x i8]* @.str.4, i64 0, i64 0), %53 ]
%62 = tail call i32 (...) @ERR_get_error()
%63 = tail call i32 @printf(i8* %61, i32 %62)
br label %64
64: ; preds = %60, %53
%65 = phi i32 [ 0, %53 ], [ -1, %60 ]
%66 = tail call i32 @RSA_free(i32* %38)
br label %67
67: ; preds = %43, %33, %23, %64
%68 = phi i32 [ %65, %64 ], [ -1, %23 ], [ -1, %33 ], [ -1, %43 ]
%69 = icmp ne i32 %68, 0
%70 = zext i1 %69 to i32
br label %71
71: ; preds = %2, %67
%72 = phi i32 [ %70, %67 ], [ -1, %2 ]
ret i32 %72
}