Add x86 SIMD legalizations for icmp less-than

This commit is contained in:
Andrew Brown
2019-10-25 11:18:26 -07:00
parent ce67ea5d58
commit af4637aff6
2 changed files with 59 additions and 11 deletions

View File

@@ -509,34 +509,42 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
); );
} }
// SIMD icmp ugt // SIMD icmp greater-/less-than
let sgt = Literal::enumerator_for(&imm.intcc, "sgt");
let ugt = Literal::enumerator_for(&imm.intcc, "ugt"); let ugt = Literal::enumerator_for(&imm.intcc, "ugt");
let sge = Literal::enumerator_for(&imm.intcc, "sge");
let uge = Literal::enumerator_for(&imm.intcc, "uge");
let slt = Literal::enumerator_for(&imm.intcc, "slt");
let ult = Literal::enumerator_for(&imm.intcc, "ult");
let sle = Literal::enumerator_for(&imm.intcc, "sle");
let ule = Literal::enumerator_for(&imm.intcc, "ule");
for ty in &[I8, I16, I32] { for ty in &[I8, I16, I32] {
// greater-than
let icmp_ = icmp.bind(vector(*ty, sse_vector_size)); let icmp_ = icmp.bind(vector(*ty, sse_vector_size));
narrow.legalize( narrow.legalize(
def!(c = icmp_(ugt, a, b)), def!(c = icmp_(ugt, a, b)),
vec![def!(x = x86_pmaxu(a, b)), def!(c = icmp(eq, a, x))], vec![def!(x = x86_pmaxu(a, b)), def!(c = icmp(eq, a, x))],
); );
}
// SIMD icmp sge
let sge = Literal::enumerator_for(&imm.intcc, "sge");
for ty in &[I8, I16, I32] {
let icmp_ = icmp.bind(vector(*ty, sse_vector_size)); let icmp_ = icmp.bind(vector(*ty, sse_vector_size));
narrow.legalize( narrow.legalize(
def!(c = icmp_(sge, a, b)), def!(c = icmp_(sge, a, b)),
vec![def!(x = x86_pmins(a, b)), def!(c = icmp(eq, x, b))], vec![def!(x = x86_pmins(a, b)), def!(c = icmp(eq, x, b))],
); );
}
// SIMD icmp uge
let uge = Literal::enumerator_for(&imm.intcc, "uge");
for ty in &[I8, I16, I32] {
let icmp_ = icmp.bind(vector(*ty, sse_vector_size)); let icmp_ = icmp.bind(vector(*ty, sse_vector_size));
narrow.legalize( narrow.legalize(
def!(c = icmp_(uge, a, b)), def!(c = icmp_(uge, a, b)),
vec![def!(x = x86_pminu(a, b)), def!(c = icmp(eq, x, b))], vec![def!(x = x86_pminu(a, b)), def!(c = icmp(eq, x, b))],
); );
// less-than
let icmp_ = icmp.bind(vector(*ty, sse_vector_size));
narrow.legalize(def!(c = icmp_(slt, a, b)), vec![def!(c = icmp(sgt, b, a))]);
let icmp_ = icmp.bind(vector(*ty, sse_vector_size));
narrow.legalize(def!(c = icmp_(ult, a, b)), vec![def!(c = icmp(ugt, b, a))]);
let icmp_ = icmp.bind(vector(*ty, sse_vector_size));
narrow.legalize(def!(c = icmp_(sle, a, b)), vec![def!(c = icmp(sge, b, a))]);
let icmp_ = icmp.bind(vector(*ty, sse_vector_size));
narrow.legalize(def!(c = icmp_(ule, a, b)), vec![def!(c = icmp(uge, b, a))]);
} }
narrow.custom_legalize(shuffle, "convert_shuffle"); narrow.custom_legalize(shuffle, "convert_shuffle");

View File

@@ -137,3 +137,43 @@ ebb0:
return v8 return v8
} }
; run ; run
function %icmp_slt_i32x4() -> b1 {
ebb0:
v0 = vconst.i32x4 [-1 1 1 1]
v1 = vconst.i32x4 [1 2 3 4]
v2 = icmp slt v0, v1
v8 = vall_true v2
return v8
}
; run
function %icmp_ult_i32x4() -> b1 {
ebb0:
v0 = vconst.i32x4 [1 1 1 1]
v1 = vconst.i32x4 [-1 2 3 4] ; -1 = 0xffff... will be greater than 1 when unsigned
v2 = icmp ult v0, v1
v8 = vall_true v2
return v8
}
; run
function %icmp_sle_i16x8() -> b1 {
ebb0:
v0 = vconst.i16x8 [-1 -1 0 0 0 0 0 0]
v1 = vconst.i16x8 [-1 0 0 0 0 0 0 0]
v2 = icmp sle v0, v1
v8 = vall_true v2
return v8
}
; run
function %icmp_ule_i16x8() -> b1 {
ebb0:
v0 = vconst.i16x8 [-1 0 0 0 0 0 0 0]
v1 = vconst.i16x8 [-1 -1 0 0 0 0 0 0]
v2 = icmp ule v0, v1
v8 = vall_true v2
return v8
}
; run