summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/match.h43
-rw-r--r--src/passes/OptimizeInstructions.cpp7
-rw-r--r--test/example/match.cpp14
-rw-r--r--test/example/match.txt2
4 files changed, 52 insertions, 14 deletions
diff --git a/src/ir/match.h b/src/ir/match.h
index 2ab3afe65..0d8d3c20a 100644
--- a/src/ir/match.h
+++ b/src/ir/match.h
@@ -39,12 +39,12 @@ namespace Match {
// argument can be a specific value to match or it can be a pointer to a
// value, Literal, or Const* at which to store the matched entity.
//
-// ival, fval
+// bval, ival, fval
//
-// Match any integer constant or any floating point constant. Takes neither,
-// either, or both of two possible arguments: first, a pointer to a value,
-// Literal, or Const* at which to store the matched entity and second, a
-// specific value to match.
+// Match any boolean, any integer or any floating point constant. Takes
+// neither, either, or both of two possible arguments: first, a pointer to a
+// value, Literal, or Const* at which to store the matched entity and second,
+// a specific value to match.
//
// constant
//
@@ -395,7 +395,14 @@ template<class T> inline decltype(auto) Exact(T* binder, T data) {
return Matcher<ExactKind<T>>(binder, data);
}
-// {I32,I64,Int,F32,F64,Float,Number}Lit: match `Literal` of the expected `Type`
+// {Bool,I32,I64,Int,F32,F64,Float,Number}Lit:
+// match `Literal` of the expected `Type`
+struct BoolLK {
+ static bool matchType(Literal lit) {
+ return lit.type == Type::i32 && (uint32_t)lit.geti32() <= 1U;
+ }
+ static int32_t getVal(Literal lit) { return lit.geti32(); }
+};
struct I32LK {
static bool matchType(Literal lit) { return lit.type == Type::i32; }
static int32_t getVal(Literal lit) { return lit.geti32(); }
@@ -434,6 +441,9 @@ template<class T> struct NumComponents<LitKind<T>> {
template<class T> struct GetComponent<LitKind<T>, 0> {
decltype(auto) operator()(Literal lit) { return T::getVal(lit); }
};
+template<class S> inline decltype(auto) BoolLit(Literal* binder, S&& s) {
+ return Matcher<LitKind<BoolLK>, S>(binder, {}, s);
+}
template<class S> inline decltype(auto) I32Lit(Literal* binder, S&& s) {
return Matcher<LitKind<I32LK>, S>(binder, {}, s);
}
@@ -601,6 +611,27 @@ SelectMatcher(Select** binder, S1&& s1, S2&& s2, S3&& s3) {
// Public matching API
+inline decltype(auto) bval() {
+ return Internal::ConstMatcher(
+ nullptr, Internal::BoolLit(nullptr, Internal::Any<bool>(nullptr)));
+}
+inline decltype(auto) bval(bool x) {
+ return Internal::ConstMatcher(
+ nullptr, Internal::BoolLit(nullptr, Internal::Exact<bool>(nullptr, x)));
+}
+inline decltype(auto) bval(bool* binder) {
+ return Internal::ConstMatcher(
+ nullptr, Internal::BoolLit(nullptr, Internal::Any(binder)));
+}
+inline decltype(auto) bval(Literal* binder) {
+ return Internal::ConstMatcher(
+ nullptr, Internal::BoolLit(binder, Internal::Any<bool>(nullptr)));
+}
+inline decltype(auto) bval(Const** binder) {
+ return Internal::ConstMatcher(
+ binder, Internal::BoolLit(nullptr, Internal::Any<bool>(nullptr)));
+}
+
inline decltype(auto) i32() {
return Internal::ConstMatcher(
nullptr, Internal::I32Lit(nullptr, Internal::Any<int32_t>(nullptr)));
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index cc263d228..d18990e8e 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -3350,14 +3350,9 @@ private:
curr->ifTrue->type != Type::unreachable &&
curr->ifFalse->type != Type::unreachable) {
Unary* un;
- Expression* x;
Const* c;
auto check = [&](Expression* a, Expression* b) {
- if (matches(a, unary(&un, EqZ, any(&x))) && matches(b, ival(&c))) {
- auto value = c->value.getInteger();
- return value == 0 || value == 1;
- }
- return false;
+ return matches(b, bval(&c)) && matches(a, unary(&un, EqZ, any()));
};
if (check(curr->ifTrue, curr->ifFalse) ||
check(curr->ifFalse, curr->ifTrue)) {
diff --git a/test/example/match.cpp b/test/example/match.cpp
index 21bbbab98..125ce8e92 100644
--- a/test/example/match.cpp
+++ b/test/example/match.cpp
@@ -123,10 +123,11 @@ void test_internal_exact() {
}
void test_internal_literal() {
- std::cout << "Testing Internal::{I32,I64,Int,F32,F64,Float}Lit\n";
+ std::cout << "Testing Internal::{Bool,I32,I64,Int,F32,F64,Float}Lit\n";
Literal i32Zero(int32_t(0));
Literal i32One(int32_t(1));
+ Literal i32Two(int32_t(2));
Literal f32Zero(float(0));
Literal f32One(float(1));
Literal i64Zero(int64_t(0));
@@ -134,6 +135,17 @@ void test_internal_literal() {
Literal f64Zero(double(0));
Literal f64One(double(1));
+ auto anyBool = Internal::BoolLit(nullptr, Internal::Any<bool>(nullptr));
+ assert(anyBool.matches(i32Zero));
+ assert(anyBool.matches(i32One));
+ assert(!anyBool.matches(i32Two));
+ assert(!anyBool.matches(f32Zero));
+ assert(!anyBool.matches(f32One));
+ assert(!anyBool.matches(i64Zero));
+ assert(!anyBool.matches(i64One));
+ assert(!anyBool.matches(f64Zero));
+ assert(!anyBool.matches(f64One));
+
auto anyi32 = Internal::I32Lit(nullptr, Internal::Any<int32_t>(nullptr));
assert(anyi32.matches(i32Zero));
assert(anyi32.matches(i32One));
diff --git a/test/example/match.txt b/test/example/match.txt
index c4ad57d73..2a66f054e 100644
--- a/test/example/match.txt
+++ b/test/example/match.txt
@@ -1,6 +1,6 @@
Testing Internal::Any
Testing Internal::Exact
-Testing Internal::{I32,I64,Int,F32,F64,Float}Lit
+Testing Internal::{Bool,I32,I64,Int,F32,F64,Float}Lit
Testing Internal::ConstantMatcher
Testing Internal::UnaryMatcher
Testing Internal::UnaryOpMatcher