#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 */
struct lconv {
  char *decimal_point;
  char *thousands_sep;
  char *grouping;
  char *int_curr_symbol;
  char *currency_symbol;
  char *mon_decimal_point;
  char *mon_thousands_sep;
  char *mon_grouping;
  char *positive_sign;
  char *negative_sign;
};

/* Variables and functions */
struct lconv *malloc(int);
int /*<<< orphan*/ memset(struct lconv *, int, int);
struct lconv *localeconv(void) {
  static struct lconv *posix_lconv;
  if (posix_lconv)
    return posix_lconv;
  posix_lconv = malloc(sizeof *posix_lconv);
  memset(posix_lconv, -1, sizeof *posix_lconv);
  posix_lconv->decimal_point = ".";
  posix_lconv->thousands_sep = "";
  posix_lconv->grouping = "\xff";
  posix_lconv->int_curr_symbol = "";
  posix_lconv->currency_symbol = "";
  posix_lconv->mon_decimal_point = "";
  posix_lconv->mon_thousands_sep = "";
  posix_lconv->mon_grouping = "\xff";
  posix_lconv->positive_sign = "";
  posix_lconv->negative_sign = "";
  return posix_lconv;
}


x86 assembly (clang, -O0):
<localeconv>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
cmpq   $0x0,0x2f08(%rip)
je     1146 <localeconv+0x26>
mov    0x2efb(%rip),%rax
mov    %rax,-0x8(%rbp)
jmp    122b <localeconv+0x10b>
mov    $0x50,%edi
call   1040 <malloc@plt>
mov    %rax,0x2ee1(%rip)
mov    0x2eda(%rip),%rdi
mov    $0xffffffff,%esi
mov    $0x50,%edx
call   1030 <memset@plt>
mov    0x2ec4(%rip),%rax
lea    0xe85(%rip),%rcx
mov    %rcx,(%rax)
mov    0x2eb3(%rip),%rax
lea    0xe75(%rip),%rcx
mov    %rcx,0x8(%rax)
mov    0x2ea1(%rip),%rax
lea    0xe64(%rip),%rcx
mov    %rcx,0x10(%rax)
mov    0x2e8f(%rip),%rax
lea    0xe51(%rip),%rcx
mov    %rcx,0x18(%rax)
mov    0x2e7d(%rip),%rax
lea    0xe3f(%rip),%rcx
mov    %rcx,0x20(%rax)
mov    0x2e6b(%rip),%rax
lea    0xe2d(%rip),%rcx
mov    %rcx,0x28(%rax)
mov    0x2e59(%rip),%rax
lea    0xe1b(%rip),%rcx
mov    %rcx,0x30(%rax)
mov    0x2e47(%rip),%rax
lea    0xe0a(%rip),%rcx
mov    %rcx,0x38(%rax)
mov    0x2e35(%rip),%rax
lea    0xdf7(%rip),%rcx
mov    %rcx,0x40(%rax)
mov    0x2e23(%rip),%rax
lea    0xde5(%rip),%rcx
mov    %rcx,0x48(%rax)
mov    0x2e11(%rip),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<localeconv>:
push   %rax
mov    0x2f10(%rip),%rax
test   %rax,%rax
je     112f <localeconv+0xf>
pop    %rcx
ret
mov    $0x50,%edi
call   1040 <malloc@plt>
mov    %rax,0x2ef8(%rip)
mov    %rax,%rdi
mov    $0xffffffff,%esi
mov    $0x50,%edx
call   1030 <memset@plt>
mov    0x2edf(%rip),%rax
lea    0xea0(%rip),%rcx
mov    %rcx,(%rax)
lea    0xe97(%rip),%rcx
mov    %rcx,0x8(%rax)
lea    0xe8d(%rip),%rdx
mov    %rdx,0x10(%rax)
mov    %rcx,0x18(%rax)
mov    %rcx,0x20(%rax)
mov    %rcx,0x28(%rax)
mov    %rcx,0x30(%rax)
mov    %rdx,0x38(%rax)
mov    %rcx,0x40(%rax)
mov    %rcx,0x48(%rax)
pop    %rcx
ret

LLVM IR (-O0):
%struct.lconv = type { i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8* }
@localeconv.posix_lconv = internal global %struct.lconv* null
@.str = [2 x i8] c".\00"
@.str.1 = [1 x i8] zeroinitializer
@.str.2 = [2 x i8] c"\FF\00"
define %struct.lconv* @localeconv() {
%1 = alloca %struct.lconv*
%2 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
%3 = icmp ne %struct.lconv* %2, null
br i1 %3, label %4, label %6
4: ; preds = %0
%5 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
store %struct.lconv* %5, %struct.lconv** %1
br label %31
6: ; preds = %0
%7 = call %struct.lconv* @malloc(i32 80)
store %struct.lconv* %7, %struct.lconv** @localeconv.posix_lconv
%8 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
%9 = call i32 @memset(%struct.lconv* %8, i32 -1, i32 80)
%10 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
%11 = getelementptr inbounds %struct.lconv, %struct.lconv* %10, i32 0, i32 0
store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0), i8** %11
%12 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
%13 = getelementptr inbounds %struct.lconv, %struct.lconv* %12, i32 0, i32 1
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.1, i64 0, i64 0), i8** %13
%14 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
%15 = getelementptr inbounds %struct.lconv, %struct.lconv* %14, i32 0, i32 2
store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.2, i64 0, i64 0), i8** %15
%16 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
%17 = getelementptr inbounds %struct.lconv, %struct.lconv* %16, i32 0, i32 3
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.1, i64 0, i64 0), i8** %17
%18 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
%19 = getelementptr inbounds %struct.lconv, %struct.lconv* %18, i32 0, i32 4
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.1, i64 0, i64 0), i8** %19
%20 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
%21 = getelementptr inbounds %struct.lconv, %struct.lconv* %20, i32 0, i32 5
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.1, i64 0, i64 0), i8** %21
%22 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
%23 = getelementptr inbounds %struct.lconv, %struct.lconv* %22, i32 0, i32 6
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.1, i64 0, i64 0), i8** %23
%24 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
%25 = getelementptr inbounds %struct.lconv, %struct.lconv* %24, i32 0, i32 7
store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.2, i64 0, i64 0), i8** %25
%26 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
%27 = getelementptr inbounds %struct.lconv, %struct.lconv* %26, i32 0, i32 8
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.1, i64 0, i64 0), i8** %27
%28 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
%29 = getelementptr inbounds %struct.lconv, %struct.lconv* %28, i32 0, i32 9
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.1, i64 0, i64 0), i8** %29
%30 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
store %struct.lconv* %30, %struct.lconv** %1
br label %31
31: ; preds = %6, %4
%32 = load %struct.lconv*, %struct.lconv** %1
ret %struct.lconv* %32
}

LLVM IR (-O2):
%struct.lconv = type { i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8* }
@localeconv.posix_lconv = internal unnamed_addr global %struct.lconv* null
@.str = [2 x i8] c".\00"
@.str.1 = [1 x i8] zeroinitializer
@.str.2 = [2 x i8] c"\FF\00"
define %struct.lconv* @localeconv() {
%1 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
%2 = icmp eq %struct.lconv* %1, null
br i1 %2, label %3, label %17
3: ; preds = %0
%4 = tail call %struct.lconv* @malloc(i32 80)
store %struct.lconv* %4, %struct.lconv** @localeconv.posix_lconv
%5 = tail call i32 @memset(%struct.lconv* %4, i32 -1, i32 80)
%6 = load %struct.lconv*, %struct.lconv** @localeconv.posix_lconv
%7 = getelementptr inbounds %struct.lconv, %struct.lconv* %6, i64 0, i32 0
store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0), i8** %7
%8 = getelementptr inbounds %struct.lconv, %struct.lconv* %6, i64 0, i32 1
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.1, i64 0, i64 0), i8** %8
%9 = getelementptr inbounds %struct.lconv, %struct.lconv* %6, i64 0, i32 2
store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.2, i64 0, i64 0), i8** %9
%10 = getelementptr inbounds %struct.lconv, %struct.lconv* %6, i64 0, i32 3
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.1, i64 0, i64 0), i8** %10
%11 = getelementptr inbounds %struct.lconv, %struct.lconv* %6, i64 0, i32 4
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.1, i64 0, i64 0), i8** %11
%12 = getelementptr inbounds %struct.lconv, %struct.lconv* %6, i64 0, i32 5
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.1, i64 0, i64 0), i8** %12
%13 = getelementptr inbounds %struct.lconv, %struct.lconv* %6, i64 0, i32 6
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.1, i64 0, i64 0), i8** %13
%14 = getelementptr inbounds %struct.lconv, %struct.lconv* %6, i64 0, i32 7
store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.2, i64 0, i64 0), i8** %14
%15 = getelementptr inbounds %struct.lconv, %struct.lconv* %6, i64 0, i32 8
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.1, i64 0, i64 0), i8** %15
%16 = getelementptr inbounds %struct.lconv, %struct.lconv* %6, i64 0, i32 9
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.1, i64 0, i64 0), i8** %16
br label %17
17: ; preds = %0, %3
%18 = phi %struct.lconv* [ %6, %3 ], [ %1, %0 ]
ret %struct.lconv* %18
}