Created
April 19, 2016 01:14
-
-
Save Nava2/f249c2a5a88d4bb833d49d3e59bde35f to your computer and use it in GitHub Desktop.
LLVM comparison between simple operation test program in C and Rust
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; 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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; 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