-
Notifications
You must be signed in to change notification settings - Fork 12.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
clang generates mismatching wasm compiler-rt function signatures with -mmulti-value #59095
Comments
@llvm/issue-subscribers-backend-webassembly |
Hi folks, I came up with the minimum repro that works for latest clang-15 official apt release on ubuntu-22.04: Content of a, c;
__int128 b;
fn1() {
if (b < 0)
if (a > 8 / b)
c = 0;
} Content of # 1 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/udivti3.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 327 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/udivti3.c" 2
# 13 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/udivti3.c"
# 1 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_lib.h" 1
# 92 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_lib.h"
# 1 "/usr/lib/llvm-15/lib/clang/15.0.6/include/float.h" 1 3
# 93 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_lib.h" 2
# 1 "/usr/lib/llvm-15/lib/clang/15.0.6/include/limits.h" 1 3
# 21 "/usr/lib/llvm-15/lib/clang/15.0.6/include/limits.h" 3
# 1 "/tmp/wasi-sysroot/include/limits.h" 1 3
# 1 "/tmp/wasi-sysroot/include/features.h" 1 3
# 5 "/tmp/wasi-sysroot/include/limits.h" 2 3
# 1 "/tmp/wasi-sysroot/include/bits/alltypes.h" 1 3
# 269 "/tmp/wasi-sysroot/include/bits/alltypes.h" 3
# 1 "/tmp/wasi-sysroot/include/__struct_timeval.h" 1 3
# 1 "/tmp/wasi-sysroot/include/__typedef_time_t.h" 1 3
typedef long long time_t;
# 5 "/tmp/wasi-sysroot/include/__struct_timeval.h" 2 3
# 1 "/tmp/wasi-sysroot/include/__typedef_suseconds_t.h" 1 3
typedef long long suseconds_t;
# 6 "/tmp/wasi-sysroot/include/__struct_timeval.h" 2 3
struct timeval {
time_t tv_sec;
suseconds_t tv_usec;
};
# 270 "/tmp/wasi-sysroot/include/bits/alltypes.h" 2 3
# 1 "/tmp/wasi-sysroot/include/__struct_timespec.h" 1 3
struct timespec {
time_t tv_sec;
long tv_nsec;
};
# 271 "/tmp/wasi-sysroot/include/bits/alltypes.h" 2 3
# 402 "/tmp/wasi-sysroot/include/bits/alltypes.h" 3
# 1 "/tmp/wasi-sysroot/include/__struct_iovec.h" 1 3
# 1 "/usr/lib/llvm-15/lib/clang/15.0.6/include/stddef.h" 1 3
# 46 "/usr/lib/llvm-15/lib/clang/15.0.6/include/stddef.h" 3
typedef long unsigned int size_t;
# 6 "/tmp/wasi-sysroot/include/__struct_iovec.h" 2 3
struct iovec {
void *iov_base;
size_t iov_len;
};
# 403 "/tmp/wasi-sysroot/include/bits/alltypes.h" 2 3
# 7 "/tmp/wasi-sysroot/include/limits.h" 2 3
# 40 "/tmp/wasi-sysroot/include/limits.h" 3
# 1 "/tmp/wasi-sysroot/include/bits/limits.h" 1 3
# 1 "/tmp/wasi-sysroot/include/__macro_PAGESIZE.h" 1 3
# 2 "/tmp/wasi-sysroot/include/bits/limits.h" 2 3
# 41 "/tmp/wasi-sysroot/include/limits.h" 2 3
# 22 "/usr/lib/llvm-15/lib/clang/15.0.6/include/limits.h" 2 3
# 94 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_lib.h" 2
# 1 "/usr/lib/llvm-15/lib/clang/15.0.6/include/stdbool.h" 1 3
# 95 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_lib.h" 2
# 1 "/usr/lib/llvm-15/lib/clang/15.0.6/include/stdint.h" 1 3
# 52 "/usr/lib/llvm-15/lib/clang/15.0.6/include/stdint.h" 3
# 1 "/tmp/wasi-sysroot/include/stdint.h" 1 3
# 20 "/tmp/wasi-sysroot/include/stdint.h" 3
# 1 "/tmp/wasi-sysroot/include/bits/alltypes.h" 1 3
# 77 "/tmp/wasi-sysroot/include/bits/alltypes.h" 3
typedef unsigned long uintptr_t;
# 92 "/tmp/wasi-sysroot/include/bits/alltypes.h" 3
typedef long intptr_t;
# 130 "/tmp/wasi-sysroot/include/bits/alltypes.h" 3
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long long int64_t;
typedef signed long long intmax_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
# 180 "/tmp/wasi-sysroot/include/bits/alltypes.h" 3
typedef unsigned long long uintmax_t;
# 21 "/tmp/wasi-sysroot/include/stdint.h" 2 3
typedef int8_t int_fast8_t;
typedef int64_t int_fast64_t;
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_fast8_t;
typedef uint64_t uint_fast64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
# 95 "/tmp/wasi-sysroot/include/stdint.h" 3
# 1 "/tmp/wasi-sysroot/include/bits/stdint.h" 1 3
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
# 96 "/tmp/wasi-sysroot/include/stdint.h" 2 3
# 53 "/usr/lib/llvm-15/lib/clang/15.0.6/include/stdint.h" 2 3
# 96 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_lib.h" 2
# 1 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_types.h" 1
# 19 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_types.h"
# 1 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_endianness.h" 1
# 20 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_types.h" 2
typedef int32_t si_int;
typedef uint32_t su_int;
# 37 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_types.h"
typedef int64_t di_int;
typedef uint64_t du_int;
typedef union {
di_int all;
struct {
su_int low;
si_int high;
} s;
} dwords;
typedef union {
du_int all;
struct {
su_int low;
su_int high;
} s;
} udwords;
# 79 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_types.h"
typedef int ti_int __attribute__((mode(TI)));
typedef unsigned tu_int __attribute__((mode(TI)));
typedef union {
ti_int all;
struct {
du_int low;
di_int high;
} s;
} twords;
typedef union {
tu_int all;
struct {
du_int low;
du_int high;
} s;
} utwords;
static inline ti_int make_ti(di_int h, di_int l) {
twords r;
r.s.high = h;
r.s.low = l;
return r.all;
}
static inline tu_int make_tu(du_int h, du_int l) {
utwords r;
r.s.high = h;
r.s.low = l;
return r.all;
}
# 133 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_types.h"
typedef union {
su_int u;
float f;
} float_bits;
typedef union {
udwords u;
double f;
} double_bits;
typedef struct {
udwords low;
udwords high;
} uqwords;
# 169 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_types.h"
typedef union {
uqwords u;
long double f;
} long_double_bits;
typedef float _Complex Fcomplex;
typedef double _Complex Dcomplex;
typedef long double _Complex Lcomplex;
# 100 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_lib.h" 2
# 1 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_util.h" 1
# 23 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_util.h"
__attribute__((noreturn)) void __compilerrt_abort_impl(const char *file, int line,
const char *function);
# 103 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/int_lib.h" 2
int __paritysi2(si_int a);
int __paritydi2(di_int a);
di_int __divdi3(di_int a, di_int b);
si_int __divsi3(si_int a, si_int b);
su_int __udivsi3(su_int n, su_int d);
su_int __udivmodsi4(su_int a, su_int b, su_int *rem);
du_int __udivmoddi4(du_int a, du_int b, du_int *rem);
int __clzti2(ti_int a);
tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem);
# 14 "/workspace/wasi-sdk/src/llvm-project/compiler-rt/lib/builtins/udivti3.c" 2
tu_int __udivti3(tu_int a, tu_int b) {
return __udivmodti4(a, b, 0);
} The command to compile and reproduce: clang-15 --target=wasm32 -mmultivalue -O2 -o muloti4.c.obj -c muloti4.c
clang-15 --target=wasm32 -mmultivalue -o udivti3.c.obj -c udivti3.c
wasm-ld-15 -r muloti4.c.obj udivti3.c.obj -o combined.o You can see the warning message about signature mismatch when
I hope the example above helps in looking into this issue, thanks :) |
canditate D146271 |
@HerrCai0907 Thanks a lot for D146271! I tried cherry-picking it on top of 16.0.0 in my fork, enabling
So it seems there are still some cases not covered by that patch. I'll try to come up with a more self-contained repro soon. |
Here's a minimal repro for the signature mismatch of int a;
long double b;
int fn1() {
a -= b;
return 0;
} $ build/install/opt/wasi-sdk/bin/clang -mmultivalue --target=wasm32-wasi -S -o floatscan.long-double.s floatscan.long-double.c The above command would generate a call to long double __subtf3(long double, long double) {} build/install/opt/wasi-sdk/bin/clang --target=wasm32-wasi -mmultivalue -o subtf3.s -S subtf3.c The above command that compiles |
It's caused by this code |
@HerrCai0907 Thanks a lot for the two patches! I tried applying both D146271 and D146499 on top of 16.0.0, and now I have another minimum repro for a signature mismatch of __uint128_t toRep();
void fromRep() {
__uint128_t bRep = toRep(), bSignificand = bRep;
int align = bRep;
bSignificand = bSignificand >> align;
if (bSignificand)
fromRep();
} $ build/install/opt/wasi-sdk/bin/clang --target=wasm32 -mmultivalue -o addtf3.s -S addtf3.c
$ grep -F '.functype __lshrti3 (i64, i64, i32) -> (i64, i64, i64, i64)' addtf3.s __int128 __lshrti3(__int128, int) {} $ build/install/opt/wasi-sdk/bin/clang --target=wasm32 -mmultivalue -o lshrti3.s -S lshrti3.c
$ grep -F '.functype __lshrti3 (i64, i64, i32) -> (i64, i64)' lshrti3.s |
current patch: Maybe you can try again. Thanks! |
@HerrCai0907 I can now confirm the three patches fix all the |
When
-mmulti-value
is added in wasi-sdk (thewasi-libc
CFLAGS, and allCMAKE_C_FLAGS
&CMAKE_CXX_FLAGS
in the top-level makefile), clang generates mismatching wasm compiler-rt function signatures, as can be seen in thewasm-ld
warning messages:Posting the bug early, and a self-contained minimal repro should come later.
The text was updated successfully, but these errors were encountered: