#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 */
scalar_t__ isxdigit(char);
char toupper(char);
void decode_string(char *s) {
  char *t = s;
  char *h = s;
  for (; *h; h++, t++) {
    if (*h != '%') {
    copychar:
      *t = *h;
    } else {
      if (!*(h + 1) || !*(h + 2) || !(isxdigit(*(h + 1)) && isxdigit(*(h + 2))))
        goto copychar;
      *t = ((((*(h + 1)) >= '0' && (*(h + 1)) <= '9')
                 ? ((*(h + 1)) - '0')
                 : (toupper(*(h + 1)) - 'A' + 10))
            << 4) +
           (((*(h + 2)) >= '0' && (*(h + 2)) <= '9')
                ? ((*(h + 2)) - '0')
                : (toupper(*(h + 2)) - 'A' + 10));
      h += 2;
    }
  }
  *t = '\0';
}


x86 assembly (clang, -O0):
<decode_string>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
cmpb   $0x0,(%rax)
je     12a1 <decode_string+0x181>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x25,%eax
je     116f <decode_string+0x4f>
jmp    115e <decode_string+0x3e>
mov    -0x18(%rbp),%rax
mov    (%rax),%cl
mov    -0x10(%rbp),%rax
mov    %cl,(%rax)
jmp    127f <decode_string+0x15f>
mov    -0x18(%rbp),%rax
cmpb   $0x0,0x1(%rax)
je     11b9 <decode_string+0x99>
mov    -0x18(%rbp),%rax
cmpb   $0x0,0x2(%rax)
je     11b9 <decode_string+0x99>
mov    -0x18(%rbp),%rax
movsbl 0x1(%rax),%edi
call   1040 <isxdigit@plt>
cmp    $0x0,%rax
je     11b9 <decode_string+0x99>
mov    -0x18(%rbp),%rax
movsbl 0x2(%rax),%edi
call   1040 <isxdigit@plt>
cmp    $0x0,%rax
jne    11be <decode_string+0x9e>
jmp    115e <decode_string+0x3e>
mov    -0x18(%rbp),%rax
movsbl 0x1(%rax),%eax
cmp    $0x30,%eax
jl     11f3 <decode_string+0xd3>
mov    -0x18(%rbp),%rax
movsbl 0x1(%rax),%eax
cmp    $0x39,%eax
jg     11f3 <decode_string+0xd3>
mov    -0x18(%rbp),%rax
movsbl 0x1(%rax),%eax
sub    $0x30,%eax
mov    %eax,-0x1c(%rbp)
jmp    120c <decode_string+0xec>
mov    -0x18(%rbp),%rax
movsbl 0x1(%rax),%edi
call   1030 <toupper@plt>
movsbl %al,%eax
sub    $0x41,%eax
add    $0xa,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
shl    $0x4,%eax
mov    %eax,-0x20(%rbp)
mov    -0x18(%rbp),%rax
movsbl 0x2(%rax),%eax
cmp    $0x30,%eax
jl     124a <decode_string+0x12a>
mov    -0x18(%rbp),%rax
movsbl 0x2(%rax),%eax
cmp    $0x39,%eax
jg     124a <decode_string+0x12a>
mov    -0x18(%rbp),%rax
movsbl 0x2(%rax),%eax
sub    $0x30,%eax
mov    %eax,-0x24(%rbp)
jmp    1263 <decode_string+0x143>
mov    -0x18(%rbp),%rax
movsbl 0x2(%rax),%edi
call   1030 <toupper@plt>
movsbl %al,%eax
sub    $0x41,%eax
add    $0xa,%eax
mov    %eax,-0x24(%rbp)
mov    -0x20(%rbp),%eax
mov    -0x24(%rbp),%ecx
add    %ecx,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,(%rax)
mov    -0x18(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x18(%rbp)
jmp    1284 <decode_string+0x164>
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    113c <decode_string+0x1c>
mov    -0x10(%rbp),%rax
movb   $0x0,(%rax)
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<decode_string>:
push   %rbp
push   %r14
push   %rbx
mov    %rdi,%rbp
mov    %rdi,%rbx
jmp    1142 <decode_string+0x22>
nopl   0x0(%rax)
test   %al,%al
je     11ae <decode_string+0x8e>
movzbl (%rbx),%eax
mov    %al,0x0(%rbp)
add    $0x1,%rbx
add    $0x1,%rbp
movzbl (%rbx),%eax
cmp    $0x25,%al
jne    1130 <decode_string+0x10>
movzbl 0x1(%rbx),%eax
test   %al,%al
je     1134 <decode_string+0x14>
cmpb   $0x0,0x2(%rbx)
je     1134 <decode_string+0x14>
movsbl %al,%edi
call   1040 <isxdigit@plt>
test   %rax,%rax
je     1134 <decode_string+0x14>
lea    0x2(%rbx),%r14
movsbl (%r14),%edi
call   1040 <isxdigit@plt>
test   %rax,%rax
je     1134 <decode_string+0x14>
movzbl 0x1(%rbx),%eax
lea    -0x30(%rax),%ebx
cmp    $0xa,%bl
jb     118f <decode_string+0x6f>
movsbl %al,%edi
call   1030 <toupper@plt>
mov    %eax,%ebx
add    $0xc9,%bl
shl    $0x4,%bl
movzbl (%r14),%ecx
lea    -0x30(%rcx),%eax
cmp    $0xa,%al
jb     11a7 <decode_string+0x87>
movsbl %cl,%edi
call   1030 <toupper@plt>
add    $0xc9,%al
add    %bl,%al
mov    %r14,%rbx
jmp    1137 <decode_string+0x17>
movb   $0x0,0x0(%rbp)
pop    %rbx
pop    %r14
pop    %rbp
ret

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

LLVM IR (-O2):
define void @decode_string(i8* nocapture %0) {
br label %2
2: ; preds = %42, %1
%3 = phi i8* [ %0, %1 ], [ %46, %42 ]
%4 = phi i8* [ %0, %1 ], [ %45, %42 ]
%5 = load i8, i8* %4
switch i8 %5, label %6 [
i8 0, label %47
i8 37, label %8
]
6: ; preds = %2, %8, %12, %16, %19
%7 = load i8, i8* %4
br label %42
8: ; preds = %2
%9 = getelementptr inbounds i8, i8* %4, i64 1
%10 = load i8, i8* %9
%11 = icmp eq i8 %10, 0
br i1 %11, label %6, label %12
12: ; preds = %8
%13 = getelementptr inbounds i8, i8* %4, i64 2
%14 = load i8, i8* %13
%15 = icmp eq i8 %14, 0
br i1 %15, label %6, label %16
16: ; preds = %12
%17 = tail call i64 @isxdigit(i8 signext %10)
%18 = icmp eq i64 %17, 0
br i1 %18, label %6, label %19
19: ; preds = %16
%20 = load i8, i8* %13
%21 = tail call i64 @isxdigit(i8 signext %20)
%22 = icmp eq i64 %21, 0
br i1 %22, label %6, label %23
23: ; preds = %19
%24 = load i8, i8* %9
%25 = add i8 %24, -48
%26 = icmp ult i8 %25, 10
br i1 %26, label %30, label %27
27: ; preds = %23
%28 = tail call signext i8 @toupper(i8 signext %24)
%29 = add i8 %28, -55
br label %30
30: ; preds = %23, %27
%31 = phi i8 [ %29, %27 ], [ %25, %23 ]
%32 = shl i8 %31, 4
%33 = load i8, i8* %13
%34 = add i8 %33, -48
%35 = icmp ult i8 %34, 10
br i1 %35, label %39, label %36
36: ; preds = %30
%37 = tail call signext i8 @toupper(i8 signext %33)
%38 = add i8 %37, -55
br label %39
39: ; preds = %30, %36
%40 = phi i8 [ %38, %36 ], [ %34, %30 ]
%41 = add i8 %40, %32
br label %42
42: ; preds = %6, %39
%43 = phi i8 [ %7, %6 ], [ %41, %39 ]
%44 = phi i8* [ %4, %6 ], [ %13, %39 ]
store i8 %43, i8* %3
%45 = getelementptr inbounds i8, i8* %44, i64 1
%46 = getelementptr inbounds i8, i8* %3, i64 1
br label %2
47: ; preds = %2
store i8 0, i8* %3
ret void
}