[codegen] legalize icmp for 64 and 128 bit operands

Add legalizations for icmp and icmp_imm for i64 and i128 operands for
the narrow legalization set, allowing 32-bit ISAs (like x86-32) to
compare 64-bit integers and all ISAs to compare 128-bit integers.

Fixes: https://github.com/bnjbvr/cranelift-x86/issues/2
This commit is contained in:
Ujjwal Sharma
2019-09-26 21:59:56 +05:30
committed by Benjamin Bouvier
parent 19444649e7
commit c062f12d7c
5 changed files with 504 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
test run
target x86_64 haswell
function %test_icmp_eq_i128() -> b1 {
ebb0:
v11 = iconst.i64 0x0
v12 = iconst.i64 0x0
v1 = iconcat v11, v12
v21 = iconst.i64 0x0
v22 = iconst.i64 0x0
v2 = iconcat v21, v22
v10 = icmp.i128 eq v1, v2
return v10
}
; run
function %test_icmp_imm_eq_i128() -> b1 {
ebb0:
v11 = iconst.i64 0x0
v12 = iconst.i64 0x0
v1 = iconcat v11, v12
v10 = icmp_imm.i128 eq v1, 0x0
return v10
}
; run
function %test_icmp_ne_i128() -> b1 {
ebb0:
v11 = iconst.i64 0x0
v12 = iconst.i64 0x0
v1 = iconcat v11, v12
v21 = iconst.i64 0x0
v22 = iconst.i64 0x1
v2 = iconcat v21, v22
v10 = icmp.i128 ne v1, v2
return v10
}
; run
function %test_icmp_imm_ne_i128() -> b1 {
ebb0:
v11 = iconst.i64 0x0
v12 = iconst.i64 0x0
v1 = iconcat v11, v12
v10 = icmp_imm.i128 ne v1, 0x1
return v10
}
; run

View File

@@ -25,3 +25,301 @@ ebb0(v1: i64, v2: i64):
; nextln: v10 = iconcat $v10_lsb, $v10_msb
return v10
}
function %icmp_eq(i64, i64) -> b1 {
ebb0(v1: i64, v2: i64):
v10 = icmp eq v1, v2
; check: v1 = iconcat $(v1_lsb=$V), $(v1_msb=$V)
; nextln: v2 = iconcat $(v2_lsb=$V), $(v2_msb=$V)
; nextln: $(v10_lsb=$V) = icmp eq $v1_lsb, $v2_lsb
; nextln: $(v10_msb=$V) = icmp eq $v1_msb, $v2_msb
; nextln: v10 = band $v10_lsb, $v10_msb
return v10
}
function %icmp_imm_eq(i64) -> b1 {
ebb0(v1: i64):
v10 = icmp_imm eq v1, 0
; check: $(v1_lsb=$V) -> $(v1_lsb_a=$V)
; nextln: $(v1_msb=$V) -> $(v1_msb_a=$V)
; nextln: v1 = iconcat $(v1_lsb_a=$V), $(v1_msb_a=$V)
; nextln: $(v2_lsb=$V) = iconst.i32 0
; nextln: $(v2_msb=$V) = iconst.i32 0
; nextln: $(v10_lsb=$V) = icmp eq $v1_lsb, $v2_lsb
; nextln: $(v10_msb=$V) = icmp eq $v1_msb, $v2_msb
; nextln: v10 = band $v10_lsb, $v10_msb
return v10
}
function %icmp_ne(i64, i64) -> b1 {
ebb0(v1: i64, v2: i64):
v10 = icmp ne v1, v2
; check: v1 = iconcat $(v1_lsb=$V), $(v1_msb=$V)
; nextln: v2 = iconcat $(v2_lsb=$V), $(v2_msb=$V)
; nextln: $(v10_lsb=$V) = icmp ne $v1_lsb, $v2_lsb
; nextln: $(v10_msb=$V) = icmp ne $v1_msb, $v2_msb
; nextln: v10 = bor $v10_lsb, $v10_msb
return v10
}
function %icmp_imm_ne(i64) -> b1 {
ebb0(v1: i64):
v10 = icmp_imm ne v1, 0
; check: $(v1_lsb=$V) -> $(v1_lsb_a=$V)
; nextln: $(v1_msb=$V) -> $(v1_msb_a=$V)
; nextln: v1 = iconcat $(v1_lsb_a=$V), $(v1_msb_a=$V)
; nextln: $(v2_lsb=$V) = iconst.i32 0
; nextln: $(v2_msb=$V) = iconst.i32 0
; nextln: $(v10_lsb=$V) = icmp ne $v1_lsb, $v2_lsb
; nextln: $(v10_msb=$V) = icmp ne $v1_msb, $v2_msb
; nextln: v10 = bor $v10_lsb, $v10_msb
return v10
}
function %icmp_sgt(i64, i64) -> b1 {
ebb0(v1: i64, v2: i64):
v10 = icmp sgt v1, v2
; check: v1 = iconcat $(v1_lsb=$V), $(v1_msb=$V)
; nextln: v2 = iconcat $(v2_lsb=$V), $(v2_msb=$V)
; nextln: $(b1=$V) = icmp sgt $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp slt $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp ugt $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}
function %icmp_imm_sgt(i64) -> b1 {
ebb0(v1: i64):
v10 = icmp_imm sgt v1, 0
; check: $(v1_lsb=$V) -> $(v1_lsb_a=$V)
; nextln: $(v1_msb=$V) -> $(v1_msb_a=$V)
; nextln: v1 = iconcat $(v1_lsb_a=$V), $(v1_msb_a=$V)
; nextln: $(v2_lsb=$V) = iconst.i32 0
; nextln: $(v2_msb=$V) = iconst.i32 0
; nextln: $(b1=$V) = icmp sgt $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp slt $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp ugt $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}
function %icmp_sge(i64, i64) -> b1 {
ebb0(v1: i64, v2: i64):
v10 = icmp sge v1, v2
; check: v1 = iconcat $(v1_lsb=$V), $(v1_msb=$V)
; nextln: v2 = iconcat $(v2_lsb=$V), $(v2_msb=$V)
; nextln: $(b1=$V) = icmp sgt $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp slt $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp uge $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}
function %icmp_imm_sge(i64) -> b1 {
ebb0(v1: i64):
v10 = icmp_imm sge v1, 0
; check: $(v1_lsb=$V) -> $(v1_lsb_a=$V)
; nextln: $(v1_msb=$V) -> $(v1_msb_a=$V)
; nextln: v1 = iconcat $(v1_lsb_a=$V), $(v1_msb_a=$V)
; nextln: $(v2_lsb=$V) = iconst.i32 0
; nextln: $(v2_msb=$V) = iconst.i32 0
; nextln: $(b1=$V) = icmp sgt $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp slt $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp uge $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}
function %icmp_slt(i64, i64) -> b1 {
ebb0(v1: i64, v2: i64):
v10 = icmp slt v1, v2
; check: v1 = iconcat $(v1_lsb=$V), $(v1_msb=$V)
; nextln: v2 = iconcat $(v2_lsb=$V), $(v2_msb=$V)
; nextln: $(b1=$V) = icmp slt $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp sgt $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp ult $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}
function %icmp_imm_slt(i64) -> b1 {
ebb0(v1: i64):
v10 = icmp_imm slt v1, 0
; check: $(v1_lsb=$V) -> $(v1_lsb_a=$V)
; nextln: $(v1_msb=$V) -> $(v1_msb_a=$V)
; nextln: v1 = iconcat $(v1_lsb_a=$V), $(v1_msb_a=$V)
; nextln: $(v2_lsb=$V) = iconst.i32 0
; nextln: $(v2_msb=$V) = iconst.i32 0
; nextln: $(b1=$V) = icmp slt $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp sgt $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp ult $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}
function %icmp_sle(i64, i64) -> b1 {
ebb0(v1: i64, v2: i64):
v10 = icmp sle v1, v2
; check: v1 = iconcat $(v1_lsb=$V), $(v1_msb=$V)
; nextln: v2 = iconcat $(v2_lsb=$V), $(v2_msb=$V)
; nextln: $(b1=$V) = icmp slt $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp sgt $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp ule $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}
function %icmp_imm_sle(i64) -> b1 {
ebb0(v1: i64):
v10 = icmp_imm sle v1, 0
; check: $(v1_lsb=$V) -> $(v1_lsb_a=$V)
; nextln: $(v1_msb=$V) -> $(v1_msb_a=$V)
; nextln: v1 = iconcat $(v1_lsb_a=$V), $(v1_msb_a=$V)
; nextln: $(v2_lsb=$V) = iconst.i32 0
; nextln: $(v2_msb=$V) = iconst.i32 0
; nextln: $(b1=$V) = icmp slt $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp sgt $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp ule $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}
function %icmp_ugt(i64, i64) -> b1 {
ebb0(v1: i64, v2: i64):
v10 = icmp ugt v1, v2
; check: v1 = iconcat $(v1_lsb=$V), $(v1_msb=$V)
; nextln: v2 = iconcat $(v2_lsb=$V), $(v2_msb=$V)
; nextln: $(b1=$V) = icmp ugt $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp ult $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp ugt $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}
function %icmp_imm_ugt(i64) -> b1 {
ebb0(v1: i64):
v10 = icmp_imm ugt v1, 0
; check: $(v1_lsb=$V) -> $(v1_lsb_a=$V)
; nextln: $(v1_msb=$V) -> $(v1_msb_a=$V)
; nextln: v1 = iconcat $(v1_lsb_a=$V), $(v1_msb_a=$V)
; nextln: $(v2_lsb=$V) = iconst.i32 0
; nextln: $(v2_msb=$V) = iconst.i32 0
; nextln: $(b1=$V) = icmp ugt $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp ult $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp ugt $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}
function %icmp_uge(i64, i64) -> b1 {
ebb0(v1: i64, v2: i64):
v10 = icmp uge v1, v2
; check: v1 = iconcat $(v1_lsb=$V), $(v1_msb=$V)
; nextln: v2 = iconcat $(v2_lsb=$V), $(v2_msb=$V)
; nextln: $(b1=$V) = icmp ugt $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp ult $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp uge $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}
function %icmp_imm_uge(i64) -> b1 {
ebb0(v1: i64):
v10 = icmp_imm uge v1, 0
; check: $(v1_lsb=$V) -> $(v1_lsb_a=$V)
; nextln: $(v1_msb=$V) -> $(v1_msb_a=$V)
; nextln: v1 = iconcat $(v1_lsb_a=$V), $(v1_msb_a=$V)
; nextln: $(v2_lsb=$V) = iconst.i32 0
; nextln: $(v2_msb=$V) = iconst.i32 0
; nextln: $(b1=$V) = icmp ugt $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp ult $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp uge $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}
function %icmp_ult(i64, i64) -> b1 {
ebb0(v1: i64, v2: i64):
v10 = icmp ult v1, v2
; check: v1 = iconcat $(v1_lsb=$V), $(v1_msb=$V)
; nextln: v2 = iconcat $(v2_lsb=$V), $(v2_msb=$V)
; nextln: $(b1=$V) = icmp ult $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp ugt $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp ult $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}
function %icmp_imm_ult(i64) -> b1 {
ebb0(v1: i64):
v10 = icmp_imm ult v1, 0
; check: $(v1_lsb=$V) -> $(v1_lsb_a=$V)
; nextln: $(v1_msb=$V) -> $(v1_msb_a=$V)
; nextln: v1 = iconcat $(v1_lsb_a=$V), $(v1_msb_a=$V)
; nextln: $(v2_lsb=$V) = iconst.i32 0
; nextln: $(v2_msb=$V) = iconst.i32 0
; nextln: $(b1=$V) = icmp ult $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp ugt $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp ult $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}
function %icmp_ule(i64, i64) -> b1 {
ebb0(v1: i64, v2: i64):
v10 = icmp ule v1, v2
; check: v1 = iconcat $(v1_lsb=$V), $(v1_msb=$V)
; nextln: v2 = iconcat $(v2_lsb=$V), $(v2_msb=$V)
; nextln: $(b1=$V) = icmp ult $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp ugt $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp ule $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}
function %icmp_imm_ule(i64) -> b1 {
ebb0(v1: i64):
v10 = icmp_imm ule v1, 0
; check: $(v1_lsb=$V) -> $(v1_lsb_a=$V)
; nextln: $(v1_msb=$V) -> $(v1_msb_a=$V)
; nextln: v1 = iconcat $(v1_lsb_a=$V), $(v1_msb_a=$V)
; nextln: $(v2_lsb=$V) = iconst.i32 0
; nextln: $(v2_msb=$V) = iconst.i32 0
; nextln: $(b1=$V) = icmp ult $v1_msb, $v2_msb
; nextln: $(b2=$V) = icmp ugt $v1_msb, $v2_msb
; nextln: $(b3=$V) = icmp ule $v1_lsb, $v2_lsb
; nextln: $(c1=$V) = bnot $b2
; nextln: $(c2=$V) = band $c1, $b3
; nextln: v10 = bor $b1, $c2
return v10
}