#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 getchar();
int /*<<< orphan*/ printf(char *, ...);
int main(void) {
  int words[40];
  int fin = '0';
  int i = 0;
  printf("Enter a sentence: ");
  while ((words[i] = getchar()) != '\n') {
    if (words[i] == '.' || words[i] == '?' || words[i] == '!') {
      fin = words[i];
      continue;
    }
    i += 1;
  }
  if (words[i] == '\n') {
    i -= 1;
  }
  int *p = &words[i];
  printf("Words reversed: ");
  while (p != &words[0]) {
    i = 0;
    while (*p != ' ') {
      p -= 1;
      i += 1;
      if (*p == ' ') {
        p += 1;
        break;
      }
      if (p == &words[0]) {
        break;
      }
    }
    int j = 0;
    while (p + j <= p + i) {
      if (*(p + j) == '\n' || *(p + j) == ' ') {
        break;
      }
      printf("%c", *(p + j));
      j += 1;
    }
    if (p != &words[0]) {
      while (*p != ' ') {
        p -= 1;
      }
      while (*p == ' ') {
        printf(" ");
        p -= 1;
      }
    }
  }
  printf("%c\n", fin);
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0xd0,%rsp
movl   $0x0,-0x4(%rbp)
movl   $0x30,-0xb4(%rbp)
movl   $0x0,-0xb8(%rbp)
lea    0xeb3(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    $0x0,%al
call   1040 <getchar@plt>
movslq -0xb8(%rbp),%rcx
mov    %eax,-0xb0(%rbp,%rcx,4)
cmp    $0xa,%eax
je     11de <main+0xbe>
movslq -0xb8(%rbp),%rax
cmpl   $0x2e,-0xb0(%rbp,%rax,4)
2e
je     11b1 <main+0x91>
movslq -0xb8(%rbp),%rax
cmpl   $0x3f,-0xb0(%rbp,%rax,4)
3f
je     11b1 <main+0x91>
movslq -0xb8(%rbp),%rax
cmpl   $0x21,-0xb0(%rbp,%rax,4)
21
jne    11ca <main+0xaa>
movslq -0xb8(%rbp),%rax
mov    -0xb0(%rbp,%rax,4),%eax
mov    %eax,-0xb4(%rbp)
jmp    1154 <main+0x34>
mov    -0xb8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xb8(%rbp)
jmp    1154 <main+0x34>
movslq -0xb8(%rbp),%rax
cmpl   $0xa,-0xb0(%rbp,%rax,4)
0a
jne    1202 <main+0xe2>
mov    -0xb8(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0xb8(%rbp)
movslq -0xb8(%rbp),%rcx
lea    -0xb0(%rbp),%rax
shl    $0x2,%rcx
add    %rcx,%rax
mov    %rax,-0xc0(%rbp)
lea    0xdee(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0xc0(%rbp),%rax
lea    -0xb0(%rbp),%rcx
cmp    %rcx,%rax
je     13f2 <main+0x2d2>
movl   $0x0,-0xb8(%rbp)
mov    -0xc0(%rbp),%rax
cmpl   $0x20,(%rax)
je     12c6 <main+0x1a6>
mov    -0xc0(%rbp),%rax
add    $0xfffffffffffffffc,%rax
mov    %rax,-0xc0(%rbp)
mov    -0xb8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xb8(%rbp)
mov    -0xc0(%rbp),%rax
cmpl   $0x20,(%rax)
jne    12a5 <main+0x185>
mov    -0xc0(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0xc0(%rbp)
jmp    12c6 <main+0x1a6>
mov    -0xc0(%rbp),%rax
lea    -0xb0(%rbp),%rcx
cmp    %rcx,%rax
jne    12c1 <main+0x1a1>
jmp    12c6 <main+0x1a6>
jmp    124d <main+0x12d>
movl   $0x0,-0xc4(%rbp)
mov    -0xc0(%rbp),%rax
movslq -0xc4(%rbp),%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    -0xc0(%rbp),%rcx
movslq -0xb8(%rbp),%rdx
shl    $0x2,%rdx
add    %rdx,%rcx
cmp    %rcx,%rax
ja     136b <main+0x24b>
mov    -0xc0(%rbp),%rax
movslq -0xc4(%rbp),%rcx
cmpl   $0xa,(%rax,%rcx,4)
je     1333 <main+0x213>
mov    -0xc0(%rbp),%rax
movslq -0xc4(%rbp),%rcx
cmpl   $0x20,(%rax,%rcx,4)
jne    1338 <main+0x218>
jmp    136b <main+0x24b>
mov    -0xc0(%rbp),%rax
movslq -0xc4(%rbp),%rcx
mov    (%rax,%rcx,4),%esi
lea    0xcd4(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0xc4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc4(%rbp)
jmp    12d0 <main+0x1b0>
mov    -0xc0(%rbp),%rax
lea    -0xb0(%rbp),%rcx
cmp    %rcx,%rax
je     13ed <main+0x2cd>
jmp    1387 <main+0x267>
mov    -0xc0(%rbp),%rax
cmpl   $0x20,(%rax)
je     13ae <main+0x28e>
mov    -0xc0(%rbp),%rax
add    $0xfffffffffffffffc,%rax
mov    %rax,-0xc0(%rbp)
jmp    1387 <main+0x267>
jmp    13b3 <main+0x293>
mov    -0xc0(%rbp),%rax
cmpl   $0x20,(%rax)
jne    13e8 <main+0x2c8>
lea    0xc58(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0xc0(%rbp),%rax
add    $0xfffffffffffffffc,%rax
mov    %rax,-0xc0(%rbp)
jmp    13b3 <main+0x293>
jmp    13ed <main+0x2cd>
jmp    122c <main+0x10c>
mov    -0xb4(%rbp),%esi
lea    0xc28(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
xor    %eax,%eax
add    $0xd0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0xa0,%rsp
lea    0xeba(%rip),%rdi
xor    %eax,%eax
call   1040 <printf@plt>
mov    $0x30,%r14d
xor    %ebp,%ebp
jmp    1163 <main+0x33>
nopw   0x0(%rax,%rax,1)
mov    %eax,%r14d
movslq %ebp,%rbp
lea    -0x1(%rbp),%ebx
jmp    1177 <main+0x47>
nopl   0x0(%rax,%rax,1)
add    $0x1,%rbp
add    $0x1,%ebx
xor    %eax,%eax
call   1050 <getchar@plt>
mov    %eax,(%rsp,%rbp,4)
cmp    $0x2d,%eax
jg     11a0 <main+0x70>
cmp    $0xa,%eax
je     11ac <main+0x7c>
cmp    $0x21,%eax
jne    1170 <main+0x40>
jmp    1160 <main+0x30>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
cmp    $0x2e,%eax
je     1160 <main+0x30>
cmp    $0x3f,%eax
jne    1170 <main+0x40>
jmp    1160 <main+0x30>
lea    0xe60(%rip),%rdi
xor    %eax,%eax
call   1040 <printf@plt>
test   %ebx,%ebx
je     1270 <main+0x140>
movslq %ebx,%rax
lea    (%rsp,%rax,4),%rbx
mov    %rsp,%r15
nopl   0x0(%rax)
mov    (%rbx),%ecx
xor    %edx,%edx
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
mov    %edx,%eax
cmp    $0x20,%ecx
je     1201 <main+0xd1>
mov    -0x4(%rbx),%ecx
cmp    $0x20,%ecx
je     11fe <main+0xce>
add    $0xfffffffffffffffc,%rbx
lea    0x1(%rax),%edx
cmp    %r15,%rbx
jne    11e0 <main+0xb0>
mov    %r15,%rbx
add    $0x1,%eax
movslq %eax,%r12
add    $0x1,%r12
xor    %ebp,%ebp
nopw   0x0(%rax,%rax,1)
mov    (%rbx,%rbp,4),%edi
cmp    $0xa,%edi
je     122b <main+0xfb>
cmp    $0x20,%edi
je     122b <main+0xfb>
call   1030 <putchar@plt>
add    $0x1,%rbp
cmp    %rbp,%r12
jne    1210 <main+0xe0>
cmp    %r15,%rbx
je     1270 <main+0x140>
add    $0x4,%rbx
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
cmpl   $0x20,-0x4(%rbx)
lea    -0x4(%rbx),%rbx
jne    1240 <main+0x110>
nopw   0x0(%rax,%rax,1)
mov    %rbx,%rbp
mov    $0x20,%edi
call   1030 <putchar@plt>
add    $0xfffffffffffffffc,%rbx
cmpl   $0x20,-0x4(%rbp)
je     1250 <main+0x120>
cmp    %r15,%rbx
jne    11d0 <main+0xa0>
lea    0xdad(%rip),%rdi
mov    %r14d,%esi
xor    %eax,%eax
call   1040 <printf@plt>
xor    %eax,%eax
add    $0xa0,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [19 x i8] c"Enter a sentence: \00"
@.str.1 = [17 x i8] c"Words reversed: \00"
@.str.2 = [3 x i8] c"%c\00"
@.str.3 = [2 x i8] c" \00"
@.str.4 = [4 x i8] c"%c\0A\00"
define i32 @main() {
%1 = alloca i32
%2 = alloca [40 x i32]
%3 = alloca i32
%4 = alloca i32
%5 = alloca i32*
%6 = alloca i32
store i32 0, i32* %1
store i32 48, i32* %3
store i32 0, i32* %4
%7 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str, i64 0, i64 0))
br label %8
8: ; preds = %37, %32, %0
%9 = call i32 (...) @getchar()
%10 = load i32, i32* %4
%11 = sext i32 %10 to i64
%12 = getelementptr inbounds [40 x i32], [40 x i32]* %2, i64 0, i64 %11
store i32 %9, i32* %12
%13 = icmp ne i32 %9, 10
br i1 %13, label %14, label %40
14: ; preds = %8
%15 = load i32, i32* %4
%16 = sext i32 %15 to i64
%17 = getelementptr inbounds [40 x i32], [40 x i32]* %2, i64 0, i64 %16
%18 = load i32, i32* %17
%19 = icmp eq i32 %18, 46
br i1 %19, label %32, label %20
20: ; preds = %14
%21 = load i32, i32* %4
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds [40 x i32], [40 x i32]* %2, i64 0, i64 %22
%24 = load i32, i32* %23
%25 = icmp eq i32 %24, 63
br i1 %25, label %32, label %26
26: ; preds = %20
%27 = load i32, i32* %4
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds [40 x i32], [40 x i32]* %2, i64 0, i64 %28
%30 = load i32, i32* %29
%31 = icmp eq i32 %30, 33
br i1 %31, label %32, label %37
32: ; preds = %26, %20, %14
%33 = load i32, i32* %4
%34 = sext i32 %33 to i64
%35 = getelementptr inbounds [40 x i32], [40 x i32]* %2, i64 0, i64 %34
%36 = load i32, i32* %35
store i32 %36, i32* %3
br label %8
37: ; preds = %26
%38 = load i32, i32* %4
%39 = add nsw i32 %38, 1
store i32 %39, i32* %4
br label %8
40: ; preds = %8
%41 = load i32, i32* %4
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds [40 x i32], [40 x i32]* %2, i64 0, i64 %42
%44 = load i32, i32* %43
%45 = icmp eq i32 %44, 10
br i1 %45, label %46, label %49
46: ; preds = %40
%47 = load i32, i32* %4
%48 = sub nsw i32 %47, 1
store i32 %48, i32* %4
br label %49
49: ; preds = %46, %40
%50 = load i32, i32* %4
%51 = sext i32 %50 to i64
%52 = getelementptr inbounds [40 x i32], [40 x i32]* %2, i64 0, i64 %51
store i32* %52, i32** %5
%53 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i64 0, i64 0))
br label %54
54: ; preds = %137, %49
%55 = load i32*, i32** %5
%56 = getelementptr inbounds [40 x i32], [40 x i32]* %2, i64 0, i64 0
%57 = icmp ne i32* %55, %56
br i1 %57, label %58, label %138
58: ; preds = %54
store i32 0, i32* %4
br label %59
59: ; preds = %79, %58
%60 = load i32*, i32** %5
%61 = load i32, i32* %60
%62 = icmp ne i32 %61, 32
br i1 %62, label %63, label %80
63: ; preds = %59
%64 = load i32*, i32** %5
%65 = getelementptr inbounds i32, i32* %64, i64 -1
store i32* %65, i32** %5
%66 = load i32, i32* %4
%67 = add nsw i32 %66, 1
store i32 %67, i32* %4
%68 = load i32*, i32** %5
%69 = load i32, i32* %68
%70 = icmp eq i32 %69, 32
br i1 %70, label %71, label %74
71: ; preds = %63
%72 = load i32*, i32** %5
%73 = getelementptr inbounds i32, i32* %72, i64 1
store i32* %73, i32** %5
br label %80
74: ; preds = %63
%75 = load i32*, i32** %5
%76 = getelementptr inbounds [40 x i32], [40 x i32]* %2, i64 0, i64 0
%77 = icmp eq i32* %75, %76
br i1 %77, label %78, label %79
78: ; preds = %74
br label %80
79: ; preds = %74
br label %59
80: ; preds = %78, %71, %59
store i32 0, i32* %6
br label %81
81: ; preds = %106, %80
%82 = load i32*, i32** %5
%83 = load i32, i32* %6
%84 = sext i32 %83 to i64
%85 = getelementptr inbounds i32, i32* %82, i64 %84
%86 = load i32*, i32** %5
%87 = load i32, i32* %4
%88 = sext i32 %87 to i64
%89 = getelementptr inbounds i32, i32* %86, i64 %88
%90 = icmp ule i32* %85, %89
br i1 %90, label %91, label %115
91: ; preds = %81
%92 = load i32*, i32** %5
%93 = load i32, i32* %6
%94 = sext i32 %93 to i64
%95 = getelementptr inbounds i32, i32* %92, i64 %94
%96 = load i32, i32* %95
%97 = icmp eq i32 %96, 10
br i1 %97, label %105, label %98
98: ; preds = %91
%99 = load i32*, i32** %5
%100 = load i32, i32* %6
%101 = sext i32 %100 to i64
%102 = getelementptr inbounds i32, i32* %99, i64 %101
%103 = load i32, i32* %102
%104 = icmp eq i32 %103, 32
br i1 %104, label %105, label %106
105: ; preds = %98, %91
br label %115
106: ; preds = %98
%107 = load i32*, i32** %5
%108 = load i32, i32* %6
%109 = sext i32 %108 to i64
%110 = getelementptr inbounds i32, i32* %107, i64 %109
%111 = load i32, i32* %110
%112 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), i32 %111)
%113 = load i32, i32* %6
%114 = add nsw i32 %113, 1
store i32 %114, i32* %6
br label %81
115: ; preds = %105, %81
%116 = load i32*, i32** %5
%117 = getelementptr inbounds [40 x i32], [40 x i32]* %2, i64 0, i64 0
%118 = icmp ne i32* %116, %117
br i1 %118, label %119, label %137
119: ; preds = %115
br label %120
120: ; preds = %124, %119
%121 = load i32*, i32** %5
%122 = load i32, i32* %121
%123 = icmp ne i32 %122, 32
br i1 %123, label %124, label %127
124: ; preds = %120
%125 = load i32*, i32** %5
%126 = getelementptr inbounds i32, i32* %125, i64 -1
store i32* %126, i32** %5
br label %120
127: ; preds = %120
br label %128
128: ; preds = %132, %127
%129 = load i32*, i32** %5
%130 = load i32, i32* %129
%131 = icmp eq i32 %130, 32
br i1 %131, label %132, label %136
132: ; preds = %128
%133 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i64 0, i64 0))
%134 = load i32*, i32** %5
%135 = getelementptr inbounds i32, i32* %134, i64 -1
store i32* %135, i32** %5
br label %128
136: ; preds = %128
br label %137
137: ; preds = %136, %115
br label %54
138: ; preds = %54
%139 = load i32, i32* %3
%140 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.4, i64 0, i64 0), i32 %139)
ret i32 0
}

LLVM IR (-O2):
@.str = [19 x i8] c"Enter a sentence: \00"
@.str.1 = [17 x i8] c"Words reversed: \00"
@.str.4 = [4 x i8] c"%c\0A\00"
define i32 @main() {
%1 = alloca [40 x i32]
%2 = bitcast [40 x i32]* %1 to i8*
%3 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([19 x i8], [19 x i8]* @.str, i64 0, i64 0))
br label %5
4: ; preds = %10, %10, %10
br label %5
5: ; preds = %4, %0
%6 = phi i32 [ 48, %0 ], [ %12, %4 ]
%7 = phi i64 [ 0, %0 ], [ %11, %4 ]
%8 = shl i64 %7, 32
%9 = ashr exact i64 %8, 32
br label %10
10: ; preds = %5, %14
%11 = phi i64 [ %9, %5 ], [ %15, %14 ]
%12 = tail call i32 (...) @getchar()
%13 = getelementptr inbounds [40 x i32], [40 x i32]* %1, i64 0, i64 %11
store i32 %12, i32* %13
switch i32 %12, label %14 [
i32 10, label %16
i32 46, label %4
i32 63, label %4
i32 33, label %4
]
14: ; preds = %10
%15 = add i64 %11, 1
br label %10
16: ; preds = %10
%17 = trunc i64 %11 to i32
%18 = add nsw i32 %17, -1
%19 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i64 0, i64 0))
%20 = getelementptr inbounds [40 x i32], [40 x i32]* %1, i64 0, i64 0
%21 = icmp eq i32 %18, 0
br i1 %21, label %67, label %22
22: ; preds = %16
%23 = sext i32 %18 to i64
%24 = getelementptr inbounds [40 x i32], [40 x i32]* %1, i64 0, i64 %23
br label %25
25: ; preds = %22, %65
%26 = phi i32* [ %62, %65 ], [ %24, %22 ]
%27 = load i32, i32* %26
br label %28
28: ; preds = %25, %38
%29 = phi i32 [ %27, %25 ], [ %36, %38 ]
%30 = phi i32 [ 0, %25 ], [ %35, %38 ]
%31 = phi i32* [ %26, %25 ], [ %34, %38 ]
%32 = icmp eq i32 %29, 32
br i1 %32, label %40, label %33
33: ; preds = %28
%34 = getelementptr inbounds i32, i32* %31, i64 -1
%35 = add nuw nsw i32 %30, 1
%36 = load i32, i32* %34
%37 = icmp eq i32 %36, 32
br i1 %37, label %40, label %38
38: ; preds = %33
%39 = icmp eq i32* %34, %20
br i1 %39, label %40, label %28
40: ; preds = %33, %38, %28
%41 = phi i32 [ %35, %38 ], [ %30, %28 ], [ %35, %33 ]
%42 = phi i32* [ %20, %38 ], [ %31, %28 ], [ %31, %33 ]
%43 = sext i32 %41 to i64
br label %44
44: ; preds = %40, %48
%45 = phi i64 [ 0, %40 ], [ %50, %48 ]
%46 = getelementptr inbounds i32, i32* %42, i64 %45
%47 = load i32, i32* %46
switch i32 %47, label %48 [
i32 10, label %52
i32 32, label %52
]
48: ; preds = %44
%49 = call i32 @putchar(i32 %47)
%50 = add nuw nsw i64 %45, 1
%51 = icmp eq i64 %45, %43
br i1 %51, label %52, label %44
52: ; preds = %44, %44, %48
%53 = icmp eq i32* %42, %20
br i1 %53, label %67, label %54
54: ; preds = %52, %54
%55 = phi i32* [ %58, %54 ], [ %42, %52 ]
%56 = load i32, i32* %55
%57 = icmp eq i32 %56, 32
%58 = getelementptr inbounds i32, i32* %55, i64 -1
br i1 %57, label %59, label %54
59: ; preds = %54, %59
%60 = phi i32* [ %62, %59 ], [ %55, %54 ]
%61 = call i32 @putchar(i32 32)
%62 = getelementptr inbounds i32, i32* %60, i64 -1
%63 = load i32, i32* %62
%64 = icmp eq i32 %63, 32
br i1 %64, label %59, label %65
65: ; preds = %59
%66 = icmp eq i32* %62, %20
br i1 %66, label %67, label %25
67: ; preds = %52, %65, %16
%68 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @.str.4, i64 0, i64 0), i32 %6)
ret i32 0
}