#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__ {
  scalar_t__ p;
};
struct TYPE_6__ {
  size_t num;
  int Nl;
  int Nh;
  int md_len;
  int *h;
  TYPE_1__ u;
};
typedef int SHA_LONG64;
typedef TYPE_2__ SHA512_CTX;

/* Variables and functions */
#define SHA384_DIGEST_LENGTH 129
#define SHA512_DIGEST_LENGTH 128
int /*<<< orphan*/ memset(unsigned char *, int /*<<< orphan*/, int);
int /*<<< orphan*/ sha512_block_data_order(TYPE_2__ *, unsigned char *, int);
int SHA512_Final(unsigned char *md, SHA512_CTX *c) {
  unsigned char *p = (unsigned char *)c->u.p;
  size_t n = c->num;
  p[n] = 0x80;
  n++;
  if (n > (sizeof(c->u) - 16)) {
    memset(p + n, 0, sizeof(c->u) - n);
    n = 0;
    sha512_block_data_order(c, p, 1);
  }
  memset(p + n, 0, sizeof(c->u) - 16 - n);
  p[sizeof(c->u) - 1] = (unsigned char)(c->Nl);
  p[sizeof(c->u) - 2] = (unsigned char)(c->Nl >> 8);
  p[sizeof(c->u) - 3] = (unsigned char)(c->Nl >> 16);
  p[sizeof(c->u) - 4] = (unsigned char)(c->Nl >> 24);
  p[sizeof(c->u) - 5] = (unsigned char)(c->Nl >> 32);
  p[sizeof(c->u) - 6] = (unsigned char)(c->Nl >> 40);
  p[sizeof(c->u) - 7] = (unsigned char)(c->Nl >> 48);
  p[sizeof(c->u) - 8] = (unsigned char)(c->Nl >> 56);
  p[sizeof(c->u) - 9] = (unsigned char)(c->Nh);
  p[sizeof(c->u) - 10] = (unsigned char)(c->Nh >> 8);
  p[sizeof(c->u) - 11] = (unsigned char)(c->Nh >> 16);
  p[sizeof(c->u) - 12] = (unsigned char)(c->Nh >> 24);
  p[sizeof(c->u) - 13] = (unsigned char)(c->Nh >> 32);
  p[sizeof(c->u) - 14] = (unsigned char)(c->Nh >> 40);
  p[sizeof(c->u) - 15] = (unsigned char)(c->Nh >> 48);
  p[sizeof(c->u) - 16] = (unsigned char)(c->Nh >> 56);
  sha512_block_data_order(c, p, 1);
  if (md == 0)
    return 0;
  switch (c->md_len) {
  case SHA384_DIGEST_LENGTH:
    for (n = 0; n < SHA384_DIGEST_LENGTH / 8; n++) {
      SHA_LONG64 t = c->h[n];
      *(md++) = (unsigned char)(t >> 56);
      *(md++) = (unsigned char)(t >> 48);
      *(md++) = (unsigned char)(t >> 40);
      *(md++) = (unsigned char)(t >> 32);
      *(md++) = (unsigned char)(t >> 24);
      *(md++) = (unsigned char)(t >> 16);
      *(md++) = (unsigned char)(t >> 8);
      *(md++) = (unsigned char)(t);
    }
    break;
  case SHA512_DIGEST_LENGTH:
    for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) {
      SHA_LONG64 t = c->h[n];
      *(md++) = (unsigned char)(t >> 56);
      *(md++) = (unsigned char)(t >> 48);
      *(md++) = (unsigned char)(t >> 40);
      *(md++) = (unsigned char)(t >> 32);
      *(md++) = (unsigned char)(t >> 24);
      *(md++) = (unsigned char)(t >> 16);
      *(md++) = (unsigned char)(t >> 8);
      *(md++) = (unsigned char)(t);
    }
    break;
  default:
    return 0;
  }
  return 1;
}


x86 assembly (clang, -O0):
<SHA512_Final>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    -0x18(%rbp),%rax
mov    0x20(%rax),%rax
mov    %rax,-0x20(%rbp)
mov    -0x18(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%rcx
movb   $0x80,(%rax,%rcx,1)
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
cmpq   $0xfffffffffffffff8,-0x28(%rbp)
jbe    119e <SHA512_Final+0x7e>
mov    -0x20(%rbp),%rdi
add    -0x28(%rbp),%rdi
mov    $0x8,%eax
sub    -0x28(%rbp),%rax
mov    %eax,%edx
xor    %esi,%esi
call   1030 <memset@plt>
movq   $0x0,-0x28(%rbp)
mov    -0x18(%rbp),%rdi
mov    -0x20(%rbp),%rsi
mov    $0x1,%edx
call   1040 <sha512_block_data_order@plt>
mov    -0x20(%rbp),%rdi
add    -0x28(%rbp),%rdi
mov    $0xfffffffffffffff8,%rax
sub    -0x28(%rbp),%rax
mov    %eax,%edx
xor    %esi,%esi
call   1030 <memset@plt>
mov    -0x18(%rbp),%rax
mov    0x8(%rax),%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,0x7(%rax)
mov    -0x18(%rbp),%rax
mov    0x8(%rax),%eax
sar    $0x8,%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,0x6(%rax)
mov    -0x18(%rbp),%rax
mov    0x8(%rax),%eax
sar    $0x10,%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,0x5(%rax)
mov    -0x18(%rbp),%rax
mov    0x8(%rax),%eax
sar    $0x18,%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,0x4(%rax)
mov    -0x18(%rbp),%rax
mov    0x8(%rax),%eax
mov    $0x20,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,0x3(%rax)
mov    -0x18(%rbp),%rax
mov    0x8(%rax),%eax
mov    $0x28,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,0x2(%rax)
mov    -0x18(%rbp),%rax
mov    0x8(%rax),%eax
mov    $0x30,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,0x1(%rax)
mov    -0x18(%rbp),%rax
mov    0x8(%rax),%eax
mov    $0x38,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,(%rax)
mov    -0x18(%rbp),%rax
mov    0xc(%rax),%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,-0x1(%rax)
mov    -0x18(%rbp),%rax
mov    0xc(%rax),%eax
sar    $0x8,%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,-0x2(%rax)
mov    -0x18(%rbp),%rax
mov    0xc(%rax),%eax
sar    $0x10,%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,-0x3(%rax)
mov    -0x18(%rbp),%rax
mov    0xc(%rax),%eax
sar    $0x18,%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,-0x4(%rax)
mov    -0x18(%rbp),%rax
mov    0xc(%rax),%eax
mov    $0x20,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,-0x5(%rax)
mov    -0x18(%rbp),%rax
mov    0xc(%rax),%eax
mov    $0x28,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,-0x6(%rax)
mov    -0x18(%rbp),%rax
mov    0xc(%rax),%eax
mov    $0x30,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,-0x7(%rax)
mov    -0x18(%rbp),%rax
mov    0xc(%rax),%eax
mov    $0x38,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,-0x8(%rax)
mov    -0x18(%rbp),%rdi
mov    -0x20(%rbp),%rsi
mov    $0x1,%edx
call   1040 <sha512_block_data_order@plt>
cmpq   $0x0,-0x10(%rbp)
jne    132c <SHA512_Final+0x20c>
movl   $0x0,-0x4(%rbp)
jmp    158c <SHA512_Final+0x46c>
mov    -0x18(%rbp),%rax
mov    0x10(%rax),%eax
mov    %eax,-0x34(%rbp)
sub    $0x80,%eax
je     1469 <SHA512_Final+0x349>
jmp    1346 <SHA512_Final+0x226>
mov    -0x34(%rbp),%eax
sub    $0x81,%eax
jne    1579 <SHA512_Final+0x459>
jmp    1359 <SHA512_Final+0x239>
movq   $0x0,-0x28(%rbp)
cmpq   $0x10,-0x28(%rbp)
jae    1464 <SHA512_Final+0x344>
mov    -0x18(%rbp),%rax
mov    0x18(%rax),%rax
mov    -0x28(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
mov    $0x38,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x2c(%rbp),%eax
mov    $0x30,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x2c(%rbp),%eax
mov    $0x28,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x2c(%rbp),%eax
mov    $0x20,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x2c(%rbp),%eax
sar    $0x18,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x2c(%rbp),%eax
sar    $0x10,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x2c(%rbp),%eax
sar    $0x8,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x2c(%rbp),%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    1361 <SHA512_Final+0x241>
jmp    1585 <SHA512_Final+0x465>
movq   $0x0,-0x28(%rbp)
cmpq   $0x10,-0x28(%rbp)
jae    1574 <SHA512_Final+0x454>
mov    -0x18(%rbp),%rax
mov    0x18(%rax),%rax
mov    -0x28(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
mov    $0x38,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x30(%rbp),%eax
mov    $0x30,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x30(%rbp),%eax
mov    $0x28,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x30(%rbp),%eax
mov    $0x20,%ecx
sar    %cl,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x30(%rbp),%eax
sar    $0x18,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x30(%rbp),%eax
sar    $0x10,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x30(%rbp),%eax
sar    $0x8,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x30(%rbp),%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    1471 <SHA512_Final+0x351>
jmp    1585 <SHA512_Final+0x465>
movl   $0x0,-0x4(%rbp)
jmp    158c <SHA512_Final+0x46c>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<SHA512_Final>:
push   %rbp
push   %r15
push   %r14
push   %rbx
push   %rax
mov    %rsi,%rbx
mov    %rdi,%r14
mov    (%rsi),%rax
mov    0x20(%rsi),%r15
movb   $0x80,(%r15,%rax,1)
lea    0x1(%rax),%rdi
cmp    $0xfffffffffffffff9,%rdi
jb     1166 <SHA512_Final+0x46>
add    %r15,%rdi
mov    $0x7,%edx
sub    %eax,%edx
xor    %esi,%esi
call   1030 <memset@plt>
mov    %rbx,%rdi
mov    %r15,%rsi
mov    $0x1,%edx
call   1040 <sha512_block_data_order@plt>
xor    %edi,%edi
lea    (%r15,%rdi,1),%rax
mov    $0xfffffff8,%edx
sub    %edi,%edx
xor    %ebp,%ebp
mov    %rax,%rdi
xor    %esi,%esi
call   1030 <memset@plt>
mov    0x8(%rbx),%al
mov    %al,0x7(%r15)
mov    0x9(%rbx),%al
mov    %al,0x6(%r15)
mov    0xa(%rbx),%al
mov    %al,0x5(%r15)
mov    0xb(%rbx),%al
mov    %al,0x4(%r15)
mov    0xc(%rbx),%al
mov    %al,-0x1(%r15)
mov    0xd(%rbx),%al
mov    %al,-0x2(%r15)
mov    0xe(%rbx),%al
mov    %al,-0x3(%r15)
mov    0xf(%rbx),%al
mov    %al,-0x4(%r15)
mov    %rbx,%rdi
mov    %r15,%rsi
mov    $0x1,%edx
call   1040 <sha512_block_data_order@plt>
test   %r14,%r14
je     123c <SHA512_Final+0x11c>
mov    0x10(%rbx),%eax
cmp    $0x81,%eax
je     1209 <SHA512_Final+0xe9>
cmp    $0x80,%eax
jne    123c <SHA512_Final+0x11c>
xor    %eax,%eax
nopl   (%rax)
mov    0x18(%rbx),%rcx
mov    (%rcx,%rax,4),%ecx
bswap  %ecx
mov    %ecx,0x4(%r14,%rax,8)
mov    0x18(%rbx),%rcx
mov    0x4(%rcx,%rax,4),%ecx
bswap  %ecx
mov    %ecx,0xc(%r14,%rax,8)
add    $0x2,%rax
cmp    $0x10,%rax
jne    11e0 <SHA512_Final+0xc0>
jmp    1237 <SHA512_Final+0x117>
xor    %eax,%eax
nopl   0x0(%rax,%rax,1)
mov    0x18(%rbx),%rcx
mov    (%rcx,%rax,4),%ecx
bswap  %ecx
mov    %ecx,0x4(%r14,%rax,8)
mov    0x18(%rbx),%rcx
mov    0x4(%rcx,%rax,4),%ecx
bswap  %ecx
mov    %ecx,0xc(%r14,%rax,8)
add    $0x2,%rax
cmp    $0x10,%rax
jne    1210 <SHA512_Final+0xf0>
mov    $0x1,%ebp
mov    %ebp,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.TYPE_6__ = type { i64, i32, i32, i32, i32*, %struct.TYPE_5__ }
%struct.TYPE_5__ = type { i64 }
define i32 @SHA512_Final(i8* %0, %struct.TYPE_6__* %1) {
%3 = alloca i32
%4 = alloca i8*
%5 = alloca %struct.TYPE_6__*
%6 = alloca i8*
%7 = alloca i64
%8 = alloca i32
%9 = alloca i32
store i8* %0, i8** %4
store %struct.TYPE_6__* %1, %struct.TYPE_6__** %5
%10 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%11 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %10, i32 0, i32 5
%12 = getelementptr inbounds %struct.TYPE_5__, %struct.TYPE_5__* %11, i32 0, i32 0
%13 = load i64, i64* %12
%14 = inttoptr i64 %13 to i8*
store i8* %14, i8** %6
%15 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%16 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %15, i32 0, i32 0
%17 = load i64, i64* %16
store i64 %17, i64* %7
%18 = load i8*, i8** %6
%19 = load i64, i64* %7
%20 = getelementptr inbounds i8, i8* %18, i64 %19
store i8 -128, i8* %20
%21 = load i64, i64* %7
%22 = add i64 %21, 1
store i64 %22, i64* %7
%23 = load i64, i64* %7
%24 = icmp ugt i64 %23, -8
br i1 %24, label %25, label %36
25: ; preds = %2
%26 = load i8*, i8** %6
%27 = load i64, i64* %7
%28 = getelementptr inbounds i8, i8* %26, i64 %27
%29 = load i64, i64* %7
%30 = sub i64 8, %29
%31 = trunc i64 %30 to i32
%32 = call i32 @memset(i8* %28, i32 0, i32 %31)
store i64 0, i64* %7
%33 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%34 = load i8*, i8** %6
%35 = call i32 @sha512_block_data_order(%struct.TYPE_6__* %33, i8* %34, i32 1)
br label %36
36: ; preds = %25, %2
%37 = load i8*, i8** %6
%38 = load i64, i64* %7
%39 = getelementptr inbounds i8, i8* %37, i64 %38
%40 = load i64, i64* %7
%41 = sub i64 -8, %40
%42 = trunc i64 %41 to i32
%43 = call i32 @memset(i8* %39, i32 0, i32 %42)
%44 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%45 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %44, i32 0, i32 1
%46 = load i32, i32* %45
%47 = trunc i32 %46 to i8
%48 = load i8*, i8** %6
%49 = getelementptr inbounds i8, i8* %48, i64 7
store i8 %47, i8* %49
%50 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%51 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %50, i32 0, i32 1
%52 = load i32, i32* %51
%53 = ashr i32 %52, 8
%54 = trunc i32 %53 to i8
%55 = load i8*, i8** %6
%56 = getelementptr inbounds i8, i8* %55, i64 6
store i8 %54, i8* %56
%57 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%58 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %57, i32 0, i32 1
%59 = load i32, i32* %58
%60 = ashr i32 %59, 16
%61 = trunc i32 %60 to i8
%62 = load i8*, i8** %6
%63 = getelementptr inbounds i8, i8* %62, i64 5
store i8 %61, i8* %63
%64 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%65 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %64, i32 0, i32 1
%66 = load i32, i32* %65
%67 = ashr i32 %66, 24
%68 = trunc i32 %67 to i8
%69 = load i8*, i8** %6
%70 = getelementptr inbounds i8, i8* %69, i64 4
store i8 %68, i8* %70
%71 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%72 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %71, i32 0, i32 1
%73 = load i32, i32* %72
%74 = ashr i32 %73, 32
%75 = trunc i32 %74 to i8
%76 = load i8*, i8** %6
%77 = getelementptr inbounds i8, i8* %76, i64 3
store i8 %75, i8* %77
%78 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%79 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %78, i32 0, i32 1
%80 = load i32, i32* %79
%81 = ashr i32 %80, 40
%82 = trunc i32 %81 to i8
%83 = load i8*, i8** %6
%84 = getelementptr inbounds i8, i8* %83, i64 2
store i8 %82, i8* %84
%85 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%86 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %85, i32 0, i32 1
%87 = load i32, i32* %86
%88 = ashr i32 %87, 48
%89 = trunc i32 %88 to i8
%90 = load i8*, i8** %6
%91 = getelementptr inbounds i8, i8* %90, i64 1
store i8 %89, i8* %91
%92 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%93 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %92, i32 0, i32 1
%94 = load i32, i32* %93
%95 = ashr i32 %94, 56
%96 = trunc i32 %95 to i8
%97 = load i8*, i8** %6
%98 = getelementptr inbounds i8, i8* %97, i64 0
store i8 %96, i8* %98
%99 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%100 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %99, i32 0, i32 2
%101 = load i32, i32* %100
%102 = trunc i32 %101 to i8
%103 = load i8*, i8** %6
%104 = getelementptr inbounds i8, i8* %103, i64 -1
store i8 %102, i8* %104
%105 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%106 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %105, i32 0, i32 2
%107 = load i32, i32* %106
%108 = ashr i32 %107, 8
%109 = trunc i32 %108 to i8
%110 = load i8*, i8** %6
%111 = getelementptr inbounds i8, i8* %110, i64 -2
store i8 %109, i8* %111
%112 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%113 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %112, i32 0, i32 2
%114 = load i32, i32* %113
%115 = ashr i32 %114, 16
%116 = trunc i32 %115 to i8
%117 = load i8*, i8** %6
%118 = getelementptr inbounds i8, i8* %117, i64 -3
store i8 %116, i8* %118
%119 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%120 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %119, i32 0, i32 2
%121 = load i32, i32* %120
%122 = ashr i32 %121, 24
%123 = trunc i32 %122 to i8
%124 = load i8*, i8** %6
%125 = getelementptr inbounds i8, i8* %124, i64 -4
store i8 %123, i8* %125
%126 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%127 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %126, i32 0, i32 2
%128 = load i32, i32* %127
%129 = ashr i32 %128, 32
%130 = trunc i32 %129 to i8
%131 = load i8*, i8** %6
%132 = getelementptr inbounds i8, i8* %131, i64 -5
store i8 %130, i8* %132
%133 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%134 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %133, i32 0, i32 2
%135 = load i32, i32* %134
%136 = ashr i32 %135, 40
%137 = trunc i32 %136 to i8
%138 = load i8*, i8** %6
%139 = getelementptr inbounds i8, i8* %138, i64 -6
store i8 %137, i8* %139
%140 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%141 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %140, i32 0, i32 2
%142 = load i32, i32* %141
%143 = ashr i32 %142, 48
%144 = trunc i32 %143 to i8
%145 = load i8*, i8** %6
%146 = getelementptr inbounds i8, i8* %145, i64 -7
store i8 %144, i8* %146
%147 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%148 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %147, i32 0, i32 2
%149 = load i32, i32* %148
%150 = ashr i32 %149, 56
%151 = trunc i32 %150 to i8
%152 = load i8*, i8** %6
%153 = getelementptr inbounds i8, i8* %152, i64 -8
store i8 %151, i8* %153
%154 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%155 = load i8*, i8** %6
%156 = call i32 @sha512_block_data_order(%struct.TYPE_6__* %154, i8* %155, i32 1)
%157 = load i8*, i8** %4
%158 = icmp eq i8* %157, null
br i1 %158, label %159, label %160
159: ; preds = %36
store i32 0, i32* %3
br label %274
160: ; preds = %36
%161 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%162 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %161, i32 0, i32 3
%163 = load i32, i32* %162
switch i32 %163, label %272 [
i32 129, label %164
i32 128, label %218
]
164: ; preds = %160
store i64 0, i64* %7
br label %165
165: ; preds = %214, %164
%166 = load i64, i64* %7
%167 = icmp ult i64 %166, 16
br i1 %167, label %168, label %217
168: ; preds = %165
%169 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%170 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %169, i32 0, i32 4
%171 = load i32*, i32** %170
%172 = load i64, i64* %7
%173 = getelementptr inbounds i32, i32* %171, i64 %172
%174 = load i32, i32* %173
store i32 %174, i32* %8
%175 = load i32, i32* %8
%176 = ashr i32 %175, 56
%177 = trunc i32 %176 to i8
%178 = load i8*, i8** %4
%179 = getelementptr inbounds i8, i8* %178, i32 1
store i8* %179, i8** %4
store i8 %177, i8* %178
%180 = load i32, i32* %8
%181 = ashr i32 %180, 48
%182 = trunc i32 %181 to i8
%183 = load i8*, i8** %4
%184 = getelementptr inbounds i8, i8* %183, i32 1
store i8* %184, i8** %4
store i8 %182, i8* %183
%185 = load i32, i32* %8
%186 = ashr i32 %185, 40
%187 = trunc i32 %186 to i8
%188 = load i8*, i8** %4
%189 = getelementptr inbounds i8, i8* %188, i32 1
store i8* %189, i8** %4
store i8 %187, i8* %188
%190 = load i32, i32* %8
%191 = ashr i32 %190, 32
%192 = trunc i32 %191 to i8
%193 = load i8*, i8** %4
%194 = getelementptr inbounds i8, i8* %193, i32 1
store i8* %194, i8** %4
store i8 %192, i8* %193
%195 = load i32, i32* %8
%196 = ashr i32 %195, 24
%197 = trunc i32 %196 to i8
%198 = load i8*, i8** %4
%199 = getelementptr inbounds i8, i8* %198, i32 1
store i8* %199, i8** %4
store i8 %197, i8* %198
%200 = load i32, i32* %8
%201 = ashr i32 %200, 16
%202 = trunc i32 %201 to i8
%203 = load i8*, i8** %4
%204 = getelementptr inbounds i8, i8* %203, i32 1
store i8* %204, i8** %4
store i8 %202, i8* %203
%205 = load i32, i32* %8
%206 = ashr i32 %205, 8
%207 = trunc i32 %206 to i8
%208 = load i8*, i8** %4
%209 = getelementptr inbounds i8, i8* %208, i32 1
store i8* %209, i8** %4
store i8 %207, i8* %208
%210 = load i32, i32* %8
%211 = trunc i32 %210 to i8
%212 = load i8*, i8** %4
%213 = getelementptr inbounds i8, i8* %212, i32 1
store i8* %213, i8** %4
store i8 %211, i8* %212
br label %214
214: ; preds = %168
%215 = load i64, i64* %7
%216 = add i64 %215, 1
store i64 %216, i64* %7
br label %165
217: ; preds = %165
br label %273
218: ; preds = %160
store i64 0, i64* %7
br label %219
219: ; preds = %268, %218
%220 = load i64, i64* %7
%221 = icmp ult i64 %220, 16
br i1 %221, label %222, label %271
222: ; preds = %219
%223 = load %struct.TYPE_6__*, %struct.TYPE_6__** %5
%224 = getelementptr inbounds %struct.TYPE_6__, %struct.TYPE_6__* %223, i32 0, i32 4
%225 = load i32*, i32** %224
%226 = load i64, i64* %7
%227 = getelementptr inbounds i32, i32* %225, i64 %226
%228 = load i32, i32* %227
store i32 %228, i32* %9
%229 = load i32, i32* %9
%230 = ashr i32 %229, 56
%231 = trunc i32 %230 to i8
%232 = load i8*, i8** %4
%233 = getelementptr inbounds i8, i8* %232, i32 1
store i8* %233, i8** %4
store i8 %231, i8* %232
%234 = load i32, i32* %9
%235 = ashr i32 %234, 48
%236 = trunc i32 %235 to i8
%237 = load i8*, i8** %4
%238 = getelementptr inbounds i8, i8* %237, i32 1
store i8* %238, i8** %4
store i8 %236, i8* %237
%239 = load i32, i32* %9
%240 = ashr i32 %239, 40
%241 = trunc i32 %240 to i8
%242 = load i8*, i8** %4
%243 = getelementptr inbounds i8, i8* %242, i32 1
store i8* %243, i8** %4
store i8 %241, i8* %242
%244 = load i32, i32* %9
%245 = ashr i32 %244, 32
%246 = trunc i32 %245 to i8
%247 = load i8*, i8** %4
%248 = getelementptr inbounds i8, i8* %247, i32 1
store i8* %248, i8** %4
store i8 %246, i8* %247
%249 = load i32, i32* %9
%250 = ashr i32 %249, 24
%251 = trunc i32 %250 to i8
%252 = load i8*, i8** %4
%253 = getelementptr inbounds i8, i8* %252, i32 1
store i8* %253, i8** %4
store i8 %251, i8* %252
%254 = load i32, i32* %9
%255 = ashr i32 %254, 16
%256 = trunc i32 %255 to i8
%257 = load i8*, i8** %4
%258 = getelementptr inbounds i8, i8* %257, i32 1
store i8* %258, i8** %4
store i8 %256, i8* %257
%259 = load i32, i32* %9
%260 = ashr i32 %259, 8
%261 = trunc i32 %260 to i8
%262 = load i8*, i8** %4
%263 = getelementptr inbounds i8, i8* %262, i32 1
store i8* %263, i8** %4
store i8 %261, i8* %262
%264 = load i32, i32* %9
%265 = trunc i32 %264 to i8
%266 = load i8*, i8** %4
%267 = getelementptr inbounds i8, i8* %266, i32 1
store i8* %267, i8** %4
store i8 %265, i8* %266
br label %268
268: ; preds = %222
%269 = load i64, i64* %7
%270 = add i64 %269, 1
store i64 %270, i64* %7
br label %219
271: ; preds = %219
br label %273
272: ; preds = %160
store i32 0, i32* %3
br label %274
273: ; preds = %271, %217
store i32 1, i32* %3
br label %274
274: ; preds = %273, %272, %159
%275 = load i32, i32* %3
ret i32 %275
}

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