#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 */
char *mmGetPtr(char *, char);
int /*<<< orphan*/ mmGrowShm(char *, char, int);
char *strchr(char *, char);
int /*<<< orphan*/ strcmp(char *, char *);
int /*<<< orphan*/ strcpy(char *, char *);
int strlen(char *);
int mmAddEntry(char *path, char key, char *type, char *value) {
  char *shmptr = mmGetPtr(path, key);
  int addSize = strlen(type) + strlen(value) + sizeof(int) + 2;
  int size = *(int *)shmptr - sizeof(int);
  shmptr += sizeof(int);
  while (size >= addSize) {
    if (*(int *)shmptr == 0) {
      break;
    } else {
      if (!strcmp(shmptr + sizeof(int), "u")) {
        if (*(int *)shmptr >= addSize)
          break;
        else {
          size -= *(int *)shmptr;
          shmptr += *(int *)shmptr;
        }
      } else {
        size -= *(int *)shmptr;
        shmptr += *(int *)shmptr;
      }
    }
  }
  if (size >= addSize) {
    if (*(int *)shmptr == 0) {
      *(int *)shmptr = addSize;
    }
    shmptr += sizeof(int);
    strcpy(shmptr, type);
    shmptr = strchr(shmptr, '\0') + 1;
    strcpy(shmptr, value);
  } else {
    mmGrowShm(path, key, addSize);
    mmAddEntry(path, key, type, value);
  }
  return 1;
}


x86 assembly (clang, -O0):
<mmAddEntry>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %sil,%al
mov    %rdi,-0x8(%rbp)
mov    %al,-0x9(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    -0x8(%rbp),%rdi
movsbl -0x9(%rbp),%esi
call   1090 <mmGetPtr@plt>
mov    %rax,-0x28(%rbp)
mov    -0x18(%rbp),%rdi
call   1040 <strlen@plt>
mov    %eax,-0x34(%rbp)
mov    -0x20(%rbp),%rdi
call   1040 <strlen@plt>
mov    %eax,%ecx
mov    -0x34(%rbp),%eax
add    %ecx,%eax
cltq
add    $0x4,%rax
add    $0x2,%rax
mov    %eax,-0x2c(%rbp)
mov    -0x28(%rbp),%rax
movslq (%rax),%rax
sub    $0x4,%rax
mov    %eax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x28(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jl     1280 <mmAddEntry+0x110>
mov    -0x28(%rbp),%rax
cmpl   $0x0,(%rax)
jne    11fc <mmAddEntry+0x8c>
jmp    1280 <mmAddEntry+0x110>
mov    -0x28(%rbp),%rdi
add    $0x4,%rdi
lea    0xdf5(%rip),%rsi
call   1070 <strcmp@plt>
cmp    $0x0,%eax
jne    1254 <mmAddEntry+0xe4>
mov    -0x28(%rbp),%rax
mov    (%rax),%eax
cmp    -0x2c(%rbp),%eax
jl     122d <mmAddEntry+0xbd>
jmp    1280 <mmAddEntry+0x110>
mov    -0x28(%rbp),%rax
mov    (%rax),%ecx
mov    -0x30(%rbp),%eax
sub    %ecx,%eax
mov    %eax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
mov    (%rax),%ecx
mov    -0x28(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x28(%rbp)
jmp    1276 <mmAddEntry+0x106>
mov    -0x28(%rbp),%rax
mov    (%rax),%ecx
mov    -0x30(%rbp),%eax
sub    %ecx,%eax
mov    %eax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
mov    (%rax),%ecx
mov    -0x28(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x28(%rbp)
jmp    127b <mmAddEntry+0x10b>
jmp    11de <mmAddEntry+0x6e>
mov    -0x30(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jl     12e0 <mmAddEntry+0x170>
mov    -0x28(%rbp),%rax
cmpl   $0x0,(%rax)
jne    12a2 <mmAddEntry+0x132>
mov    -0x2c(%rbp),%ecx
mov    -0x28(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x28(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1030 <strcpy@plt>
mov    -0x28(%rbp),%rdi
xor    %esi,%esi
call   1050 <strchr@plt>
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rdi
mov    -0x20(%rbp),%rsi
call   1030 <strcpy@plt>
jmp    1309 <mmAddEntry+0x199>
mov    -0x8(%rbp),%rdi
mov    -0x9(%rbp),%al
mov    -0x2c(%rbp),%edx
movsbl %al,%esi
call   1080 <mmGrowShm@plt>
mov    -0x8(%rbp),%rdi
mov    -0x9(%rbp),%al
mov    -0x18(%rbp),%rdx
mov    -0x20(%rbp),%rcx
movsbl %al,%esi
call   1060 <mmAddEntry@plt>
mov    $0x1,%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<mmAddEntry>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
mov    %rcx,%r12
mov    %rdx,%rbx
mov    %rdi,%rbp
movsbl %sil,%esi
lea    0xe8e(%rip),%r15
mov    %rcx,0x8(%rsp)
mov    %rdi,0x10(%rsp)
mov    %esi,0x4(%rsp)
jmp    11b0 <mmAddEntry+0x60>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mov    0x10(%rsp),%rbp
mov    %rbp,%rdi
mov    0x4(%rsp),%ebx
mov    %ebx,%esi
mov    %r14d,%edx
call   1060 <mmGrowShm@plt>
mov    %ebx,%esi
mov    0x8(%rsp),%r12
mov    %r13,%rbx
mov    %rbp,%rdi
call   1070 <mmGetPtr@plt>
mov    %rax,%rbp
mov    %rbx,%r13
mov    %rbx,%rdi
call   1040 <strlen@plt>
mov    %eax,%r14d
mov    %r12,%rdi
call   1040 <strlen@plt>
add    %eax,%r14d
add    $0x6,%r14d
mov    0x0(%rbp),%ebx
add    $0xfffffffc,%ebx
cmp    %r14d,%ebx
jl     1190 <mmAddEntry+0x40>
add    $0x4,%rbp
jmp    11fb <mmAddEntry+0xab>
nopl   0x0(%rax)
sub    %r12d,%ebx
add    %r12,%rbp
cmp    %r14d,%ebx
jl     1190 <mmAddEntry+0x40>
movslq 0x0(%rbp),%r12
test   %r12,%r12
je     121b <mmAddEntry+0xcb>
lea    0x4(%rbp),%rdi
mov    %r15,%rsi
call   1050 <strcmp@plt>
test   %eax,%eax
jne    11f0 <mmAddEntry+0xa0>
cmp    %r14d,%r12d
jl     11f0 <mmAddEntry+0xa0>
jmp    121f <mmAddEntry+0xcf>
mov    %r14d,0x0(%rbp)
lea    0x4(%rbp),%rbx
mov    %rbx,%rdi
mov    %r13,%rsi
call   1030 <strcpy@plt>
mov    %rbx,%rdi
call   1040 <strlen@plt>
lea    (%rax,%rbp,1),%rdi
add    $0x5,%rdi
mov    0x8(%rsp),%rsi
call   1030 <strcpy@plt>
mov    $0x1,%eax
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
@.str = [2 x i8] c"u\00"
define i32 @mmAddEntry(i8* %0, i8 signext %1, i8* %2, i8* %3) {
br label %5
5: ; preds = %43, %4
%6 = tail call i8* @mmGetPtr(i8* %0, i8 signext %1)
%7 = tail call i32 @strlen(i8* %2)
%8 = tail call i32 @strlen(i8* %3)
%9 = add i32 %7, 6
%10 = add i32 %9, %8
%11 = bitcast i8* %6 to i32*
%12 = load i32, i32* %11
%13 = add i32 %12, -4
%14 = icmp slt i32 %13, %10
br i1 %14, label %43, label %15
15: ; preds = %5
%16 = getelementptr inbounds i8, i8* %6, i64 4
br label %17
17: ; preds = %15, %29
%18 = phi i32 [ %30, %29 ], [ %13, %15 ]
%19 = phi i8* [ %32, %29 ], [ %16, %15 ]
%20 = bitcast i8* %19 to i32*
%21 = load i32, i32* %20
%22 = icmp eq i32 %21, 0
br i1 %22, label %34, label %23
23: ; preds = %17
%24 = getelementptr inbounds i8, i8* %19, i64 4
%25 = tail call i32 @strcmp(i8* %24, i8* dereferenceable(2) getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%26 = icmp ne i32 %25, 0
%27 = icmp slt i32 %21, %10
%28 = select i1 %26, i1 true, i1 %27
br i1 %28, label %29, label %36
29: ; preds = %23
%30 = sub nsw i32 %18, %21
%31 = sext i32 %21 to i64
%32 = getelementptr inbounds i8, i8* %19, i64 %31
%33 = icmp slt i32 %30, %10
br i1 %33, label %43, label %17
34: ; preds = %17
%35 = bitcast i8* %19 to i32*
store i32 %10, i32* %35
br label %36
36: ; preds = %23, %34
%37 = getelementptr inbounds i8, i8* %19, i64 4
%38 = tail call i32 @strcpy(i8* %37, i8* %2)
%39 = tail call i64 bitcast (i32 (i8*)* @strlen to i64 (i8*)*)(i8* %37)
%40 = getelementptr i8, i8* %37, i64 %39
%41 = getelementptr inbounds i8, i8* %40, i64 1
%42 = tail call i32 @strcpy(i8* %41, i8* %3)
ret i32 1
43: ; preds = %29, %5
%44 = tail call i32 @mmGrowShm(i8* %0, i8 signext %1, i32 %10)
br label %5
}