unsigned char is_greater(unsigned char x, unsigned char y) {
  unsigned char uc1, uc2;
  uc1 = ~x & y;
  uc2 = x & ~y;
  uc1 = uc1 | (uc1 >> 1);
  uc1 = uc1 | (uc1 >> 2);
  uc1 = uc1 | (uc1 >> 4);
  return ~is_zero(~uc1 & uc2) & 1;
}


x86 assembly (clang, -O0):
<is_greater>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %sil,%al
mov    %dil,%cl
mov    %cl,-0x1(%rbp)
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%eax
xor    $0xffffffff,%eax
movzbl -0x2(%rbp),%ecx
and    %ecx,%eax
mov    %al,-0x3(%rbp)
movzbl -0x1(%rbp),%eax
movzbl -0x2(%rbp),%ecx
xor    $0xffffffff,%ecx
and    %ecx,%eax
mov    %al,-0x4(%rbp)
movzbl -0x3(%rbp),%eax
movzbl -0x3(%rbp),%ecx
sar    $0x1,%ecx
or     %ecx,%eax
mov    %al,-0x3(%rbp)
movzbl -0x3(%rbp),%eax
movzbl -0x3(%rbp),%ecx
sar    $0x2,%ecx
or     %ecx,%eax
mov    %al,-0x3(%rbp)
movzbl -0x3(%rbp),%eax
movzbl -0x3(%rbp),%ecx
sar    $0x4,%ecx
or     %ecx,%eax
mov    %al,-0x3(%rbp)
movzbl -0x3(%rbp),%edi
xor    $0xffffffff,%edi
movzbl -0x4(%rbp),%eax
and    %eax,%edi
mov    $0x0,%al
call   1030 <is_zero@plt>
xor    $0xffffffff,%eax
and    $0x1,%eax
movzbl %al,%eax
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<is_greater>:
push   %rax
mov    %edi,%eax
not    %al
and    %sil,%al
not    %sil
and    %dil,%sil
mov    %eax,%ecx
shr    %cl
or     %al,%cl
mov    %ecx,%eax
shr    $0x2,%al
or     %cl,%al
mov    %eax,%ecx
shr    $0x4,%cl
or     %al,%cl
movzbl %cl,%eax
not    %eax
movzbl %sil,%edi
and    %eax,%edi
xor    %eax,%eax
call   1030 <is_zero@plt>
not    %al
and    $0x1,%al
pop    %rcx
ret

LLVM IR (-O0):
define zeroext i8 @is_greater(i8 zeroext %0, i8 zeroext %1) {
%3 = alloca i8
%4 = alloca i8
%5 = alloca i8
%6 = alloca i8
store i8 %0, i8* %3
store i8 %1, i8* %4
%7 = load i8, i8* %3
%8 = zext i8 %7 to i32
%9 = xor i32 %8, -1
%10 = load i8, i8* %4
%11 = zext i8 %10 to i32
%12 = and i32 %9, %11
%13 = trunc i32 %12 to i8
store i8 %13, i8* %5
%14 = load i8, i8* %3
%15 = zext i8 %14 to i32
%16 = load i8, i8* %4
%17 = zext i8 %16 to i32
%18 = xor i32 %17, -1
%19 = and i32 %15, %18
%20 = trunc i32 %19 to i8
store i8 %20, i8* %6
%21 = load i8, i8* %5
%22 = zext i8 %21 to i32
%23 = load i8, i8* %5
%24 = zext i8 %23 to i32
%25 = ashr i32 %24, 1
%26 = or i32 %22, %25
%27 = trunc i32 %26 to i8
store i8 %27, i8* %5
%28 = load i8, i8* %5
%29 = zext i8 %28 to i32
%30 = load i8, i8* %5
%31 = zext i8 %30 to i32
%32 = ashr i32 %31, 2
%33 = or i32 %29, %32
%34 = trunc i32 %33 to i8
store i8 %34, i8* %5
%35 = load i8, i8* %5
%36 = zext i8 %35 to i32
%37 = load i8, i8* %5
%38 = zext i8 %37 to i32
%39 = ashr i32 %38, 4
%40 = or i32 %36, %39
%41 = trunc i32 %40 to i8
store i8 %41, i8* %5
%42 = load i8, i8* %5
%43 = zext i8 %42 to i32
%44 = xor i32 %43, -1
%45 = load i8, i8* %6
%46 = zext i8 %45 to i32
%47 = and i32 %44, %46
%48 = call i32 (i32, ...) bitcast (i32 (...)* @is_zero to i32 (i32, ...)*)(i32 %47)
%49 = xor i32 %48, -1
%50 = and i32 %49, 1
%51 = trunc i32 %50 to i8
ret i8 %51
}

LLVM IR (-O2):
define zeroext i8 @is_greater(i8 zeroext %0, i8 zeroext %1) {
%3 = xor i8 %0, -1
%4 = and i8 %3, %1
%5 = xor i8 %1, -1
%6 = and i8 %5, %0
%7 = lshr i8 %4, 1
%8 = or i8 %7, %4
%9 = lshr i8 %8, 2
%10 = or i8 %9, %8
%11 = lshr i8 %10, 4
%12 = or i8 %11, %10
%13 = zext i8 %12 to i32
%14 = xor i32 %13, -1
%15 = zext i8 %6 to i32
%16 = and i32 %14, %15
%17 = tail call i32 (i32, ...) bitcast (i32 (...)* @is_zero to i32 (i32, ...)*)(i32 %16)
%18 = trunc i32 %17 to i8
%19 = and i8 %18, 1
%20 = xor i8 %19, 1
ret i8 %20
}