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();
|
i->Remove();
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case OPCODE_VECTOR_CONVERT_F2I:
|
||||||
if (i->src1.value->IsConstant()) {
|
if (i->src1.value->IsConstant()) {
|
||||||
v->set_zero(VEC128_TYPE);
|
v->set_zero(VEC128_TYPE);
|
||||||
|
|
|
@ -248,22 +248,57 @@ void Value::Round(RoundMode round_mode) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case FLOAT32_TYPE:
|
case FLOAT32_TYPE:
|
||||||
switch (round_mode) {
|
switch (round_mode) {
|
||||||
|
case ROUND_TO_ZERO:
|
||||||
|
constant.f32 = std::trunc(constant.f32);
|
||||||
|
break;
|
||||||
case ROUND_TO_NEAREST:
|
case ROUND_TO_NEAREST:
|
||||||
constant.f32 = std::round(constant.f32);
|
constant.f32 = std::round(constant.f32);
|
||||||
return;
|
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:
|
default:
|
||||||
assert_unhandled_case(round_mode);
|
assert_unhandled_case(round_mode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case FLOAT64_TYPE:
|
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;
|
return;
|
||||||
case VEC128_TYPE:
|
case VEC128_TYPE:
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
switch (round_mode) {
|
switch (round_mode) {
|
||||||
|
case ROUND_TO_ZERO:
|
||||||
|
constant.v128.f32[i] = std::trunc(constant.v128.f32[i]);
|
||||||
|
break;
|
||||||
case ROUND_TO_NEAREST:
|
case ROUND_TO_NEAREST:
|
||||||
constant.v128.f32[i] = std::round(constant.v128.f32[i]);
|
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:
|
default:
|
||||||
assert_unhandled_case(round_mode);
|
assert_unhandled_case(round_mode);
|
||||||
return;
|
return;
|
||||||
|
@ -920,16 +955,121 @@ void Value::VectorCompareSGT(Value* other, TypeName type) {
|
||||||
constant.v128.i32[i] > other->constant.v128.i32[i] ? -1 : 0;
|
constant.v128.i32[i] > other->constant.v128.i32[i] ? -1 : 0;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case FLOAT32_TYPE:
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
constant.v128.u32[i] =
|
constant.v128.u32[i] =
|
||||||
constant.v128.f32[i] > other->constant.v128.f32[i] ? -1 : 0;
|
constant.v128.f32[i] > other->constant.v128.f32[i] ? -1 : 0;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case INT64_TYPE:
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
constant.v128.u64[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;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -500,6 +500,9 @@ class Value {
|
||||||
void Splat(Value* other);
|
void Splat(Value* other);
|
||||||
void VectorCompareEQ(Value* other, TypeName type);
|
void VectorCompareEQ(Value* other, TypeName type);
|
||||||
void VectorCompareSGT(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 VectorConvertI2F(Value* other);
|
||||||
void VectorConvertF2I(Value* other);
|
void VectorConvertF2I(Value* other);
|
||||||
void VectorShl(Value* other, TypeName type);
|
void VectorShl(Value* other, TypeName type);
|
||||||
|
|
Loading…
Reference in New Issue