#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 strlen(char *);
char *util_rtrim(char *str, char c) {
  int i;
  for (i = strlen(str) - 1; i >= 0; i--) {
    if (c && str[i] == c) {
      str[i] = '\0';
    } else if (str[i] == '\r' || str[i] == '\n' || str[i] == ' ' ||
               str[i] == '\t' || str[i] == '\x0B') {
      str[i] = '\0';
    } else {
      break;
    }
  }
  return str;
}


x86 assembly (clang, -O0):
<util_rtrim>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %sil,%al
mov    %rdi,-0x8(%rbp)
mov    %al,-0x9(%rbp)
mov    -0x8(%rbp),%rdi
call   1030 <strlen@plt>
sub    $0x1,%eax
mov    %eax,-0x10(%rbp)
cmpl   $0x0,-0x10(%rbp)
jl     1208 <util_rtrim+0xf8>
movsbl -0x9(%rbp),%eax
cmp    $0x0,%eax
je     1171 <util_rtrim+0x61>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
movsbl -0x9(%rbp),%ecx
cmp    %ecx,%eax
jne    1171 <util_rtrim+0x61>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
jmp    11f5 <util_rtrim+0xe5>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0xd,%eax
je     11da <util_rtrim+0xca>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0xa,%eax
je     11da <util_rtrim+0xca>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x20,%eax
je     11da <util_rtrim+0xca>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x9,%eax
je     11da <util_rtrim+0xca>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0xb,%eax
jne    11eb <util_rtrim+0xdb>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
jmp    11f0 <util_rtrim+0xe0>
jmp    1208 <util_rtrim+0xf8>
jmp    11f5 <util_rtrim+0xe5>
jmp    11fa <util_rtrim+0xea>
mov    -0x10(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x10(%rbp)
jmp    1131 <util_rtrim+0x21>
mov    -0x8(%rbp),%rax
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<util_rtrim>:
push   %rbp
push   %rbx
push   %rax
mov    %esi,%ebp
mov    %rdi,%rbx
call   1030 <strlen@plt>
test   %eax,%eax
jle    1170 <util_rtrim+0x60>
mov    %eax,%eax
add    $0x1,%rax
movabs $0x100002e00,%rsi
jmp    114d <util_rtrim+0x3d>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movb   $0x0,(%rdx)
add    $0xffffffffffffffff,%rax
cmp    $0x1,%rax
jbe    1170 <util_rtrim+0x60>
lea    -0x2(%rax),%ecx
lea    (%rbx,%rcx,1),%rdx
movzbl (%rbx,%rcx,1),%ecx
test   %bpl,%bpl
je     1162 <util_rtrim+0x52>
cmp    %bpl,%cl
je     1140 <util_rtrim+0x30>
cmp    $0x20,%cl
ja     1170 <util_rtrim+0x60>
movzbl %cl,%ecx
bt     %rcx,%rsi
jb     1140 <util_rtrim+0x30>
mov    %rbx,%rax
add    $0x8,%rsp
pop    %rbx
pop    %rbp
ret

LLVM IR (-O0):
define i8* @util_rtrim(i8* %0, i8 signext %1) {
%3 = alloca i8*
%4 = alloca i8
%5 = alloca i32
store i8* %0, i8** %3
store i8 %1, i8* %4
%6 = load i8*, i8** %3
%7 = call i32 @strlen(i8* %6)
%8 = sub nsw i32 %7, 1
store i32 %8, i32* %5
br label %9
9: ; preds = %79, %2
%10 = load i32, i32* %5
%11 = icmp sge i32 %10, 0
br i1 %11, label %12, label %82
12: ; preds = %9
%13 = load i8, i8* %4
%14 = sext i8 %13 to i32
%15 = icmp ne i32 %14, 0
br i1 %15, label %16, label %31
16: ; preds = %12
%17 = load i8*, i8** %3
%18 = load i32, i32* %5
%19 = sext i32 %18 to i64
%20 = getelementptr inbounds i8, i8* %17, i64 %19
%21 = load i8, i8* %20
%22 = sext i8 %21 to i32
%23 = load i8, i8* %4
%24 = sext i8 %23 to i32
%25 = icmp eq i32 %22, %24
br i1 %25, label %26, label %31
26: ; preds = %16
%27 = load i8*, i8** %3
%28 = load i32, i32* %5
%29 = sext i32 %28 to i64
%30 = getelementptr inbounds i8, i8* %27, i64 %29
store i8 0, i8* %30
br label %78
31: ; preds = %16, %12
%32 = load i8*, i8** %3
%33 = load i32, i32* %5
%34 = sext i32 %33 to i64
%35 = getelementptr inbounds i8, i8* %32, i64 %34
%36 = load i8, i8* %35
%37 = sext i8 %36 to i32
%38 = icmp eq i32 %37, 13
br i1 %38, label %71, label %39
39: ; preds = %31
%40 = load i8*, i8** %3
%41 = load i32, i32* %5
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds i8, i8* %40, i64 %42
%44 = load i8, i8* %43
%45 = sext i8 %44 to i32
%46 = icmp eq i32 %45, 10
br i1 %46, label %71, label %47
47: ; preds = %39
%48 = load i8*, i8** %3
%49 = load i32, i32* %5
%50 = sext i32 %49 to i64
%51 = getelementptr inbounds i8, i8* %48, i64 %50
%52 = load i8, i8* %51
%53 = sext i8 %52 to i32
%54 = icmp eq i32 %53, 32
br i1 %54, label %71, label %55
55: ; preds = %47
%56 = load i8*, i8** %3
%57 = load i32, i32* %5
%58 = sext i32 %57 to i64
%59 = getelementptr inbounds i8, i8* %56, i64 %58
%60 = load i8, i8* %59
%61 = sext i8 %60 to i32
%62 = icmp eq i32 %61, 9
br i1 %62, label %71, label %63
63: ; preds = %55
%64 = load i8*, i8** %3
%65 = load i32, i32* %5
%66 = sext i32 %65 to i64
%67 = getelementptr inbounds i8, i8* %64, i64 %66
%68 = load i8, i8* %67
%69 = sext i8 %68 to i32
%70 = icmp eq i32 %69, 11
br i1 %70, label %71, label %76
71: ; preds = %63, %55, %47, %39, %31
%72 = load i8*, i8** %3
%73 = load i32, i32* %5
%74 = sext i32 %73 to i64
%75 = getelementptr inbounds i8, i8* %72, i64 %74
store i8 0, i8* %75
br label %77
76: ; preds = %63
br label %82
77: ; preds = %71
br label %78
78: ; preds = %77, %26
br label %79
79: ; preds = %78
%80 = load i32, i32* %5
%81 = add nsw i32 %80, -1
store i32 %81, i32* %5
br label %9
82: ; preds = %76, %9
%83 = load i8*, i8** %3
ret i8* %83
}

LLVM IR (-O2):
define i8* @util_rtrim(i8* returned %0, i8 signext %1) {
%3 = tail call i32 @strlen(i8* %0)
%4 = icmp sgt i32 %3, 0
br i1 %4, label %5, label %22
5: ; preds = %2
%6 = icmp ne i8 %1, 0
%7 = zext i32 %3 to i64
br label %8
8: ; preds = %5, %19
%9 = phi i64 [ %7, %5 ], [ %10, %19 ]
%10 = add nsw i64 %9, -1
%11 = and i64 %10, 4294967295
%12 = getelementptr inbounds i8, i8* %0, i64 %11
%13 = load i8, i8* %12
%14 = icmp eq i8 %13, %1
%15 = select i1 %6, i1 %14, i1 false
br i1 %15, label %19, label %16
16: ; preds = %8
switch i8 %13, label %22 [
i8 13, label %17
i8 10, label %17
i8 32, label %17
i8 9, label %17
i8 11, label %17
]
17: ; preds = %16, %16, %16, %16, %16
%18 = getelementptr inbounds i8, i8* %0, i64 %11
br label %19
19: ; preds = %8, %17
%20 = phi i8* [ %18, %17 ], [ %12, %8 ]
store i8 0, i8* %20
%21 = icmp ugt i64 %9, 1
br i1 %21, label %8, label %22
22: ; preds = %19, %16, %2
ret i8* %0
}