diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/abstract.h | 10 | ||||
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 14 |
2 files changed, 24 insertions, 0 deletions
diff --git a/src/ir/abstract.h b/src/ir/abstract.h index ac67a59b3..1cd51b9ba 100644 --- a/src/ir/abstract.h +++ b/src/ir/abstract.h @@ -40,6 +40,8 @@ enum Op { Shl, ShrU, ShrS, + RotL, + RotR, And, Or, Xor, @@ -137,6 +139,10 @@ inline BinaryOp getBinary(Type type, Op op) { return ShrUInt32; case ShrS: return ShrSInt32; + case RotL: + return RotLInt32; + case RotR: + return RotRInt32; case And: return AndInt32; case Or: @@ -190,6 +196,10 @@ inline BinaryOp getBinary(Type type, Op op) { return ShrUInt64; case ShrS: return ShrSInt64; + case RotL: + return RotLInt64; + case RotR: + return RotRInt64; case And: return AndInt64; case Or: diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 3b7a9dc6d..869512774 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -1397,6 +1397,20 @@ private: return right; } { + // ~(1 << x) aka (1 << x) ^ -1 ==> rotl(-2, x) + Expression* x; + if (matches(curr, + binary(Abstract::Xor, + binary(Abstract::Shl, ival(1), any(&x)), + ival(-1)))) { + curr->op = Abstract::getBinary(type, Abstract::RotL); + right->value = Literal::makeFromInt32(-2, type); + curr->left = right; + curr->right = x; + return curr; + } + } + { // Wasm binary encoding uses signed LEBs, which slightly favor negative // numbers: -64 is more efficient than +64 etc., as well as other powers // of two 7 bits etc. higher. we therefore prefer x - -64 over x + 64. in |