diff --git a/cranelift/codegen/src/legalizer/mod.rs b/cranelift/codegen/src/legalizer/mod.rs index 3b33e55b1e..1900b144ce 100644 --- a/cranelift/codegen/src/legalizer/mod.rs +++ b/cranelift/codegen/src/legalizer/mod.rs @@ -774,12 +774,12 @@ fn narrow_icmp_imm( let ty = pos.func.dfg.ctrl_typevar(inst); let ty_half = ty.half_width().unwrap(); - let imm_low = pos - .ins() - .iconst(ty_half, imm & ((1u128 << ty_half.bits()) - 1) as i64); - let imm_high = pos - .ins() - .iconst(ty_half, imm.wrapping_shr(ty_half.bits().into())); + let mask = ((1u128 << ty_half.bits()) - 1) as i64; + let imm_low = pos.ins().iconst(ty_half, imm & mask); + let imm_high = pos.ins().iconst( + ty_half, + imm.checked_shr(ty_half.bits().into()).unwrap_or(0) & mask, + ); let (arg_low, arg_high) = pos.ins().isplit(arg); match cond { diff --git a/cranelift/filetests/filetests/legalizer/icmp_imm_i128.clif b/cranelift/filetests/filetests/legalizer/icmp_imm_i128.clif new file mode 100644 index 0000000000..56e54fa1c3 --- /dev/null +++ b/cranelift/filetests/filetests/legalizer/icmp_imm_i128.clif @@ -0,0 +1,23 @@ +test legalizer +target x86_64 + +function %icmp_imm_i128(i128) -> i8 { +block0(v0: i128): + v1 = icmp_imm.i128 eq v0, 1 + v2 = bint.i8 v1 + return v2 +} + +; check: function %icmp_imm_i128(i64 [%rdi], i64 [%rsi]) -> i8 [%rax] fast { +; nextln: block0(v3: i64, v4: i64): +; nextln: v7 -> v3 +; nextln: v8 -> v4 +; nextln: [-] v0 = iconcat v3, v4 +; nextln: [RexOp1pu_id#b8] v5 = iconst.i64 1 +; nextln: [RexOp1pu_id#b8] v6 = iconst.i64 0 +; nextln: [RexOp1icscc#8039] v9 = icmp eq v7, v5 +; nextln: [RexOp1icscc#8039] v10 = icmp eq v8, v6 +; nextln: [RexOp1rr#21] v1 = band v9, v10 +; nextln: [RexOp2urm_noflags#4b6] v2 = bint.i8 v1 +; nextln: [Op1ret#c3] return v2 +; nextln: }