Closed zyz9740 closed 1 year ago
I reproduce, and I think I also have a fix for the problem, thanks a lot for signaling this.
Historically -O0 has been not supported, and less testing is done in this configuration, so we recommend compiling with at least -O1 enabled, since there might be stubble bugs introduced by some optimization passes being tagged as optional while they are actually not.
In this case the problem was not pass ordering/selection, but an actual bug in the Wasm writer while handling Constant non representable as int32_t.
Thanks again for the test-case, should be merged in master in the next batch.
Trigger is as follows:
#include "cd.h"
long long a = 0;
long b = 0;
int main() {
b = a ^= b;
long long c = (int)a;
if (c <= 0)
transparent_crc(c, "c", 1);
return 0;
}
When executing the wasm generated by cheerp, this program print nothing. But of course it should output something in "transparent_crc" function because variable "a" is always equal to zero.
We found the cause of this case when debugging wasm.
This is the main function in wasm:
(func (;100;) (type 3)
(local i64)
global.get 6
global.get 12
i64.extend_i32_s
i64.xor
local.tee 0
global.set 6
local.get 0
i32.wrap_i64
global.set 12
local.get 0
i64.const 32
i64.shl
local.tee 0
i64.const 0
i64.lt_s // There should be le_s instead of lt_s, which causes this issue
if ;; label = @1
local.get 0
i64.const 32
i64.shr_s
call 63
end
global.get 6
i64.const 12134
i64.add
global.set 6)
What confuses me is that I don't know why this happens and if change anything in the C program, it print correctly. Which transformation compile operator "<=" to lt instead of le ?
Thanks again for getting in depth! The problem was:
(func $main (type 3)
(local i64)
global.get 11
global.get 12
i64.extend_i32_s
i64.xor
local.tee 0
global.set 11
local.get 0
i32.wrap_i64
global.set 12
local.get 0
i64.const 32
i64.shl
local.tee 0
i64.const 0 // 2^32 -> Overflow !!!
i64.lt_s
if ;; label = @1
local.get 0
i64.const 32
i64.shr_s
call $transparent_crc
end)
instead of
(func $main (type 3)
(local i64)
global.get 11
global.get 12
i64.extend_i32_s
i64.xor
local.tee 0
global.set 11
local.get 0
i32.wrap_i64
global.set 12
local.get 0
i64.const 32
i64.shl
local.tee 0
i64.const 4294967296 // 2^32
i64.lt_s
if ;; label = @1
local.get 0
i64.const 32
i64.shr_s
call $transparent_crc
end)
OK, thanks for your fast response again! We found the cause in the same time Hhhhhh. What a coincidence ; )
I still have a question. To compile C code if (c <= 0)
, cheerp printf i64.const 4294967296 // 2^32
.Why wasm compares (0 << 32)
with a such huge number instead of 0 ? From my perspective, wasm should compare (0<<32)
with "0" and the comparison operators should be le_s instead of lt_s.
Your explaination will help to understand the root cause deeper. I'm looking forward to your reply !
bug.zip
Can you reproduce this ? I can't locate which statement cause this issue.