Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release build emit assertion `(KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"' #44899

Closed
kamyuentse opened this issue Sep 28, 2017 · 12 comments
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@kamyuentse
Copy link

I'm a user of the rust-zookeeper, and I found it build failed in release mode.
using the command: cargo build --release --verbose

log:https://gist.github.com/kamyuentse/1bf0c8d65fd40a17060f5cca515e720c

It seems an upstream bug related the LLVM? There is any workaround to fix this bug?

bonifaido/rust-zookeeper#37

Environment:
rustc: rustc 1.22.0-nightly (0e6f4cf51 2017-09-27)
OS: CentOS Linux release 7.4.1708
Kernel: Linux 4.13.3-1.el7.elrepo.x86_64

@jason-wolfe
Copy link

jason-wolfe commented Sep 29, 2017

I just encountered the same bug using the same library, using cargo build --release.

rustc: rustc 1.22.0-nightly (dd08c3070 2017-09-12)
toolchain: nightly-x86_64-unknown-linux-musl and nightly-x86_64-unknown-linux-gnu both trigger it.
OS: Ubuntu 14.04.5 LTS
Kernel: Linux 3.19.0-80-generic x86_64

Builds fine in debug mode.

@jonas-schievink
Copy link
Contributor

Can repro on Arch with Rust nightlies from rustup, so not a packaging issue. Only one LLVM bug mentions the message: https://bugs.llvm.org/show_bug.cgi?id=24241

@TimNN TimNN added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 1, 2017
@jason-wolfe
Copy link

jason-wolfe commented Oct 20, 2017

I don't know if this is entirely relevant and don't know how to debug rustc, but I tried running with RUSTFLAGS="-Zverbose" cargo build --release --verbose, which ended up resulting in

   Compiling zookeeper_derive v0.3.0 (file:///home/jwolfe/Rust/rust-zookeeper/zookeeper-derive)
     Running `rustc --crate-name zookeeper_derive zookeeper-derive/src/lib.rs --crate-type proc-macro --emit=dep-info,link -C prefer-dynamic -C opt-level=3 -C metadata=3d948e35b92c7695 -C extra-filename=-3d948e35b92c7695 --out-dir /home/jwolfe/Rust/rust-zookeeper/target/release/deps -L dependency=/home/jwolfe/Rust/rust-zookeeper/target/release/deps --extern syn=/home/jwolfe/Rust/rust-zookeeper/target/release/deps/libsyn-b00a444c8aa4acf3.rlib --extern quote=/home/jwolfe/Rust/rust-zookeeper/target/release/deps/libquote-7cd2e6e51ec0ccc5.rlib -Zverbose`
   Compiling zookeeper v0.3.0 (file:///home/jwolfe/Rust/rust-zookeeper)
     Running `rustc --crate-name zookeeper src/lib.rs --crate-type lib --emit=dep-info,link -C opt-level=3 -C metadata=b5a475f1c342e7c6 -C extra-filename=-b5a475f1c342e7c6 --out-dir /home/jwolfe/Rust/rust-zookeeper/target/release/deps -L dependency=/home/jwolfe/Rust/rust-zookeeper/target/release/deps --extern snowflake=/home/jwolfe/Rust/rust-zookeeper/target/release/deps/libsnowflake-e9a06768725f9ce6.rlib --extern bytes=/home/jwolfe/Rust/rust-zookeeper/target/release/deps/libbytes-896568c95020390b.rlib --extern byteorder=/home/jwolfe/Rust/rust-zookeeper/target/release/deps/libbyteorder-549a4dbae79b4adf.rlib --extern zookeeper_derive=/home/jwolfe/Rust/rust-zookeeper/target/release/deps/libzookeeper_derive-3d948e35b92c7695.so --extern log=/home/jwolfe/Rust/rust-zookeeper/target/release/deps/liblog-03d566855f19b793.rlib --extern mio=/home/jwolfe/Rust/rust-zookeeper/target/release/deps/libmio-c1cb259295b5b695.rlib --extern lazy_static=/home/jwolfe/Rust/rust-zookeeper/target/release/deps/liblazy_static-a9194fff651d7463.rlib -Zverbose`
error: /home/jwolfe/Rust/rust-zookeeper/target/release/deps/libzookeeper_derive-3d948e35b92c7695.so: undefined symbol: _ZN116_$LT$alloc..string..String$u20$as$u20$core..convert..From$LT$$RF$ReEarlyBound$LP$0$C$$u20$$u27$a$RP$$u20$str$GT$$GT$4from17h3156f71d21fd9c11E
  --> src/lib.rs:11:1
   |
11 | extern crate zookeeper_derive;
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: Could not compile `zookeeper`.

I was surprised to see something entirely different than the error I see without the debug flag, the surprising part to me being

error: /home/jwolfe/Rust/rust-zookeeper/target/release/deps/libzookeeper_derive-3d948e35b92c7695.so: undefined symbol: _ZN116_$LT$alloc..string..String$u20$as$u20$core..convert..From$LT$$RF$ReEarlyBound$LP$0$C$$u20$$u27$a$RP$$u20$str$GT$$GT$4from17h3156f71d21fd9c11E

@fulmicoton
Copy link

Here is a minimum code to reproduce.

https://github.com/fulmicoton/bug_known_bits/blob/master/src/lib.rs

To reproduce you can clone the repo and run cargo build --release.

@fulmicoton
Copy link

Here is the last pass that makes LLVM unhappy.

*** IR Dump Before Early CSE ***
; Function Attrs: uwtable
define i32 @_ZN3lib16bugging_function17hab1ad2b68c3d5905E(i32) unnamed_addr #2 {
start:
  %1 = icmp ult i32 %0, 3
  call void @llvm.assume(i1 %1)
  %2 = xor i32 %0, -1
  %.off.i = add i32 %2, -1
  %switch.i = icmp ult i32 %.off.i, 2
  br i1 %switch.i, label %_ZN3lib8from_u3217hcbd3743a2503d713E.exit, label %bb3.i

bb3.i:                                            ; preds = %start
  call fastcc void @_ZN3std9panicking11begin_panic17h684cdffa117ea7c2E()
  unreachable

_ZN3lib8from_u3217hcbd3743a2503d713E.exit:        ; preds = %start
  %3 = icmp ult i32 %2, 3
  call void @llvm.assume(i1 %3)
  %4 = or i32 %2, 1
  ret i32 %4
}

LLVM's value checker is correct to infer that some of the bits in the second branch are supposed to be both 0 and 1... The conclusion is however wrong : the branch is simply unreachable.

@fulmicoton
Copy link

Same error without any panics! nor any enum.

#![feature(core_intrinsics)]

extern crate core;
use core::intrinsics::assume;

#[inline(always)]
pub fn from_u32(v: u32) -> Option<u32> {
    if v >= 1 && v <= 2u32 {
        Some(v)
    } else {
        None
    }
}

pub fn bugging_function(v: bool) -> u32 {
    let input: u32 = if v { 1 } else { 2 };
    if let Some(nval) =  from_u32(!input) {
        unsafe {
            assume(nval >= 1);
            assume(nval <= 2);
        }
        return nval;
    }
    0u32
}

@arielb1
Copy link
Contributor

arielb1 commented Nov 7, 2017

This crashes our LLVM with -early-cse set, but doesn't crash any of the debian llvms

; Function Attrs: nounwind
declare void @llvm.assume(i1)

; Function Attrs: nounwind uwtable
define i32 @_ZN3ice16bugging_function17hec6c566c29298c46E(i1 zeroext) unnamed_addr #0 {
start:
  %. = select i1 %0, i32 -2, i32 -3
  %.off.i = add i32 %., -1
  %1 = icmp ult i32 %.off.i, 2
  %_0.sroa.0.0.i = zext i1 %1 to i64
  %_0.sroa.3.0.insert.ext.i = zext i32 %. to i64
  %_0.sroa.3.0.insert.shift.i = shl nuw i64 %_0.sroa.3.0.insert.ext.i, 32
  %_0.sroa.0.0.insert.insert.i = or i64 %_0.sroa.0.0.i, %_0.sroa.3.0.insert.shift.i
  %abi_cast.sroa.4.0.extract.shift = lshr i64 %_0.sroa.0.0.insert.insert.i, 32
  %abi_cast.sroa.4.0.extract.trunc = trunc i64 %abi_cast.sroa.4.0.extract.shift to i32
  %2 = and i64 %_0.sroa.0.0.insert.insert.i, 4294967295
  %cond = icmp eq i64 %2, 1
  br i1 %cond, label %bb6, label %bb9

bb6:                                              ; preds = %start
  %3 = icmp ne i32 %abi_cast.sroa.4.0.extract.trunc, 0
  call void @llvm.assume(i1 %3)
  %4 = icmp ult i32 %abi_cast.sroa.4.0.extract.trunc, 3
  call void @llvm.assume(i1 %4)
  br label %bb9

bb9:                                              ; preds = %start, %bb6
  %_0.0 = phi i32 [ %abi_cast.sroa.4.0.extract.trunc, %bb6 ], [ 0, %start ]
  ret i32 %_0.0
}

@arielb1
Copy link
Contributor

arielb1 commented Nov 7, 2017

Minified:

; Function Attrs: nounwind
declare void @llvm.assume(i1)

; Function Attrs: nounwind uwtable
define i64 @icey(i1 zeroext) {
start:
  %. = select i1 %0, i64 -1, i64 -2
  %_4 = icmp eq i64 %., 0
  call void @llvm.assume(i1 %_4)

  ret i64 %.
}

@arielb1
Copy link
Contributor

arielb1 commented Nov 7, 2017

Looks like https://bugs.llvm.org/show_bug.cgi?id=31809 - there's a fix in upstream LLVM, which we can backport.

@nikic
Copy link
Contributor

nikic commented Nov 3, 2018

I believe this can be closed, as the fix landed upstream and our LLVM has since been updated. Also can't repro with #44899 (comment) anymore.

@fulmicoton
Copy link

I confirm that this seems fixed.

@kamyuentse
Copy link
Author

Thanks @fulmicoton , I am closing this now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants