Fix icmp_imm.i128

The immediate splitting code contained a bug causing both low and high
to be equal for i128. This is the root cause for
bjorn3/rustc_codegen_cranelift#1097 and likely the only bug preventing
cg_clif from bootstrapping rustc.
This commit is contained in:
bjorn3
2020-10-31 19:22:32 +01:00
parent 53f044715b
commit 23aafa1054
2 changed files with 29 additions and 6 deletions

View File

@@ -774,12 +774,12 @@ fn narrow_icmp_imm(
let ty = pos.func.dfg.ctrl_typevar(inst); let ty = pos.func.dfg.ctrl_typevar(inst);
let ty_half = ty.half_width().unwrap(); let ty_half = ty.half_width().unwrap();
let imm_low = pos let mask = ((1u128 << ty_half.bits()) - 1) as i64;
.ins() let imm_low = pos.ins().iconst(ty_half, imm & mask);
.iconst(ty_half, imm & ((1u128 << ty_half.bits()) - 1) as i64); let imm_high = pos.ins().iconst(
let imm_high = pos ty_half,
.ins() imm.checked_shr(ty_half.bits().into()).unwrap_or(0) & mask,
.iconst(ty_half, imm.wrapping_shr(ty_half.bits().into())); );
let (arg_low, arg_high) = pos.ins().isplit(arg); let (arg_low, arg_high) = pos.ins().isplit(arg);
match cond { match cond {

View File

@@ -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: }