Skip to content

Commit b245afb

Browse files
OptimizeInstructions: Extend getMaxbits to handle Blocks (#7590)
E.g. (i32.and (i32.load (i32.const 0) ) (block (result i32) (i32.store (i32.const 0) (i32.const 0) ) (i32.const 0) ) Interactions between the and's arms prevent other optimizations from helping here, but we can see the and is with 0. Fixes: #7559
1 parent 4f9374c commit b245afb

File tree

3 files changed

+110
-8
lines changed

3 files changed

+110
-8
lines changed

src/ir/bits.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,10 @@ Index getMaxBits(Expression* curr,
456456
if (LoadUtils::isSignRelevant(load) && !load->signed_) {
457457
return 8 * load->bytes;
458458
}
459+
} else if (auto* block = curr->dynCast<Block>()) {
460+
if (!block->name.is() && !block->list.empty() && block->type.isConcrete()) {
461+
return getMaxBits(block->list.back(), localInfoProvider);
462+
}
459463
}
460464
switch (curr->type.getBasic()) {
461465
case Type::i32:

src/passes/OptimizeInstructions.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2608,8 +2608,13 @@ struct OptimizeInstructions
26082608
}
26092609

26102610
Index getMaxBitsForLocal(LocalGet* get) {
2611-
// check what we know about the local
2612-
return localInfo[get->index].maxBits;
2611+
// check what we know about the local (we may know nothing, if this local
2612+
// was added after the pass scanned for locals; in that case, full
2613+
// optimization may require another cycle)
2614+
if (get->index < localInfo.size()) {
2615+
return localInfo[get->index].maxBits;
2616+
}
2617+
return getBitsForType(get->type);
26132618
}
26142619

26152620
private:

test/lit/passes/optimize-instructions-mvp.wast

Lines changed: 99 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8745,36 +8745,129 @@
87458745
(i32.const 0)
87468746
)
87478747
)
8748-
;; CHECK: (func $andZero (param $0 i32) (result i32)
8748+
;; CHECK: (func $andZero (param $0 i32) (param $1 i64) (result i32)
87498749
;; CHECK-NEXT: (drop
87508750
;; CHECK-NEXT: (i32.const 0)
87518751
;; CHECK-NEXT: )
87528752
;; CHECK-NEXT: (drop
8753+
;; CHECK-NEXT: (i64.const 0)
8754+
;; CHECK-NEXT: )
8755+
;; CHECK-NEXT: (drop
87538756
;; CHECK-NEXT: (block (result i32)
87548757
;; CHECK-NEXT: (drop
8755-
;; CHECK-NEXT: (call $andZero
8756-
;; CHECK-NEXT: (i32.const 1234)
8758+
;; CHECK-NEXT: (local.tee $0
8759+
;; CHECK-NEXT: (i32.const 1)
87578760
;; CHECK-NEXT: )
87588761
;; CHECK-NEXT: )
87598762
;; CHECK-NEXT: (i32.const 0)
87608763
;; CHECK-NEXT: )
87618764
;; CHECK-NEXT: )
8765+
;; CHECK-NEXT: (drop
8766+
;; CHECK-NEXT: (block (result i64)
8767+
;; CHECK-NEXT: (drop
8768+
;; CHECK-NEXT: (local.tee $1
8769+
;; CHECK-NEXT: (i64.const 1)
8770+
;; CHECK-NEXT: )
8771+
;; CHECK-NEXT: )
8772+
;; CHECK-NEXT: (i64.const 0)
8773+
;; CHECK-NEXT: )
8774+
;; CHECK-NEXT: )
8775+
;; CHECK-NEXT: (drop
8776+
;; CHECK-NEXT: (block (result i32)
8777+
;; CHECK-NEXT: (drop
8778+
;; CHECK-NEXT: (local.tee $0
8779+
;; CHECK-NEXT: (i32.const 1)
8780+
;; CHECK-NEXT: )
8781+
;; CHECK-NEXT: )
8782+
;; CHECK-NEXT: (drop
8783+
;; CHECK-NEXT: (block (result i32)
8784+
;; CHECK-NEXT: (local.set $0
8785+
;; CHECK-NEXT: (i32.const 1)
8786+
;; CHECK-NEXT: )
8787+
;; CHECK-NEXT: (i32.const 0)
8788+
;; CHECK-NEXT: )
8789+
;; CHECK-NEXT: )
8790+
;; CHECK-NEXT: (i32.const 0)
8791+
;; CHECK-NEXT: )
8792+
;; CHECK-NEXT: )
8793+
;; CHECK-NEXT: (drop
8794+
;; CHECK-NEXT: (block (result i64)
8795+
;; CHECK-NEXT: (drop
8796+
;; CHECK-NEXT: (local.tee $1
8797+
;; CHECK-NEXT: (i64.const 1)
8798+
;; CHECK-NEXT: )
8799+
;; CHECK-NEXT: )
8800+
;; CHECK-NEXT: (drop
8801+
;; CHECK-NEXT: (block (result i64)
8802+
;; CHECK-NEXT: (local.set $1
8803+
;; CHECK-NEXT: (i64.const 1)
8804+
;; CHECK-NEXT: )
8805+
;; CHECK-NEXT: (i64.const 0)
8806+
;; CHECK-NEXT: )
8807+
;; CHECK-NEXT: )
8808+
;; CHECK-NEXT: (i64.const 0)
8809+
;; CHECK-NEXT: )
8810+
;; CHECK-NEXT: )
87628811
;; CHECK-NEXT: (unreachable)
87638812
;; CHECK-NEXT: )
8764-
(func $andZero (param $0 i32) (result i32)
8813+
(func $andZero (param $0 i32) (param $1 i64) (result i32)
87658814
(drop
87668815
(i32.and
87678816
(local.get $0)
87688817
(i32.const 0)
87698818
)
87708819
)
8820+
(drop
8821+
(i64.and
8822+
(local.get $1)
8823+
(i64.const 0)
8824+
)
8825+
)
8826+
;; side effects. we must keep the tee, but
8827+
;; can drop it.
87718828
(drop
87728829
(i32.and
8773-
(call $andZero (i32.const 1234)) ;; side effects, we must keep this, but
8774-
;; can drop it.
8830+
(local.tee $0
8831+
(i32.const 1)
8832+
)
87758833
(i32.const 0)
87768834
)
87778835
)
8836+
(drop
8837+
(i64.and
8838+
(local.tee $1
8839+
(i64.const 1)
8840+
)
8841+
(i64.const 0)
8842+
)
8843+
)
8844+
;; We can optimize out the |and| even if the 0 is at the end of a block.
8845+
(drop
8846+
(i32.and
8847+
(local.tee $0
8848+
(i32.const 1)
8849+
)
8850+
(block (result i32)
8851+
(local.set $0
8852+
(i32.const 1)
8853+
)
8854+
(i32.const 0)
8855+
)
8856+
)
8857+
)
8858+
(drop
8859+
(i64.and
8860+
(local.tee $1
8861+
(i64.const 1)
8862+
)
8863+
(block (result i64)
8864+
(local.set $1
8865+
(i64.const 1)
8866+
)
8867+
(i64.const 0)
8868+
)
8869+
)
8870+
)
87788871
(unreachable)
87798872
)
87808873
;; CHECK: (func $abstract-additions (param $x32 i32) (param $x64 i64) (param $y32 f32) (param $y64 f64)

0 commit comments

Comments
 (0)