Skip to content

Commit 49f4f80

Browse files
committed
do not assume anything about the top bits in llvm intrinsics receiving i8/i16 values - while normally we can assume that the top bits are clear due to how LLVM creates the call, if the call is an ffi or constructed in a non-clang way (see rust-lang/rust#39119 - rust emits a negative constant i8 -1 instead of clang's i8 255) then we must be careful
1 parent 62dfd0f commit 49f4f80

File tree

3 files changed

+44
-2
lines changed

3 files changed

+44
-2
lines changed

src/library.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -951,15 +951,15 @@ LibraryManager.library = {
951951
llvm_ctlz_i8: function(x, isZeroUndef) {
952952
x = x | 0;
953953
isZeroUndef = isZeroUndef | 0;
954-
return (Math_clz32(x) | 0) - 24 | 0;
954+
return (Math_clz32(x & 0xff) | 0) - 24 | 0;
955955
},
956956

957957
llvm_ctlz_i16__asm: true,
958958
llvm_ctlz_i16__sig: 'ii',
959959
llvm_ctlz_i16: function(x, isZeroUndef) {
960960
x = x | 0;
961961
isZeroUndef = isZeroUndef | 0;
962-
return (Math_clz32(x) | 0) - 16 | 0
962+
return (Math_clz32(x & 0xffff) | 0) - 16 | 0
963963
},
964964

965965
llvm_ctlz_i64__asm: true,

tests/cases/rust_ctlz_negative_i8.ll

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; ModuleID = 'foo.cgu-0.rs'
2+
source_filename = "foo.cgu-0.rs"
3+
target datalayout = "e-p:32:32-i64:64-v128:32:128-n32-S128"
4+
target triple = "asmjs-unknown-emscripten"
5+
6+
@.str = private unnamed_addr constant [18 x i8] c"hello, world %d!\0A\00", align 1
7+
8+
; Function Attrs: inlinehint uwtable
9+
define internal i32 @"_ZN4core3num20_$LT$impl$u20$u8$GT$13leading_zeros17h0d6a1b849828bff0E"(i8) unnamed_addr #0 {
10+
entry-block:
11+
%tmp_ret = alloca i8
12+
br label %start
13+
14+
start: ; preds = %entry-block
15+
%1 = call i8 @llvm.ctlz.i8(i8 %0, i1 false)
16+
store i8 %1, i8* %tmp_ret
17+
%2 = load i8, i8* %tmp_ret
18+
br label %bb1
19+
20+
bb1: ; preds = %start
21+
%3 = zext i8 %2 to i32
22+
ret i32 %3
23+
}
24+
25+
define i32 @main() {
26+
entry:
27+
%retval = alloca i32, align 4
28+
store i32 0, i32* %retval
29+
%value = call i32 @"_ZN4core3num20_$LT$impl$u20$u8$GT$13leading_zeros17h0d6a1b849828bff0E"(i8 -1)
30+
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str, i32 0, i32 0), i32 %value)
31+
ret i32 0
32+
}
33+
34+
; Function Attrs: nounwind readnone
35+
declare i8 @llvm.ctlz.i8(i8, i1) #2
36+
37+
declare i32 @printf(i8*, ...)
38+
39+
attributes #0 = { inlinehint uwtable }
40+
attributes #1 = { uwtable }
41+
attributes #2 = { nounwind readnone }

tests/cases/rust_ctlz_negative_i8.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
hello, world 0!

0 commit comments

Comments
 (0)