diff --git a/examples/example.rs b/examples/example.rs index ecc5db5c0db1..05b370f91e08 100644 --- a/examples/example.rs +++ b/examples/example.rs @@ -150,3 +150,7 @@ fn use_array(arr: [u8; 3]) -> u8 { fn repeat_array() -> [u8; 3] { [0; 3] } + +unsafe fn use_ctlz_nonzero(a: u16) -> u16 { + intrinsics::ctlz_nonzero(a) +} diff --git a/examples/mini_core.rs b/examples/mini_core.rs index dc19d66b2144..17d321db345d 100644 --- a/examples/mini_core.rs +++ b/examples/mini_core.rs @@ -139,6 +139,7 @@ pub mod intrinsics { pub fn copy(src: *const T, dst: *mut T, count: usize); pub fn transmute(e: T) -> U; pub fn uninit() -> T; + pub fn ctlz_nonzero(x: T) -> T; } } diff --git a/src/abi.rs b/src/abi.rs index 929002f0e803..0d44952dc0d5 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -500,6 +500,24 @@ pub fn codegen_call<'a, 'tcx: 'a>( let uninit_val = uninit_place.to_cvalue(fx); ret.write_cvalue(fx, uninit_val); } + "ctlz" | "ctlz_nonzero" => { + assert_eq!(args.len(), 1); + let arg = args[0].load_value(fx); + let res = CValue::ByVal(fx.bcx.ins().clz(arg), args[0].layout()); + ret.write_cvalue(fx, res); + } + "cttz" | "cttz_nonzero" => { + assert_eq!(args.len(), 1); + let arg = args[0].load_value(fx); + let res = CValue::ByVal(fx.bcx.ins().clz(arg), args[0].layout()); + ret.write_cvalue(fx, res); + } + "ctpop" => { + assert_eq!(args.len(), 1); + let arg = args[0].load_value(fx); + let res = CValue::ByVal(fx.bcx.ins().popcnt(arg), args[0].layout()); + ret.write_cvalue(fx, res); + } _ => fx .tcx .sess diff --git a/src/base.rs b/src/base.rs index d479e9350686..31be6e58f420 100644 --- a/src/base.rs +++ b/src/base.rs @@ -359,7 +359,8 @@ fn trans_stmt<'a, 'tcx: 'a>( UnOp::Not => fx.bcx.ins().bnot(val), UnOp::Neg => match ty.sty { TypeVariants::TyInt(_) => { - let zero = fx.bcx.ins().iconst(types::I64, 0); + let clif_ty = fx.cton_type(ty).unwrap(); + let zero = fx.bcx.ins().iconst(clif_ty, 0); fx.bcx.ins().isub(zero, val) } TypeVariants::TyFloat(_) => fx.bcx.ins().fneg(val),