diff --git a/src/common.rs b/src/common.rs index fb030470936a..54c393e2824f 100644 --- a/src/common.rs +++ b/src/common.rs @@ -69,6 +69,21 @@ pub fn cton_type_from_ty<'a, 'tcx: 'a>( }) } +pub fn codegen_select(bcx: &mut FunctionBuilder, cond: Value, lhs: Value, rhs: Value) -> Value { + let lhs_ty = bcx.func.dfg.value_type(lhs); + let rhs_ty = bcx.func.dfg.value_type(rhs); + assert_eq!(lhs_ty, rhs_ty); + if lhs_ty == types::I8 || lhs_ty == types::I16 { + // FIXME workaround for missing enocding for select.i8 + let lhs = bcx.ins().uextend(types::I32, lhs); + let rhs = bcx.ins().uextend(types::I32, rhs); + let res = bcx.ins().select(cond, lhs, rhs); + bcx.ins().ireduce(lhs_ty, res) + } else { + bcx.ins().select(cond, lhs, rhs) + } +} + fn codegen_field<'a, 'tcx: 'a>( fx: &mut FunctionCx<'a, 'tcx, impl Backend>, base: Value, diff --git a/src/intrinsics.rs b/src/intrinsics.rs index 1cc16419413c..79ed21ce3112 100644 --- a/src/intrinsics.rs +++ b/src/intrinsics.rs @@ -76,7 +76,7 @@ macro_rules! atomic_minmax { // Compare let is_eq = $fx.bcx.ins().icmp(IntCC::SignedGreaterThan, old, $src); - let new = $fx.bcx.ins().select(is_eq, old, $src); + let new = crate::common::codegen_select(&mut $fx.bcx, is_eq, old, $src); // Write new $fx.bcx.ins().store(MemFlags::new(), new, $ptr, 0); @@ -378,7 +378,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>( // Compare let is_eq = fx.bcx.ins().icmp(IntCC::Equal, old, test_old); - let new = fx.bcx.ins().select(is_eq, old, new); // Keep old if not equal to test_old + let new = crate::common::codegen_select(&mut fx.bcx, is_eq, old, new); // Keep old if not equal to test_old // Write new fx.bcx.ins().store(MemFlags::new(), new, ptr, 0);