From 49f4f8089cb5a466f7136b0023c3c4b72f5a875c Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Tue, 17 Jan 2017 11:04:28 -0800 Subject: [PATCH] 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 https://github.com/rust-lang/rust/issues/39119 - rust emits a negative constant i8 -1 instead of clang's i8 255) then we must be careful --- src/library.js | 4 +-- tests/cases/rust_ctlz_negative_i8.ll | 41 +++++++++++++++++++++++++++ tests/cases/rust_ctlz_negative_i8.txt | 1 + 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 tests/cases/rust_ctlz_negative_i8.ll create mode 100644 tests/cases/rust_ctlz_negative_i8.txt diff --git a/src/library.js b/src/library.js index cd7d946c393fd..f3a9d1a91a236 100644 --- a/src/library.js +++ b/src/library.js @@ -951,7 +951,7 @@ LibraryManager.library = { llvm_ctlz_i8: function(x, isZeroUndef) { x = x | 0; isZeroUndef = isZeroUndef | 0; - return (Math_clz32(x) | 0) - 24 | 0; + return (Math_clz32(x & 0xff) | 0) - 24 | 0; }, llvm_ctlz_i16__asm: true, @@ -959,7 +959,7 @@ LibraryManager.library = { llvm_ctlz_i16: function(x, isZeroUndef) { x = x | 0; isZeroUndef = isZeroUndef | 0; - return (Math_clz32(x) | 0) - 16 | 0 + return (Math_clz32(x & 0xffff) | 0) - 16 | 0 }, llvm_ctlz_i64__asm: true, diff --git a/tests/cases/rust_ctlz_negative_i8.ll b/tests/cases/rust_ctlz_negative_i8.ll new file mode 100644 index 0000000000000..08043359d2a61 --- /dev/null +++ b/tests/cases/rust_ctlz_negative_i8.ll @@ -0,0 +1,41 @@ +; ModuleID = 'foo.cgu-0.rs' +source_filename = "foo.cgu-0.rs" +target datalayout = "e-p:32:32-i64:64-v128:32:128-n32-S128" +target triple = "asmjs-unknown-emscripten" + +@.str = private unnamed_addr constant [18 x i8] c"hello, world %d!\0A\00", align 1 + +; Function Attrs: inlinehint uwtable +define internal i32 @"_ZN4core3num20_$LT$impl$u20$u8$GT$13leading_zeros17h0d6a1b849828bff0E"(i8) unnamed_addr #0 { +entry-block: + %tmp_ret = alloca i8 + br label %start + +start: ; preds = %entry-block + %1 = call i8 @llvm.ctlz.i8(i8 %0, i1 false) + store i8 %1, i8* %tmp_ret + %2 = load i8, i8* %tmp_ret + br label %bb1 + +bb1: ; preds = %start + %3 = zext i8 %2 to i32 + ret i32 %3 +} + +define i32 @main() { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval + %value = call i32 @"_ZN4core3num20_$LT$impl$u20$u8$GT$13leading_zeros17h0d6a1b849828bff0E"(i8 -1) + %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str, i32 0, i32 0), i32 %value) + ret i32 0 +} + +; Function Attrs: nounwind readnone +declare i8 @llvm.ctlz.i8(i8, i1) #2 + +declare i32 @printf(i8*, ...) + +attributes #0 = { inlinehint uwtable } +attributes #1 = { uwtable } +attributes #2 = { nounwind readnone } diff --git a/tests/cases/rust_ctlz_negative_i8.txt b/tests/cases/rust_ctlz_negative_i8.txt new file mode 100644 index 0000000000000..dfba99f8be198 --- /dev/null +++ b/tests/cases/rust_ctlz_negative_i8.txt @@ -0,0 +1 @@ +hello, world 0!