#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*/ FILE;

/* Variables and functions */
scalar_t__ errno;
int /*<<< orphan*/ print_special(unsigned char const *, char *,
                                 int /*<<< orphan*/ *);
double strtod(char *, char **);
long strtol(char *, char **, int);
void print_string(const unsigned char *s, FILE *out) {
  long i;
  double f;
  char *end;
  errno = 0;
  f = strtod((char *)s, &end);
  if ((f != 0 || !errno) && *end == 0) {
    print_special(s, 0, out);
    return;
  }
  errno = 0;
  i = strtol((char *)s, &end, 10);
  if ((i != 0 || !errno) && *end == 0) {
    print_special(s, 0, out);
    return;
  }
  print_special(s, "\", \f\n\r\t\v", out);
}


x86 assembly (clang, -O0):
<print_string>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    0x2e99(%rip),%rax
movq   $0x0,(%rax)
mov    -0x8(%rbp),%rdi
lea    -0x28(%rbp),%rsi
call   1030 <strtod@plt>
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1189 <print_string+0x59>
jp     1189 <print_string+0x59>
mov    0x2e61(%rip),%rax
cmpq   $0x0,(%rax)
jne    11af <print_string+0x7f>
mov    -0x28(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
jne    11af <print_string+0x7f>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rdx
xor    %eax,%eax
mov    %eax,%esi
call   1050 <print_special@plt>
jmp    1229 <print_string+0xf9>
mov    0x2e2a(%rip),%rax
movq   $0x0,(%rax)
mov    -0x8(%rbp),%rdi
lea    -0x28(%rbp),%rsi
mov    $0xa,%edx
call   1040 <strtol@plt>
mov    %rax,-0x18(%rbp)
cmpq   $0x0,-0x18(%rbp)
jne    11ef <print_string+0xbf>
mov    0x2dfb(%rip),%rax
cmpq   $0x0,(%rax)
jne    1215 <print_string+0xe5>
mov    -0x28(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
jne    1215 <print_string+0xe5>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rdx
xor    %eax,%eax
mov    %eax,%esi
call   1050 <print_special@plt>
jmp    1229 <print_string+0xf9>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rdx
lea    0xddc(%rip),%rsi
call   1050 <print_special@plt>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<print_string>:
push   %r15
push   %r14
push   %rbx
sub    $0x10,%rsp
mov    %rsi,%r14
mov    %rdi,%rbx
mov    0x2e9a(%rip),%r15
movq   $0x0,(%r15)
lea    0x8(%rsp),%rsi
call   1030 <strtod@plt>
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1169 <print_string+0x39>
jp     1169 <print_string+0x39>
cmpq   $0x0,(%r15)
jne    1173 <print_string+0x43>
mov    0x8(%rsp),%rax
cmpb   $0x0,(%rax)
je     11aa <print_string+0x7a>
movq   $0x0,(%r15)
lea    0x8(%rsp),%rsi
mov    %rbx,%rdi
mov    $0xa,%edx
call   1040 <strtol@plt>
test   %rax,%rax
jne    1197 <print_string+0x67>
cmpq   $0x0,(%r15)
jne    11a1 <print_string+0x71>
mov    0x8(%rsp),%rax
cmpb   $0x0,(%rax)
je     11aa <print_string+0x7a>
lea    0xe58(%rip),%rsi
jmp    11ac <print_string+0x7c>
xor    %esi,%esi
mov    %rbx,%rdi
mov    %r14,%rdx
add    $0x10,%rsp
pop    %rbx
pop    %r14
pop    %r15
jmp    1050 <print_special@plt>

LLVM IR (-O0):
@errno = global i64 0
@.str = [9 x i8] c"\22, \0C\0A\0D\09\0B\00"
define void @print_string(i8* %0, i32* %1) {
%3 = alloca i8*
%4 = alloca i32*
%5 = alloca i64
%6 = alloca double
%7 = alloca i8*
store i8* %0, i8** %3
store i32* %1, i32** %4
store i64 0, i64* @errno
%8 = load i8*, i8** %3
%9 = call double @strtod(i8* %8, i8** %7)
store double %9, double* %6
%10 = load double, double* %6
%11 = fcmp une double %10, 0.000000e+00
br i1 %11, label %15, label %12
12: ; preds = %2
%13 = load i64, i64* @errno
%14 = icmp ne i64 %13, 0
br i1 %14, label %24, label %15
15: ; preds = %12, %2
%16 = load i8*, i8** %7
%17 = load i8, i8* %16
%18 = sext i8 %17 to i32
%19 = icmp eq i32 %18, 0
br i1 %19, label %20, label %24
20: ; preds = %15
%21 = load i8*, i8** %3
%22 = load i32*, i32** %4
%23 = call i32 @print_special(i8* %21, i8* null, i32* %22)
br label %45
24: ; preds = %15, %12
store i64 0, i64* @errno
%25 = load i8*, i8** %3
%26 = call i64 @strtol(i8* %25, i8** %7, i32 10)
store i64 %26, i64* %5
%27 = load i64, i64* %5
%28 = icmp ne i64 %27, 0
br i1 %28, label %32, label %29
29: ; preds = %24
%30 = load i64, i64* @errno
%31 = icmp ne i64 %30, 0
br i1 %31, label %41, label %32
32: ; preds = %29, %24
%33 = load i8*, i8** %7
%34 = load i8, i8* %33
%35 = sext i8 %34 to i32
%36 = icmp eq i32 %35, 0
br i1 %36, label %37, label %41
37: ; preds = %32
%38 = load i8*, i8** %3
%39 = load i32*, i32** %4
%40 = call i32 @print_special(i8* %38, i8* null, i32* %39)
br label %45
41: ; preds = %32, %29
%42 = load i8*, i8** %3
%43 = load i32*, i32** %4
%44 = call i32 @print_special(i8* %42, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0), i32* %43)
br label %45
45: ; preds = %41, %37, %20
ret void
}

LLVM IR (-O2):
@errno = global i64 0
@.str = [9 x i8] c"\22, \0C\0A\0D\09\0B\00"
define void @print_string(i8* %0, i32* %1) {
%3 = alloca i8*
%4 = bitcast i8** %3 to i8*
store i64 0, i64* @errno
%5 = call double @strtod(i8* %0, i8** %3)
%6 = fcmp oeq double %5, 0.000000e+00
%7 = load i64, i64* @errno
%8 = icmp ne i64 %7, 0
%9 = select i1 %6, i1 %8, i1 false
br i1 %9, label %14, label %10
10: ; preds = %2
%11 = load i8*, i8** %3
%12 = load i8, i8* %11
%13 = icmp eq i8 %12, 0
br i1 %13, label %25, label %14
14: ; preds = %2, %10
store i64 0, i64* @errno
%15 = call i64 @strtol(i8* %0, i8** %3, i32 10)
%16 = icmp eq i64 %15, 0
%17 = load i64, i64* @errno
%18 = icmp ne i64 %17, 0
%19 = select i1 %16, i1 %18, i1 false
br i1 %19, label %24, label %20
20: ; preds = %14
%21 = load i8*, i8** %3
%22 = load i8, i8* %21
%23 = icmp eq i8 %22, 0
br i1 %23, label %25, label %24
24: ; preds = %14, %20
br label %25
25: ; preds = %20, %10, %24
%26 = phi i8* [ getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0), %24 ], [ null, %10 ], [ null, %20 ]
%27 = tail call i32 @print_special(i8* %0, i8* %26, i32* %1)
ret void
}