I found a micompiled bug.
When different optimization options are given to two LLVM IRs, the results of the program are different.
So i’ve tested a few things.
with below two files, These are ir files that call foo from main and 1 should be zero extended and return -1 ( 0-1 ).
define i32 @foo(i1 signext noundef %cond, i32 noundef %y) {
%e = zext i1 %cond to i32
%r = sub i32 %y, %e
ret i32 %r
}
declare i32 @foo(i1 signext noundef, i32 noundef)
define i32 @main() #0 {
start:
%0 = call i32 @foo(i1 1, i32 0)
ret i32 %0
}
compiling with below options.
llc --march=wasm32 --filetype=obj temp/foo.ll -o temp/foo.o
llc --march=wasm32 --filetype=obj -O0 temp/main.ll -o temp/main.o
and linking these two object files to one binary
wasm-ld --no-entry --export-all --allow-undefined temp/foo.o temp/main.o -o temp/poc.wasm
the result is below.
(module
(type (;0;) (func))
(type (;1;) (func (param i32 i32) (result i32)))
(type (;2;) (func (result i32)))
(func $__wasm_call_ctors (type 0))
(func $foo (type 1) (param i32 i32) (result i32)
local.get 1
local.get 0
i32.add)
(func $__original_main (type 2) (result i32)
(local i32 i32 i32)
i32.const 1
local.set 0
i32.const 0
local.set 1
local.get 0
local.get 1
call $foo
local.set 2
local.get 2
return)
(func $main (type 1) (param i32 i32) (result i32)
(local i32)
call $__original_main
local.set 2
local.get 2
return)
(memory (;0;) 2)
(global $__stack_pointer (mut i32) (i32.const 66560))
(global (;1;) i32 (i32.const 1024))
(global (;2;) i32 (i32.const 1024))
(global (;3;) i32 (i32.const 1024))
(global (;4;) i32 (i32.const 66560))
(global (;5;) i32 (i32.const 1024))
(global (;6;) i32 (i32.const 66560))
(global (;7;) i32 (i32.const 131072))
(global (;8;) i32 (i32.const 0))
(global (;9;) i32 (i32.const 1))
(export "memory" (memory 0))
(export "__wasm_call_ctors" (func $__wasm_call_ctors))
(export "foo" (func $foo))
(export "__original_main" (func $__original_main))
(export "main" (func $main))
(export "__dso_handle" (global 1))
(export "__data_end" (global 2))
(export "__stack_low" (global 3))
(export "__stack_high" (global 4))
(export "__global_base" (global 5))
(export "__heap_base" (global 6))
(export "__heap_end" (global 7))
(export "__memory_base" (global 8))
(export "__table_base" (global 9)))
the result is 0 + 1 = 1.
When compiling both files with same options,
llc --march=wasm32 --filetype=obj temp/foo.ll -o temp/foo.o
llc --march=wasm32 --filetype=obj temp/main.ll -o temp/main.o
the result binary is below.
(module
(type (;0;) (func))
(type (;1;) (func (param i32 i32) (result i32)))
(type (;2;) (func (result i32)))
(func $__wasm_call_ctors (type 0))
(func $foo (type 1) (param i32 i32) (result i32)
local.get 1
local.get 0
i32.add)
(func $__original_main (type 2) (result i32)
i32.const -1
i32.const 0
call $foo)
(func $main (type 1) (param i32 i32) (result i32)
call $__original_main)
(memory (;0;) 2)
the result is -1 ( 0 + -1 ). (this seems to be okay.)
When i compiled above two ll files with different compilation options and linked two object file to one binary, the result is different.
I think this has some issues.
Can anyone help me with this issue?