#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 */
int inet_addr(char *);
int sscanf(char *, char *, long *, long *, long *, long *);
int isValidIpAddr(char *ipAddr) {
  long field[4];
  if (sscanf(ipAddr, "%ld.%ld.%ld.%ld", &field[0], &field[1], &field[2],
             &field[3]) != 4)
    return 0;
  if (field[0] < 1 || field[0] > 223 || field[0] == 127 || field[1] < 0 ||
      field[1] > 255 || field[2] < 0 || field[2] > 255 || field[3] < 0 ||
      field[3] > 254)
    return 0;
  if (inet_addr(ipAddr) == -1)
    return 0;
  return 1;
}


x86 assembly (clang, -O0):
<isValidIpAddr>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
mov    -0x10(%rbp),%rdi
lea    -0x30(%rbp),%rdx
lea    -0x30(%rbp),%rcx
add    $0x8,%rcx
lea    -0x30(%rbp),%r8
add    $0x10,%r8
lea    -0x30(%rbp),%r9
add    $0x18,%r9
lea    0xead(%rip),%rsi
call   1040 <sscanf@plt>
cmp    $0x4,%eax
je     116d <isValidIpAddr+0x4d>
movl   $0x0,-0x4(%rbp)
jmp    120d <isValidIpAddr+0xed>
cmpq   $0x1,-0x30(%rbp)
jl     11dc <isValidIpAddr+0xbc>
cmpq   $0xdf,-0x30(%rbp)
jg     11dc <isValidIpAddr+0xbc>
cmpq   $0x7f,-0x30(%rbp)
je     11dc <isValidIpAddr+0xbc>
cmpq   $0x0,-0x28(%rbp)
jl     11dc <isValidIpAddr+0xbc>
cmpq   $0xff,-0x28(%rbp)
jg     11dc <isValidIpAddr+0xbc>
cmpq   $0x0,-0x20(%rbp)
jl     11dc <isValidIpAddr+0xbc>
cmpq   $0xff,-0x20(%rbp)
jg     11dc <isValidIpAddr+0xbc>
cmpq   $0x0,-0x18(%rbp)
jl     11dc <isValidIpAddr+0xbc>
cmpq   $0xfe,-0x18(%rbp)
jle    11e8 <isValidIpAddr+0xc8>
movl   $0x0,-0x4(%rbp)
jmp    120d <isValidIpAddr+0xed>
mov    -0x10(%rbp),%rdi
call   1030 <inet_addr@plt>
cmp    $0xffffffff,%eax
jne    1206 <isValidIpAddr+0xe6>
movl   $0x0,-0x4(%rbp)
jmp    120d <isValidIpAddr+0xed>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<isValidIpAddr>:
push   %rbx
sub    $0x20,%rsp
mov    %rdi,%rbx
lea    0x8(%rsp),%rcx
lea    0x10(%rsp),%r8
lea    0x18(%rsp),%r9
lea    0xec2(%rip),%rsi
mov    %rsp,%rdx
call   1040 <sscanf@plt>
mov    %eax,%ecx
xor    %eax,%eax
cmp    $0x4,%ecx
jne    11b4 <isValidIpAddr+0x94>
mov    (%rsp),%rcx
cmp    $0x7f,%rcx
je     11b4 <isValidIpAddr+0x94>
add    $0xffffffffffffff20,%rcx
cmp    $0xffffffffffffff21,%rcx
jb     11b4 <isValidIpAddr+0x94>
mov    0x8(%rsp),%rcx
test   %rcx,%rcx
js     11b4 <isValidIpAddr+0x94>
cmp    $0xff,%rcx
jg     11b4 <isValidIpAddr+0x94>
mov    0x10(%rsp),%rcx
test   %rcx,%rcx
js     11b4 <isValidIpAddr+0x94>
cmp    $0xff,%rcx
jg     11b4 <isValidIpAddr+0x94>
mov    0x18(%rsp),%rcx
test   %rcx,%rcx
js     11b4 <isValidIpAddr+0x94>
cmp    $0xfe,%rcx
jg     11b4 <isValidIpAddr+0x94>
mov    %rbx,%rdi
call   1030 <inet_addr@plt>
mov    %eax,%ecx
xor    %eax,%eax
cmp    $0xffffffff,%ecx
setne  %al
add    $0x20,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@.str = [16 x i8] c"%ld.%ld.%ld.%ld\00"
define i32 @isValidIpAddr(i8* %0) {
%2 = alloca i32
%3 = alloca i8*
%4 = alloca [4 x i64]
store i8* %0, i8** %3
%5 = load i8*, i8** %3
%6 = getelementptr inbounds [4 x i64], [4 x i64]* %4, i64 0, i64 0
%7 = getelementptr inbounds [4 x i64], [4 x i64]* %4, i64 0, i64 1
%8 = getelementptr inbounds [4 x i64], [4 x i64]* %4, i64 0, i64 2
%9 = getelementptr inbounds [4 x i64], [4 x i64]* %4, i64 0, i64 3
%10 = call i32 @sscanf(i8* %5, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str, i64 0, i64 0), i64* %6, i64* %7, i64* %8, i64* %9)
%11 = icmp ne i32 %10, 4
br i1 %11, label %12, label %13
12: ; preds = %1
store i32 0, i32* %2
br label %56
13: ; preds = %1
%14 = getelementptr inbounds [4 x i64], [4 x i64]* %4, i64 0, i64 0
%15 = load i64, i64* %14
%16 = icmp slt i64 %15, 1
br i1 %16, label %49, label %17
17: ; preds = %13
%18 = getelementptr inbounds [4 x i64], [4 x i64]* %4, i64 0, i64 0
%19 = load i64, i64* %18
%20 = icmp sgt i64 %19, 223
br i1 %20, label %49, label %21
21: ; preds = %17
%22 = getelementptr inbounds [4 x i64], [4 x i64]* %4, i64 0, i64 0
%23 = load i64, i64* %22
%24 = icmp eq i64 %23, 127
br i1 %24, label %49, label %25
25: ; preds = %21
%26 = getelementptr inbounds [4 x i64], [4 x i64]* %4, i64 0, i64 1
%27 = load i64, i64* %26
%28 = icmp slt i64 %27, 0
br i1 %28, label %49, label %29
29: ; preds = %25
%30 = getelementptr inbounds [4 x i64], [4 x i64]* %4, i64 0, i64 1
%31 = load i64, i64* %30
%32 = icmp sgt i64 %31, 255
br i1 %32, label %49, label %33
33: ; preds = %29
%34 = getelementptr inbounds [4 x i64], [4 x i64]* %4, i64 0, i64 2
%35 = load i64, i64* %34
%36 = icmp slt i64 %35, 0
br i1 %36, label %49, label %37
37: ; preds = %33
%38 = getelementptr inbounds [4 x i64], [4 x i64]* %4, i64 0, i64 2
%39 = load i64, i64* %38
%40 = icmp sgt i64 %39, 255
br i1 %40, label %49, label %41
41: ; preds = %37
%42 = getelementptr inbounds [4 x i64], [4 x i64]* %4, i64 0, i64 3
%43 = load i64, i64* %42
%44 = icmp slt i64 %43, 0
br i1 %44, label %49, label %45
45: ; preds = %41
%46 = getelementptr inbounds [4 x i64], [4 x i64]* %4, i64 0, i64 3
%47 = load i64, i64* %46
%48 = icmp sgt i64 %47, 254
br i1 %48, label %49, label %50
49: ; preds = %45, %41, %37, %33, %29, %25, %21, %17, %13
store i32 0, i32* %2
br label %56
50: ; preds = %45
%51 = load i8*, i8** %3
%52 = call i32 @inet_addr(i8* %51)
%53 = icmp eq i32 %52, -1
br i1 %53, label %54, label %55
54: ; preds = %50
store i32 0, i32* %2
br label %56
55: ; preds = %50
store i32 1, i32* %2
br label %56
56: ; preds = %55, %54, %49, %12
%57 = load i32, i32* %2
ret i32 %57
}

LLVM IR (-O2):
@.str = [16 x i8] c"%ld.%ld.%ld.%ld\00"
define i32 @isValidIpAddr(i8* %0) {
%2 = alloca [4 x i64]
%3 = bitcast [4 x i64]* %2 to i8*
%4 = getelementptr inbounds [4 x i64], [4 x i64]* %2, i64 0, i64 0
%5 = getelementptr inbounds [4 x i64], [4 x i64]* %2, i64 0, i64 1
%6 = getelementptr inbounds [4 x i64], [4 x i64]* %2, i64 0, i64 2
%7 = getelementptr inbounds [4 x i64], [4 x i64]* %2, i64 0, i64 3
%8 = call i32 @sscanf(i8* %0, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str, i64 0, i64 0), i64* %4, i64* %5, i64* %6, i64* %7)
%9 = icmp eq i32 %8, 4
br i1 %9, label %10, label %35
10: ; preds = %1
%11 = load i64, i64* %4
%12 = add i64 %11, -224
%13 = icmp ult i64 %12, -223
%14 = icmp eq i64 %11, 127
%15 = or i1 %14, %13
%16 = load i64, i64* %5
%17 = icmp slt i64 %16, 0
%18 = select i1 %15, i1 true, i1 %17
%19 = icmp sgt i64 %16, 255
%20 = select i1 %18, i1 true, i1 %19
%21 = load i64, i64* %6
%22 = icmp slt i64 %21, 0
%23 = select i1 %20, i1 true, i1 %22
%24 = icmp sgt i64 %21, 255
%25 = select i1 %23, i1 true, i1 %24
%26 = load i64, i64* %7
%27 = icmp slt i64 %26, 0
%28 = select i1 %25, i1 true, i1 %27
%29 = icmp sgt i64 %26, 254
%30 = select i1 %28, i1 true, i1 %29
br i1 %30, label %35, label %31
31: ; preds = %10
%32 = call i32 @inet_addr(i8* %0)
%33 = icmp ne i32 %32, -1
%34 = zext i1 %33 to i32
br label %35
35: ; preds = %31, %10, %1
%36 = phi i32 [ 0, %1 ], [ 0, %10 ], [ %34, %31 ]
ret i32 %36
}