// -----------------------------------------------------------------------------
+// Word32Shl
+
+
+TEST_F(MachineOperatorReducerTest, Word32ShlWithZeroShift) {
+ Node* p0 = Parameter(0);
+ Node* node = graph()->NewNode(machine()->Word32Shl(), p0, Int32Constant(0));
+ Reduction r = Reduce(node);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(p0, r.replacement());
+}
+
+
+TEST_F(MachineOperatorReducerTest, Word32ShlWithWord32Sar) {
+ Node* p0 = Parameter(0);
+ TRACED_FORRANGE(int32_t, x, 1, 31) {
+ Node* node = graph()->NewNode(
+ machine()->Word32Shl(),
+ graph()->NewNode(machine()->Word32Sar(), p0, Int32Constant(x)),
+ Int32Constant(x));
+ Reduction r = Reduce(node);
+ ASSERT_TRUE(r.Changed());
+ int32_t m = bit_cast<int32_t>(~((1U << x) - 1U));
+ EXPECT_THAT(r.replacement(), IsWord32And(p0, IsInt32Constant(m)));
+ }
+}
+
+
+TEST_F(MachineOperatorReducerTest, Word32ShlWithWord32Shr) {
+ Node* p0 = Parameter(0);
+ TRACED_FORRANGE(int32_t, x, 1, 31) {
+ Node* node = graph()->NewNode(
+ machine()->Word32Shl(),
+ graph()->NewNode(machine()->Word32Shr(), p0, Int32Constant(x)),
+ Int32Constant(x));
+ Reduction r = Reduce(node);
+ ASSERT_TRUE(r.Changed());
+ int32_t m = bit_cast<int32_t>(~((1U << x) - 1U));
+ EXPECT_THAT(r.replacement(), IsWord32And(p0, IsInt32Constant(m)));
+ }
+}
+
+
+// -----------------------------------------------------------------------------
// Int32AddWithOverflow
if (m.IsFoldable()) { // K << K => K
return ReplaceInt32(m.left().Value() << m.right().Value());
}
+ if (m.right().IsInRange(1, 31)) {
+ // (x >>> K) << K => x & ~(2^K - 1)
+ // (x >> K) << K => x & ~(2^K - 1)
+ if (m.left().IsWord32Sar() || m.left().IsWord32Shr()) {
+ Int32BinopMatcher mleft(m.left().node());
+ if (mleft.right().Is(m.right().Value())) {
+ node->set_op(machine()->Word32And());
+ node->ReplaceInput(0, mleft.left().node());
+ node->ReplaceInput(
+ 1, Uint32Constant(~((1U << m.right().Value()) - 1U)));
+ return Changed(node);
+ }
+ }
+ }
break;
}
case IrOpcode::kWord32Shr: {
Node* Float64Constant(volatile double value);
Node* Int32Constant(int32_t value);
Node* Int64Constant(int64_t value);
+ Node* Uint32Constant(uint32_t value) {
+ return Int32Constant(bit_cast<uint32_t>(value));
+ }
Reduction ReplaceBool(bool value) { return ReplaceInt32(value ? 1 : 0); }
Reduction ReplaceFloat32(volatile float value) {
--- /dev/null
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+ "use asm";
+ var MEM32 = new stdlib.Int32Array(heap);
+ function load(i) {
+ i = i|0;
+ i = MEM32[i >> 2] | 0;
+ return i;
+ }
+ function store(i, v) {
+ i = i|0;
+ v = v|0;
+ MEM32[i >> 2] = v;
+ }
+ return { load: load, store: store };
+}
+
+var m = Module(this, {}, new ArrayBuffer(1024));
+
+m.store(0, 0x12345678);
+m.store(4, -1);
+m.store(8, -1);
+for (var i = 0; i < 4; ++i) {
+ assertEquals(0x12345678, m.load(i));
+}
+for (var i = 4; i < 12; ++i) {
+ assertEquals(-1, m.load(i));
+}
+for (var j = 4; j < 8; ++j) {
+ m.store(j, 0x11223344);
+ for (var i = 0; i < 4; ++i) {
+ assertEquals(0x12345678, m.load(i));
+ }
+ for (var i = 4; i < 8; ++i) {
+ assertEquals(0x11223344, m.load(i));
+ }
+ for (var i = 8; i < 12; ++i) {
+ assertEquals(-1, m.load(i));
+ }
+}