LoopInvariantCodeMotion: `struct.new` is hoisted out of a loop, so all iterations share one object
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 68/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- wasm
- Lĩnh vực
- compilers
Hướng nghiên cứu
Start with the LoopInvariantCodeMotion pass and its unsafeToMove logic, then reproduce the issue with the supplied WAT module using wasm-opt --enable-gc --enable-reference-types --licm --fuzz-exec. Check that struct.new remains per-iteration and that the optimized and unoptimized executions both return 1.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
unsafeToMove does not treat an allocation as generative, so local.set $x (struct.new ...) is moved out of the loop and every iteration mutates the same object.
Root cause
struct.new is considered movable because it has no side effect on existing state, but it creates a new identity on each evaluation.
Affected passes
Only LoopInvariantCodeMotion. Allocations in other loop-hoisting code were not examined.
Reproducer
In C-like pseudo code, the function below is:
struct T { int f; };
int f(void) {
struct T *x;
int i = 0;
do {
x = new_T(0); // a new object on every iteration
x->f = x->f + 1;
i = i + 1;
} while (i < 2);
return x->f; // 1
}
After --licm, new_T(0) is moved above the loop, so both iterations update the same object and f returns 2:
x = new_T(0);
do {
x->f = x->f + 1;
i = i + 1;
} while (i < 2);
return x->f; // 2
(module
(type $T (struct (field (mut i32))))
(func (export "f") (result i32)
(local $x (ref null $T)) (local $i i32)
(loop $l
(local.set $x (struct.new $T (i32.const 0)))
(struct.set $T 0 (local.get $x)
(i32.add (struct.get $T 0 (local.get $x)) (i32.const 1)))
(br_if $l (i32.lt_u (local.tee $i (i32.add (local.get $i) (i32.const 1))) (i32.const 2))))
(struct.get $T 0 (local.get $x))))
$ wasm-opt in.wat --enable-gc --enable-reference-types --licm --fuzz-exec -o /dev/null
[fuzz-exec] export f
[fuzz-exec] note result: f => 1
[fuzz-exec] export f
[fuzz-exec] note result: f => 2
[fuzz-exec] comparing f
values not identical! 2 != 1
[fuzz-exec] optimization passes changed results
Expected vs actual
The original returns 1 (each iteration starts from a fresh object). After the pass the object is shared across the two iterations and the function returns 2.
Version
Reproduced on upstream main at 4d8ac549e2ab9b283246ea95e79ebe139ca579ac (wasm-opt version 133).
AI was used as part of the process of finding this issue. I have manually checked and reproduced it.
- Ngôn ngữ chính
- WebAssembly
- Star
- 8.7k
- Fork
- 893
- Merge trung bình
- 1 ngày 18 giờ
- Pull request đã merge (30 ngày)
- 95
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của WebAssembly/binaryen
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
WebAssembly/binaryen#9135 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 Nửa ngày Mức phù hợp với người mới 76/100
WebAssembly/binaryen#9018 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Memory64Lowering: table.get/table.set keep i64 index on lowered table64, output fails validationĐang mở
Độ khó 3/5 Nửa ngày Mức phù hợp với người mới 66/100
WebAssembly/binaryen#9245 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 65/100
WebAssembly/binaryen#9244 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 62/100
WebAssembly/binaryen#9243 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của WebAssembly/binaryen
Issue tương tự
-
IO.get_env on Node truncates names at embedded NULCó thể đã có người làm @Yi-111-a đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
HigherOrderCO/Bend#1449 · 1 bình luận ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
grame-cncm/faust#1344 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
handsontable/hyperformula#1803 ·
Maintainer thường phản hồi trong vòng 1 ngày