Constant propagation for vector SGT/UGE/UGT

Constant rounding (and fixed vec128 rounding only doing x)
This commit is contained in:
Dr. Chat 2016-07-25 11:57:14 -05:00
parent 91be5f979e
commit a72f1d949f
3 changed files with 166 additions and 2 deletions

View File

@ -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);

View File

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

View File

@ -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);