Skip to content

Instantly share code, notes, and snippets.

@Nava2
Created April 19, 2016 01:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nava2/f249c2a5a88d4bb833d49d3e59bde35f to your computer and use it in GitHub Desktop.
Save Nava2/f249c2a5a88d4bb833d49d3e59bde35f to your computer and use it in GitHub Desktop.
LLVM comparison between simple operation test program in C and Rust
#include <stdint.h>
/* Unsigned comparisons */
/* Return 1 if condition is true, 0 otherwise */
int ct_isnonzero_u32(uint32_t x)
{
return (x|-x)>>31;
}
/* Generate a mask: 0xFFFFFFFF if bit != 0, 0 otherwise */
uint32_t ct_mask_u32(uint32_t bit)
{
return -(uint32_t)ct_isnonzero_u32(bit);
}
uint32_t ct_select_u32(uint32_t x, uint32_t y, _Bool bit)
{
uint32_t m = ct_mask_u32(bit);
return (x&m) | (y&~m);
}
int main() {
uint32_t a = 0xFFFFFFFF;
uint32_t b = 0x00000000;
uint32_t c = ct_select_u32(a, b, 4);
}
; Function Attrs: nounwind ssp uwtable
define i32 @ct_isnonzero_u32(i32 %x) #0 {
%1 = alloca i32, align 4
store i32 %x, i32* %1, align 4
%2 = load i32* %1, align 4
%3 = load i32* %1, align 4
%4 = sub i32 0, %3
%5 = or i32 %2, %4
%6 = lshr i32 %5, 31
ret i32 %6
}
; Function Attrs: nounwind ssp uwtable
define i32 @ct_mask_u32(i32 %bit) #0 {
%1 = alloca i32, align 4
store i32 %bit, i32* %1, align 4
%2 = load i32* %1, align 4
%3 = call i32 @ct_isnonzero_u32(i32 %2)
%4 = sub i32 0, %3
ret i32 %4
}
; Function Attrs: nounwind ssp uwtable
define i32 @ct_select_u32(i32 %x, i32 %y, i1 zeroext %bit) #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i8, align 1
%m = alloca i32, align 4
store i32 %x, i32* %1, align 4
store i32 %y, i32* %2, align 4
%4 = zext i1 %bit to i8
store i8 %4, i8* %3, align 1
%5 = load i8* %3, align 1
%6 = trunc i8 %5 to i1
%7 = zext i1 %6 to i32
%8 = call i32 @ct_mask_u32(i32 %7)
store i32 %8, i32* %m, align 4
%9 = load i32* %1, align 4
%10 = load i32* %m, align 4
%11 = and i32 %9, %10
%12 = load i32* %2, align 4
%13 = load i32* %m, align 4
%14 = xor i32 %13, -1
%15 = and i32 %12, %14
%16 = or i32 %11, %15
ret i32 %16
}
; Function Attrs: nounwind ssp uwtable
define i32 @main() #0 {
%a = alloca i32, align 4
%b = alloca i32, align 4
%c = alloca i32, align 4
store i32 -1, i32* %a, align 4
store i32 0, i32* %b, align 4
%1 = load i32* %a, align 4
%2 = load i32* %b, align 4
%3 = call i32 @ct_select_u32(i32 %1, i32 %2, i1 zeroext true)
store i32 %3, i32* %c, align 4
ret i32 0
}
// Unsigned comparisons
// Return 1 if condition is true, 0 otherwise
fn ct_isnonzero_u32(x: u32) -> i32 {
(x | (-(x as i32) as u32) >> 31) as i32
}
// Generate a mask: 0xFFFFFFFF if
// bit != 0, 0 otherwise
fn ct_mask_u32(bit: u32) -> u32 {
-ct_isnonzero_u32(bit) as u32
}
fn ct_select_u32(x: u32, y: u32, bit: u32)
-> u32 {
let m = ct_mask_u32(bit);
(x & m) | (y & !m)
}
fn main() {
let a = 0xFFFFFFFFu32;
let b = 0x00000000u32;
let c = ct_select_u32(a, b, 4);
}
; Function Attrs: uwtable
define internal i32 @_ZN4test16ct_isnonzero_u3217h8d4d40af41636ca5E(i32) unnamed_addr #0 {
entry-block:
%x = alloca i32
store i32 %0, i32* %x
%1 = load i32, i32* %x
%2 = load i32, i32* %x
%3 = sub i32 0, %2
%4 = icmp eq i32 %2, -2147483648
br i1 %4, label %cond, label %next
next: ; preds = %entry-block
%5 = lshr i32 %3, 31
%6 = or i32 %1, %5
ret i32 %6
cond: ; preds = %entry-block
call void @_ZN4core9panicking5panic17h4bb1497076d04ab9E({ %str_slice, %str_slice, i32 }* noalias readonly dereferenceable(40) @panic_loc3064)
unreachable
}
; Function Attrs: cold noinline noreturn
declare void @_ZN4core9panicking5panic17h4bb1497076d04ab9E({ %str_slice, %str_slice, i32 }* noalias readonly dereferenceable(40)) unnamed_addr #1
; Function Attrs: uwtable
define internal i32 @_ZN4test11ct_mask_u3217h72287265d52dbb7aE(i32) unnamed_addr #0 {
entry-block:
%bit = alloca i32
%1 = alloca i32
store i32 %0, i32* %bit
%2 = load i32, i32* %bit
%3 = call i32 @_ZN4test16ct_isnonzero_u3217h8d4d40af41636ca5E(i32 %2)
store i32 %3, i32* %1
%4 = load i32, i32* %1
%5 = sub i32 0, %4
%6 = icmp eq i32 %4, -2147483648
br i1 %6, label %cond, label %next
next: ; preds = %entry-block
ret i32 %5
cond: ; preds = %entry-block
call void @_ZN4core9panicking5panic17h4bb1497076d04ab9E({ %str_slice, %str_slice, i32 }* noalias readonly dereferenceable(40) @panic_loc3070)
unreachable
}
; Function Attrs: uwtable
define internal i32 @_ZN4test13ct_select_u3217h83cfd05da43761d3E(i32, i32, i32) unnamed_addr #0 {
entry-block:
%x = alloca i32
%y = alloca i32
%bit = alloca i32
%m = alloca i32
store i32 %0, i32* %x
store i32 %1, i32* %y
store i32 %2, i32* %bit
%3 = load i32, i32* %bit
%4 = call i32 @_ZN4test11ct_mask_u3217h72287265d52dbb7aE(i32 %3)
store i32 %4, i32* %m
%5 = load i32, i32* %x
%6 = load i32, i32* %m
%7 = and i32 %5, %6
%8 = load i32, i32* %y
%9 = load i32, i32* %m
%10 = xor i32 %9, -1
%11 = and i32 %8, %10
%12 = or i32 %7, %11
ret i32 %12
}
; Function Attrs: uwtable
define internal void @_ZN4test4main17h1ef728500ff2f89bE() unnamed_addr #0 {
entry-block:
%a = alloca i32
%b = alloca i32
%c = alloca i32
store i32 -1, i32* %a
store i32 0, i32* %b
%0 = load i32, i32* %a
%1 = load i32, i32* %b
%2 = call i32 @_ZN4test13ct_select_u3217h83cfd05da43761d3E(i32 %0, i32 %1, i32 4)
store i32 %2, i32* %c
ret void
}
define i64 @main(i64, i8**) unnamed_addr {
top:
%2 = call i64 @_ZN3std2rt10lang_start17h61f4934e780b4dfcE(i8* bitcast (void ()* @_ZN4test4main17h1ef728500ff2f89bE to i8*), i64 %0, i8** %1)
ret i64 %2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment