Constant propagation for vector SGT/UGE/UGT
Constant rounding (and fixed vec128 rounding only doing x)
This commit is contained in:
parent
91be5f979e
commit
a72f1d949f
|
@ -607,6 +607,27 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) {
|
|||
i->Remove();
|
||||
}
|
||||
break;
|
||||
case OPCODE_VECTOR_COMPARE_SGE:
|
||||
if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) {
|
||||
v->set_from(i->src1.value);
|
||||
v->VectorCompareSGE(i->src2.value, hir::TypeName(i->flags));
|
||||
i->Remove();
|
||||
}
|
||||
break;
|
||||
case OPCODE_VECTOR_COMPARE_UGT:
|
||||
if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) {
|
||||
v->set_from(i->src1.value);
|
||||
v->VectorCompareUGT(i->src2.value, hir::TypeName(i->flags));
|
||||
i->Remove();
|
||||
}
|
||||
break;
|
||||
case OPCODE_VECTOR_COMPARE_UGE:
|
||||
if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) {
|
||||
v->set_from(i->src1.value);
|
||||
v->VectorCompareUGE(i->src2.value, hir::TypeName(i->flags));
|
||||
i->Remove();
|
||||
}
|
||||
break;
|
||||
case OPCODE_VECTOR_CONVERT_F2I:
|
||||
if (i->src1.value->IsConstant()) {
|
||||
v->set_zero(VEC128_TYPE);
|
||||
|
|
|
@ -248,22 +248,57 @@ void Value::Round(RoundMode round_mode) {
|
|||
switch (type) {
|
||||
case FLOAT32_TYPE:
|
||||
switch (round_mode) {
|
||||
case ROUND_TO_ZERO:
|
||||
constant.f32 = std::trunc(constant.f32);
|
||||
break;
|
||||
case ROUND_TO_NEAREST:
|
||||
constant.f32 = std::round(constant.f32);
|
||||
return;
|
||||
case ROUND_TO_MINUS_INFINITY:
|
||||
constant.f32 = std::floor(constant.f32);
|
||||
break;
|
||||
case ROUND_TO_POSITIVE_INFINITY:
|
||||
constant.f32 = std::ceil(constant.f32);
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(round_mode);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
case FLOAT64_TYPE:
|
||||
switch (round_mode) {
|
||||
case ROUND_TO_ZERO:
|
||||
constant.f64 = std::trunc(constant.f64);
|
||||
break;
|
||||
case ROUND_TO_NEAREST:
|
||||
constant.f64 = std::round(constant.f64);
|
||||
return;
|
||||
case ROUND_TO_MINUS_INFINITY:
|
||||
constant.f64 = std::floor(constant.f64);
|
||||
break;
|
||||
case ROUND_TO_POSITIVE_INFINITY:
|
||||
constant.f64 = std::ceil(constant.f64);
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(round_mode);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
case VEC128_TYPE:
|
||||
for (int i = 0; i < 4; i++) {
|
||||
switch (round_mode) {
|
||||
case ROUND_TO_ZERO:
|
||||
constant.v128.f32[i] = std::trunc(constant.v128.f32[i]);
|
||||
break;
|
||||
case ROUND_TO_NEAREST:
|
||||
constant.v128.f32[i] = std::round(constant.v128.f32[i]);
|
||||
return;
|
||||
break;
|
||||
case ROUND_TO_MINUS_INFINITY:
|
||||
constant.v128.f32[i] = std::floor(constant.v128.f32[i]);
|
||||
break;
|
||||
case ROUND_TO_POSITIVE_INFINITY:
|
||||
constant.v128.f32[i] = std::ceil(constant.v128.f32[i]);
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(round_mode);
|
||||
return;
|
||||
|
@ -920,16 +955,121 @@ void Value::VectorCompareSGT(Value* other, TypeName type) {
|
|||
constant.v128.i32[i] > other->constant.v128.i32[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
case INT64_TYPE:
|
||||
for (int i = 0; i < 2; i++) {
|
||||
constant.v128.u64[i] =
|
||||
constant.v128.i64[i] > other->constant.v128.i64[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
case FLOAT32_TYPE:
|
||||
for (int i = 0; i < 4; i++) {
|
||||
constant.v128.u32[i] =
|
||||
constant.v128.f32[i] > other->constant.v128.f32[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Value::VectorCompareSGE(Value* other, TypeName type) {
|
||||
assert_true(this->type == VEC128_TYPE && other->type == VEC128_TYPE);
|
||||
switch (type) {
|
||||
case INT8_TYPE:
|
||||
for (int i = 0; i < 16; i++) {
|
||||
constant.v128.u8[i] =
|
||||
constant.v128.i8[i] >= other->constant.v128.i8[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
case INT16_TYPE:
|
||||
for (int i = 0; i < 8; i++) {
|
||||
constant.v128.u16[i] =
|
||||
constant.v128.i16[i] >= other->constant.v128.i16[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
case INT32_TYPE:
|
||||
for (int i = 0; i < 4; i++) {
|
||||
constant.v128.u32[i] =
|
||||
constant.v128.i32[i] >= other->constant.v128.i32[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
case INT64_TYPE:
|
||||
for (int i = 0; i < 2; i++) {
|
||||
constant.v128.u64[i] =
|
||||
constant.v128.i64[i] > other->constant.v128.i64[i] ? -1 : 0;
|
||||
constant.v128.i64[i] >= other->constant.v128.i64[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
case FLOAT32_TYPE:
|
||||
for (int i = 0; i < 4; i++) {
|
||||
constant.v128.u32[i] =
|
||||
constant.v128.f32[i] >= other->constant.v128.f32[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Value::VectorCompareUGT(Value* other, TypeName type) {
|
||||
assert_true(this->type == VEC128_TYPE && other->type == VEC128_TYPE);
|
||||
switch (type) {
|
||||
case INT8_TYPE:
|
||||
for (int i = 0; i < 16; i++) {
|
||||
constant.v128.u8[i] =
|
||||
constant.v128.u8[i] > other->constant.v128.u8[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
case INT16_TYPE:
|
||||
for (int i = 0; i < 8; i++) {
|
||||
constant.v128.u16[i] =
|
||||
constant.v128.u16[i] > other->constant.v128.u16[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
case INT32_TYPE:
|
||||
for (int i = 0; i < 4; i++) {
|
||||
constant.v128.u32[i] =
|
||||
constant.v128.u32[i] > other->constant.v128.u32[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
case INT64_TYPE:
|
||||
for (int i = 0; i < 2; i++) {
|
||||
constant.v128.u64[i] =
|
||||
constant.v128.u64[i] > other->constant.v128.u64[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Value::VectorCompareUGE(Value* other, TypeName type) {
|
||||
assert_true(this->type == VEC128_TYPE && other->type == VEC128_TYPE);
|
||||
switch (type) {
|
||||
case INT8_TYPE:
|
||||
for (int i = 0; i < 16; i++) {
|
||||
constant.v128.u8[i] =
|
||||
constant.v128.u8[i] >= other->constant.v128.u8[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
case INT16_TYPE:
|
||||
for (int i = 0; i < 8; i++) {
|
||||
constant.v128.u16[i] =
|
||||
constant.v128.u16[i] >= other->constant.v128.u16[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
case INT32_TYPE:
|
||||
for (int i = 0; i < 4; i++) {
|
||||
constant.v128.u32[i] =
|
||||
constant.v128.u32[i] >= other->constant.v128.u32[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
case INT64_TYPE:
|
||||
for (int i = 0; i < 2; i++) {
|
||||
constant.v128.u64[i] =
|
||||
constant.v128.u64[i] >= other->constant.v128.u64[i] ? -1 : 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -500,6 +500,9 @@ class Value {
|
|||
void Splat(Value* other);
|
||||
void VectorCompareEQ(Value* other, TypeName type);
|
||||
void VectorCompareSGT(Value* other, TypeName type);
|
||||
void VectorCompareSGE(Value* other, TypeName type);
|
||||
void VectorCompareUGT(Value* other, TypeName type);
|
||||
void VectorCompareUGE(Value* other, TypeName type);
|
||||
void VectorConvertI2F(Value* other);
|
||||
void VectorConvertF2I(Value* other);
|
||||
void VectorShl(Value* other, TypeName type);
|
||||
|
|
Loading…
Reference in New Issue