Issue |
138394
|
Summary |
[WebAssembly] Loop that shouldn't be given a return type
|
Labels |
new issue
|
Assignees |
|
Reporter |
Photosounder
|
I could be wrong about this one because Wasm control flow is confusing, but I'm 85% sure this C function compiles to something it shouldn't:
```c
intmax_t make_power_of_10_int(int p)
{
intmax_t v = 1;
while (p >= 5) { v *= 100000; p -= 5; }
while (p >= 1) { v *= 10; p -= 1; }
return v;
}
```
Using `-Oz` this compiles to:
```
make_power_of_10_int:
i64.const 1
local.set 1
loop i64
block
local.get 0
i32.const 4
i32.gt_s
br_if 0
block
loop
local.get 0
i32.const 1
i32.lt_s
br_if 1
local.get 0
i32.const -1
i32.add
local.set 0
local.get 1
i64.const 10
i64.mul
local.set 1
br 0
end_loop
end_block
local.get 1
return
end_block
local.get 0
i32.const -5
i32.add
local.set 0
local.get 1
i64.const 100000
i64.mul
local.set 1
br 0
end_loop
end_function
```
The problem is that:
- The first (outermost) loop has a `i64` return type, but at the 4th line from the bottom `local.set 1` empties the stack.
- This loop branches unconditionally with `br 0`, so even if there was something in the stack it could never be used.
- This loop and the whole function can only end through `return`.
- The result is stored in `local1` anyway, I can't see why the loop would need a return type.
Therefore the most immediately obvious conclusion is that giving that loop a return type is a mistake because it doesn't actually return anything (due to empty stack) and it can never exit normally anyway.
This problem seems specific to `-Oz` as the other optimisation settings produce totally different Wasm.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs