WIP: wasm: New backend #160

Draft
feedable wants to merge 5 commits from feedable/gcc-TEST:gcc-wasm-2 into trunk
Member

I would like to submit my work on a GCC backend for WebAssembly for review and potential inclusion into mainline GCC.

WebAssembly is a target intended primarily for running in a web environment. It's very similar to NVPTX in that it is a virtual ISA with infinite registers intended to be further processed by a target runtime into target-specific machine code to be executed. WebAssembly differs, however, in that can be directly interpreted too, and there is an abundance of interpreters for it already.

The primary objective of WebAssembly is to be a target that is executable by a web browser in the same context as JavaScript. This allows people to write web applications in C or C++ (or any other compiled language). Now, however, it is also used in many other niches, mostly whenever there is a need for platform-agnostic execution environment that is isolated from critical parts of a program.

The port in its current state passes all but 80 tests in the GCC test suite, sans tests for debug info, since debug info output is not supported currently. The port uses an external assembler, linker, and C standard library implementation.
Please take a look at https://gcc.gnu.org/wiki/WebAssemblyBackend for more information.

I would like to submit my work on a GCC backend for WebAssembly for review and potential inclusion into mainline GCC. WebAssembly is a target intended primarily for running in a web environment. It's very similar to NVPTX in that it is a virtual ISA with infinite registers intended to be further processed by a target runtime into target-specific machine code to be executed. WebAssembly differs, however, in that can be directly interpreted too, and there is an abundance of interpreters for it already. The primary objective of WebAssembly is to be a target that is executable by a web browser in the same context as JavaScript. This allows people to write web applications in C or C++ (or any other compiled language). Now, however, it is also used in many other niches, mostly whenever there is a need for platform-agnostic execution environment that is isolated from critical parts of a program. The port in its current state passes all but 80 tests in the GCC test suite, sans tests for debug info, since debug info output is not supported currently. The port uses an external assembler, linker, and C standard library implementation. Please take a look at https://gcc.gnu.org/wiki/WebAssemblyBackend for more information.
Member

Hi @feedable. This bot helps send your PR as a patch series to the mailing list.

Next steps

  1. Write a clear PR description. It will be used as the cover letter.
  2. To CC extra people, add lines like this at the end of the PR description: CC: Reviewer1 <revi.ewer@example.com>, Reviewer2 <an.other@example.com>.
  3. To preview the emails, comment with /preview.
  4. When ready, request review in the Reviewers section. Or, if you just want to send the series, comment with /submit.
  5. Use the cover-letter links below to follow replies.
  6. For a new patch series, push your changes, update the PR description with a Changes since vX section, and comment with /submit again.

See Submitting Patches and UsingForge.

Consider joining the gcc and gcc-patches mailing lists..
For real time communication, check the gcc irc channels.

Or join #overseers on Libera Chat, particularly if this automation is not working (stay online to get replies, IRC does not save messages if people are not online).

<!-- pr-welcome --> Hi @feedable. This bot helps send your PR as a patch series to the mailing list. ## Next steps 1. Write a clear PR description. It will be used as the cover letter. 2. To CC extra people, add lines like this **at the end** of the PR description: `CC: Reviewer1 <revi.ewer@example.com>, Reviewer2 <an.other@example.com>`. 3. To preview the emails, comment with `/preview`. 4. When ready, request review in the Reviewers section. Or, if you just want to send the series, comment with `/submit`. 5. Use the cover-letter links below to follow replies. 6. For a new patch series, push your changes, update the PR description with a `Changes since vX` section, and comment with `/submit` again. See [Submitting Patches](https://gcc.gnu.org/contribute.html#patches) and [UsingForge](https://gcc.gnu.org/wiki/UsingForge). Consider joining the [gcc and gcc-patches mailing lists.](https://gcc.gnu.org/lists.html). For real time communication, check the [gcc irc channels](https://gcc.gnu.org/wiki/GCConIRC). Or join [`#overseers`](https://web.libera.chat/#overseers) on Libera Chat, particularly if this automation is not working (stay online to get replies, IRC does not save messages if people are not online).
feedable force-pushed gcc-wasm-2 from 8976050eab
Some checks failed
/ format-checks (pull_request) Has been cancelled
to b114c074bc
Some checks failed
/ format-checks (pull_request) Failing after 1m30s
2026-05-23 15:28:58 +00:00
Compare
gcc/config.gcc Outdated
@ -609,6 +609,10 @@ tic6x-*-*)
extra_headers="c6x_intrinsics.h"
extra_options="${extra_options} c6x/c6x-tables.opt"
;;
wasm*-*-*)
Member

indendention is different from the others in this file.

indendention is different from the others in this file.
feedable marked this conversation as resolved
gcc/config.gcc Outdated
@ -3674,2 +3678,4 @@
tmake_file="visium/t-visium visium/t-crtstuff"
;;
wasm*-*-*)
target_has_targetm_common=no
Member

target_has_targetm_common belongs to the first wasm case.

I think you are missing setting tmake_file.

target_has_targetm_common belongs to the first wasm case. I think you are missing setting tmake_file.
Author
Member

I think I don't need that since I'm using the default one.

I think I don't need that since I'm using the default one.
feedable marked this conversation as resolved
@ -0,0 +1,84 @@
(define_c_enum "unspecv" [
Member

MIssing a copyright notice in front of the file.

The convention is to put the iterators in iterators.md.

MIssing a copyright notice in front of the file. The convention is to put the iterators in iterators.md.
feedable marked this conversation as resolved
@ -0,0 +21,4 @@
#define IN_TARGET_CODE 1
#include <limits>
#include <utility>
Member

#include is already done in system.h
So is limits; well limits.h is done.

#include <utility> is already done in system.h So is limits; well limits.h is done.
Author
Member

This was for numeric limits (for that template specifically), but it looks like it's no longer required.

This was for numeric limits (for that template specifically), but it looks like it's no longer required.
feedable marked this conversation as resolved
@ -0,0 +92,4 @@
is_escape (char x)
{
const char *escapes = "\"\'\\\t\n\r";
while (*escapes and x != *escapes)
Member

&& is used instead of and.

&& is used instead of and.
feedable marked this conversation as resolved
@ -0,0 +188,4 @@
void
print_type (FILE *stream, const_tree type, bool first = false)
Member

Missing comment saying what the functions does.

Missing comment saying what the functions does.
feedable marked this conversation as resolved
@ -0,0 +200,4 @@
case NULLPTR_TYPE:
case VECTOR_TYPE:
case COMPLEX_TYPE:
print_type (stream, ptr_type_node, first);
Member

This seems wrong for vector and complex types.

This seems wrong for vector and complex types.
Author
Member

This is actually dead code, so I removed it

This is actually dead code, so I removed it
feedable marked this conversation as resolved
@ -0,0 +217,4 @@
case INTEGER_TYPE:
case BOOLEAN_TYPE:
case ENUMERAL_TYPE:
fprintf (stream, "%s%s", delim,
Member

This seems wrong.
And does not handle BITINT.

This seems wrong. And does not handle BITINT.
Author
Member

BITINT is unsupported for now. This function prints the wasm's PoV on the type (as if it's in function signatures etc), so even for small ints it will be a full i32. What else is wrong?

BITINT is unsupported for now. This function prints the wasm's PoV on the type (as if it's in function signatures etc), so even for small ints it will be a full i32. What else is wrong?
@ -0,0 +311,4 @@
if (VOID_TYPE_P (type))
return;
if (TREE_CODE (type) == COMPLEX_TYPE
&& targetm.calls.split_complex_arg (type))
Member

Since you are in target code directly and I doubt you have defined a split_complex_arg target hook, this becomes reachable.

Since you are in target code directly and I doubt you have defined a split_complex_arg target hook, this becomes reachable.
Author
Member

The hook is defined to false, since LLVM ABI wants them to be in memory, so the code is really dead, but it would be nice if that would adapt if it ever changes

The hook is defined to false, since LLVM ABI wants them to be in memory, so the code is really dead, but it would be nice if that would adapt if it ever changes
feedable marked this conversation as resolved
@ -0,0 +432,4 @@
constexpr int ndata = sizeof (T) / 4;
long data[ndata];
real_to_target (data, n, float_mode_for_size (sizeof (T) * 8).require ());
int mantissa = std::numeric_limits<T>::digits - 1;
Member

Using the host floating point mode here seems wrong.
to get the number of significiant bits use significand_size with format_helper.

Using the host floating point mode here seems wrong. to get the number of significiant bits use significand_size with format_helper.
feedable marked this conversation as resolved
@ -0,0 +672,4 @@
void
wasm_assemble_decl_end ()
{
return decl_end(asm_out_file);
Member

Missing space between the function name and (.

Missing space between the function name and `(`.
feedable marked this conversation as resolved
@ -0,0 +1,12 @@
Member

Missing copyright notice.

Missing copyright notice.
feedable marked this conversation as resolved
@ -0,0 +1,125 @@
#include "config.h"
Member

Missing copyright notice.

Missing copyright notice.
feedable marked this conversation as resolved
@ -0,0 +164,4 @@
#define BITS_BIG_ENDIAN 1
#define BYTES_BIG_ENDIAN 0
#define WORDS_BIG_ENDIAN 0
Member

This seems odd to define BITS big endian to 1 without the others.
Is it wasm really most significant bit is lowest numbered?

This seems odd to define BITS big endian to 1 without the others. Is it wasm really `most significant bit is lowest numbered`?
feedable marked this conversation as resolved
@ -0,0 +165,4 @@
#define BITS_BIG_ENDIAN 1
#define BYTES_BIG_ENDIAN 0
#define WORDS_BIG_ENDIAN 0
#define UNITS_PER_WORD 8
Member

So the underlying registers are 64bit?
But then this is a ILP32 target?

So the underlying registers are 64bit? But then this is a ILP32 target?
Author
Member

Registers come in 2 distinct classes: 32- and 64-bit. 64-bit registers are used for passing long long args, so I have to support that too. Pointers are 32-bit though.

Registers come in 2 distinct classes: 32- and 64-bit. 64-bit registers are used for passing `long long` args, so I have to support that too. Pointers are 32-bit though.
feedable marked this conversation as resolved
@ -0,0 +182,4 @@
#define WCHAR_TYPE_SIZE 32
/* ??? Need to figure out why do we have to set this in order for TI to not
appear */
#define MAX_FIXED_MODE_SIZE 64
Member

MAX_FIXED_MODE_SIZE defaults to MAX (BITS_PER_WORD * 2, 64) as BITS_PER_WORD is defined as UNITS_PER_WORD*BITS_PER_WORD meaning the max will be 128. So defining it to 64 is correct if you don't support 128bit (yet).

MAX_FIXED_MODE_SIZE defaults to `MAX (BITS_PER_WORD * 2, 64)` as `BITS_PER_WORD` is defined as `UNITS_PER_WORD*BITS_PER_WORD` meaning the max will be 128. So defining it to 64 is correct if you don't support 128bit (yet).
Author
Member

Yes, that's right, I don't support that

Yes, that's right, I don't support that
Member

@feedable wrote in gcc/gcc-TEST#160 (comment):

Yes, that's right, I don't support that

Right I was trying to explain why you need to define the macro since you had a ??? there.

@feedable wrote in https://forge.sourceware.org/gcc/gcc-TEST/pulls/160#issuecomment-6035: > Yes, that's right, I don't support that Right I was trying to explain why you need to define the macro since you had a `???` there.
Author
Member

Oh right, got it. I can remove the comment, then.

Oh right, got it. I can remove the comment, then.
feedable marked this conversation as resolved
@ -0,0 +6,4 @@
"(nop)"
[])
(define_predicate "symbol_operand"
Member

The convention for new targets is to place predicates in predicates.md.

The convention for new targets is to place predicates in predicates.md.
feedable marked this conversation as resolved
@ -1,3 +1,5 @@
/* { dg-skip-if "wasi-libc doesn't work well with analyzer" { wasm*-*-* } } */
Member

It might make sense to xfail this rather than skip. Depending on the failure mode. The analyzer has special code to handle errno so it might need to be updated to support wasi-libc here.

It might make sense to xfail this rather than skip. Depending on the failure mode. The analyzer has special code to handle errno so it might need to be updated to support wasi-libc here.
Author
Member

I think it's the other way around, and wasi-libc doesn't have the attributes required to say that errno is errno and not some other thing, if I understand correctly

I think it's the other way around, and wasi-libc doesn't have the attributes required to say that errno is errno and not some other thing, if I understand correctly
Member

@feedable wrote in gcc/gcc-TEST#160 (comment):

I think it's the other way around, and wasi-libc doesn't have the attributes required to say that errno is errno and not some other thing, if I understand correctly

No analyzer code deals with errno as a special case; there is no attribute for errno. See analyzer/kf.cc:3184 . It might just need to add support for the wasi-libc case here.

@feedable wrote in https://forge.sourceware.org/gcc/gcc-TEST/pulls/160#issuecomment-6037: > I think it's the other way around, and wasi-libc doesn't have the attributes required to say that errno is errno and not some other thing, if I understand correctly No analyzer code deals with errno as a special case; there is no attribute for errno. See analyzer/kf.cc:3184 . It might just need to add support for the wasi-libc case here.
Author
Member

It looks like wasi-libc just uses a thread-local variable by the name errno for that: github.com/WebAssembly/wasi-libc@04bd527eb3/libc-bottom-half/headers/public/__errno.h (L8), but I don't feel like marking errno as a special location here would be a great idea.

It looks like wasi-libc just uses a thread-local variable by the name `errno` for that: https://github.com/WebAssembly/wasi-libc/blob/04bd527eb37512303f83efc01e4fb6222392849e/libc-bottom-half/headers/public/__errno.h#L8, but I don't feel like marking `errno` as a special location here would be a great idea.
Member

I would xfail for now and have a bug report ready to file when the code is merged or ask David M. for help on getting the right thing hooked up.

I would xfail for now and have a bug report ready to file when the code is merged or ask David M. for help on getting the right thing hooked up.
feedable marked this conversation as resolved
@ -0,0 +1,56 @@
/* { dg-additional-options "-std=gnu17" } */
Member

Is there a reason why you need -std=gnu17 for this testcase?

Is there a reason why you need -std=gnu17 for this testcase?
Author
Member

It was in the original test (pr67037.c), so I kept it.

It was in the original test (pr67037.c), so I kept it.
feedable marked this conversation as resolved
@ -3,6 +3,7 @@
attribute alloc_size that __builtin_object_size can make use of (or
are treated as if they were for that purpose)..
{ dg-do compile }
{ dg-skip-if "wasm uses wasi-libc" { wasm*-*-* } }
Member

This skip message does not makes sense since the testcase just uses all __builtin_* functions. So there is no dependency on the libc. If anything maybe it should be an xfail.

This skip message does not makes sense since the testcase just uses all `__builtin_*` functions. So there is no dependency on the libc. If anything maybe it should be an xfail.
feedable marked this conversation as resolved
@ -5,2 +5,3 @@
/* { dg-do run } */
/* { dg-do run }
{ dg-skip-if "wasm does not support prefetch" { wasm*-*-* } } */
Member

if a target does not provide a prefetch pattern, then the testcase should still work as the expansion of the prefetch builtin turns into no RTL instruction. So this skip seems wrong.

if a target does not provide a prefetch pattern, then the testcase should still work as the expansion of the prefetch builtin turns into no RTL instruction. So this skip seems wrong.
Author
Member

It does work, but it warns every time that prefetch is not meanigful. I don't want to silence that warning by making a dummy pattern, so skip. I think another option would be to expect warnings everywhere, ig?

It does work, but it warns every time that prefetch is not meanigful. I don't want to silence that warning by making a dummy pattern, so skip. I think another option would be to expect warnings everywhere, ig?
Member

Hmm, I don't see how this would warn.
expand_builtin_prefetch does not call warning for the !targetm.have_prefetch () case. This sems like something else is going wrong.

Hmm, I don't see how this would warn. expand_builtin_prefetch does not call warning for the `!targetm.have_prefetch ()` case. This sems like something else is going wrong.
Author
Member

Yep, this doesn't even seem to fail now.

Yep, this doesn't even seem to fail now.
feedable marked this conversation as resolved
@ -1,6 +1,7 @@
/* PR c/17308 - nonnull attribute not as useful as it could be
PR c/78673 - sprintf missing attribute nonnull on destination argument
{ dg-do "compile" }
{ dg-skip-if "wasm uses wasi-libc" { wasm*-*-* } }
Member

Skip message seems wrong as this is a compile time testcase without dependancy on the libc.
Maybe a xfail or is this due to variable argument printf?

Skip message seems wrong as this is a compile time testcase without dependancy on the libc. Maybe a xfail or is this due to variable argument printf?
Author
Member

This appears to not be failing anymore. The message also doesn't really make sense now. Deleted.

This appears to not be failing anymore. The message also doesn't really make sense now. Deleted.
feedable marked this conversation as resolved
@ -1,6 +1,7 @@
/* Test __STDC_VERSION_STDINT_H__ in C23. */
/* { dg-do preprocess } */
/* { dg-options "-std=c23 -pedantic-errors -ffreestanding" } */
/* { dg-skip-if "wasi-libc doesn't support c23" { wasm*-*-* } } */
Member

You should be using a stdint wrapper then. Look at other examples in config.gcc for that.

You should be using a stdint wrapper then. Look at other examples in config.gcc for that.
feedable marked this conversation as resolved
@ -1,5 +1,5 @@
/* { dg-do compile } */
/* { dg-skip-if "only works for ELF targets" { *-*-darwin* *-*-aix* } } */
/* { dg-skip-if "only works for ELF targets" { *-*-darwin* *-*-aix* wasm*-*-* } } */
Member

This should be changed to { elf } and submitted seperately.

This should be changed to `{ elf }` and submitted seperately.
Author
Member

Made a separate patch for it. I want to keep in the series though, since I think the set will grow during review and I don't want to spam small patches in the meantime, so I hope that's fine with you.

Made a separate patch for it. I want to keep in the series though, since I think the set will grow during review and I don't want to spam small patches in the meantime, so I hope that's fine with you.
Owner

We get many small patches. A few more won't hurt and getting this out of the way makes reviewing the main parts of the patch easier, IMO.

We get many small patches. A few more won't hurt and getting this out of the way makes reviewing the main parts of the patch easier, IMO.
Member

Version 1 of this pull request has been stored. It includes the following commits:

  • expand: End argument processing after processing the last argument in assign_params - 184da0c3e9
  • df: Add support for pseudos in function arguments - 096aa4e092
  • wasm: New backend - 95bbe94cdc
  • wasm: Adjust tests - b114c074bc
<!-- pr-new-version --> Version 1 of this pull request has been stored. It includes the following commits: - expand: End argument processing after processing the last argument in assign_params - 184da0c3e905cd6c5487955f4325bf4923dc2f5b - df: Add support for pseudos in function arguments - 096aa4e0929daab063d63479b0842a272d8202a2 - wasm: New backend - 95bbe94cdc2ddfe61fa33fe170b5aa5664d77256 - wasm: Adjust tests - b114c074bc43bbaa376e2f9bfb7df06d90ad3764
feedable force-pushed gcc-wasm-2 from b114c074bc
Some checks failed
/ format-checks (pull_request) Failing after 1m30s
to dad99c1cb4
Some checks failed
/ format-checks (pull_request) Failing after 1m39s
2026-05-24 00:10:29 +00:00
Compare
feedable force-pushed gcc-wasm-2 from dad99c1cb4
Some checks failed
/ format-checks (pull_request) Failing after 1m39s
to 762c13c12a
Some checks failed
/ format-checks (pull_request) Failing after 1m35s
2026-05-25 16:25:56 +00:00
Compare
feedable force-pushed gcc-wasm-2 from 762c13c12a
Some checks failed
/ format-checks (pull_request) Failing after 1m35s
to 276f248c12
Some checks failed
/ format-checks (pull_request) Failing after 1m31s
2026-05-26 22:30:57 +00:00
Compare
feedable force-pushed gcc-wasm-2 from 276f248c12
Some checks failed
/ format-checks (pull_request) Failing after 1m31s
to 2eb0a7b949
Some checks failed
/ format-checks (pull_request) Failing after 1m30s
2026-05-26 23:06:07 +00:00
Compare
feedable force-pushed gcc-wasm-2 from 2eb0a7b949
Some checks failed
/ format-checks (pull_request) Failing after 1m30s
to f270ac3975
Some checks failed
/ format-checks (pull_request) Failing after 1m35s
2026-05-28 12:06:54 +00:00
Compare
feedable force-pushed gcc-wasm-2 from f270ac3975
Some checks failed
/ format-checks (pull_request) Failing after 1m35s
to ac20dcd5f8
Some checks failed
/ format-checks (pull_request) Failing after 1m32s
2026-05-28 13:20:04 +00:00
Compare
Member

Version 2 of this pull request has been stored. It includes the following commits:

  • expand: End argument processing after processing the last argument in assign_params - 771a580b4e
  • df: Add support for pseudos in function arguments - 64d9153aa3
  • testsuite: Adjust requirements - 73c5527223
  • wasm: New backend - 8f90eb001a
  • wasm: Adjust tests - ac20dcd5f8
<!-- pr-new-version --> Version 2 of this pull request has been stored. It includes the following commits: - expand: End argument processing after processing the last argument in assign_params - 771a580b4e5beed3122fc2a0b0f2219340b21ff7 - df: Add support for pseudos in function arguments - 64d9153aa32ffbcba496f13c1bee8888ca779df5 - testsuite: Adjust requirements - 73c55272234d23143f28d20402abb406adb980e3 - wasm: New backend - 8f90eb001a5b25ef1e6285c8dc9f9bc13e1a8acd - wasm: Adjust tests - ac20dcd5f8c5ae858f9b2d9cdf4140c0738e5e27
Member

Pull Request versions:

# Base Head
1 6e1679ebd5 b114c074bc (diff)
2 33ac889aa2 ac20dcd5f8 (diff)

In order to compare , clone this repository and run

PR=160
git fetch origin "refs/versioned_pull/${PR}/*:refs/versioned_pull/${PR}/*"
PRV1=1
PRV2=2
git range-diff "refs/versioned_pull/${PR}/${PRV1}/base..refs/versioned_pull/${PR}/${PRV1}/head"  "refs/versioned_pull/${PR}/${PRV2}/base..refs/versioned_pull/${PR}/${PRV2}/head"
<!-- pr-versions --> Pull Request versions: | # | Base | Head | | | - | ---- | ---- | - | | 1 | 6e1679ebd5e62dd63ee6c93df2514e0c08a2b674 | b114c074bc43bbaa376e2f9bfb7df06d90ad3764 | [(diff)](https://forge.sourceware.org/gcc/gcc-TEST.git/compare/6e1679ebd5e62dd63ee6c93df2514e0c08a2b674...b114c074bc43bbaa376e2f9bfb7df06d90ad3764) | | 2 | 33ac889aa27d9917e6e7d07c282015b7c48e0440 | ac20dcd5f8c5ae858f9b2d9cdf4140c0738e5e27 | [(diff)](https://forge.sourceware.org/gcc/gcc-TEST.git/compare/33ac889aa27d9917e6e7d07c282015b7c48e0440...ac20dcd5f8c5ae858f9b2d9cdf4140c0738e5e27) | In order to compare , clone this repository and run ``` PR=160 git fetch origin "refs/versioned_pull/${PR}/*:refs/versioned_pull/${PR}/*" PRV1=1 PRV2=2 git range-diff "refs/versioned_pull/${PR}/${PRV1}/base..refs/versioned_pull/${PR}/${PRV1}/head" "refs/versioned_pull/${PR}/${PRV2}/base..refs/versioned_pull/${PR}/${PRV2}/head" ```
@ -0,0 +44,4 @@
(define_mode_attr promote_type [
(QI "i32") (HI "i32")
(SI "i32") (DI "i64")
(SF "f32") (DF "f32")])
Member

I don't understand why this doesn't say (DF "f64"). Is this a special case?

I don't understand why this doesn't say `(DF "f64")`. Is this a special case?
Author
Member

Nope, this is just an oversight. Didn't catch that myself because only integer types here are actually used.

Nope, this is just an oversight. Didn't catch that myself because only integer types here are actually used.
@ -0,0 +174,4 @@
#define FUNCTION_MODE SImode
#define CASE_VECTOR_MODE SImode
#define POINTER_SIZE 32
Member

Are you trying to follow the https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md document?
I think there are some inconsistencies with that:
long double is emitted as 8-byte DFmode, TImode is disabled, plain char is
unsigned, and wchar_t is long. The WebAssembly Basic C ABI requires
binary128 long double, 128-bit integers as two i64s, signed plain char, and
wchar_t as int.

Are you trying to follow the https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md document? I think there are some inconsistencies with that: long double is emitted as 8-byte DFmode, TImode is disabled, plain char is unsigned, and wchar_t is long. The WebAssembly Basic C ABI requires binary128 long double, 128-bit integers as two i64s, signed plain char, and wchar_t as int.
Author
Member

I can't really enable TImode now (or anything 128-bit), since to my understanding there isn't machinery to split these values to registers of appropriate size, and that's only likely to change when I make the register allocation infrastructure work with infinite registers. I would also then want to disable long double for now, since that's also subject to the same problems. The rest is fair, will fix

I can't really enable `TImode` now (or anything 128-bit), since to my understanding there isn't machinery to split these values to registers of appropriate size, and that's only likely to change when I make the register allocation infrastructure work with infinite registers. I would also then want to disable `long double` for now, since that's also subject to the same problems. The rest is fair, will fix
@ -0,0 +585,4 @@
return wasm_function_value (rtype, NULL_TREE, false);
}
/* Implementation of TARGET_PASS_BY_REFERENCE. */
Member
 wasm_pass_by_reference passes every aggregate indirectly, while
 wasm_return_in_memory returns ordinary records directly. The assembler
 signature printer independently treats records as pointers. This produces
 incompatible parameter/result types and can emit a result from a no-result
 function.

 Use one shared Basic C ABI classifier for argument lowering, return
 lowering, and signature emission.
wasm_pass_by_reference passes every aggregate indirectly, while wasm_return_in_memory returns ordinary records directly. The assembler signature printer independently treats records as pointers. This produces incompatible parameter/result types and can emit a result from a no-result function. Use one shared Basic C ABI classifier for argument lowering, return lowering, and signature emission.
@ -0,0 +98,4 @@
}
void
record_libcall (const_rtx sym, tree ret)
Member
 wasm_pass_by_reference passes every aggregate indirectly, while
 wasm_return_in_memory returns ordinary records directly. The assembler
 signature printer independently treats records as pointers. This produces
 incompatible parameter/result types and can emit a result from a no-result
 function.

 Use one shared Basic C ABI classifier for argument lowering, return
 lowering, and signature emission.
wasm_pass_by_reference passes every aggregate indirectly, while wasm_return_in_memory returns ordinary records directly. The assembler signature printer independently treats records as pointers. This produces incompatible parameter/result types and can emit a result from a no-result function. Use one shared Basic C ABI classifier for argument lowering, return lowering, and signature emission.
Author
Member

What do you mean by "ordinary structs" here? aggregate_value_p already handles aggregate types that are not transparent (i.e. have a single field of scalar type) and always returns them by reference, so wasm_return_in_memory doesn't even encounter them.

The one thing that's not handled are empty structs, which didn't manifest because TARGET_EMPTY_RECORD_P is false by default.

What do you mean by "ordinary structs" here? `aggregate_value_p` already handles aggregate types that are not transparent (i.e. have a single field of scalar type) and always returns them by reference, so `wasm_return_in_memory` doesn't even encounter them. The one thing that's not handled are empty structs, which didn't manifest because `TARGET_EMPTY_RECORD_P` is false by default.
@ -3756,6 +3756,9 @@ assign_parms (tree fndecl)
targetm.calls.function_arg_advance (all.args_so_far, data.arg);
}
targetm.calls.function_incoming_arg (all.args_so_far,
Member
 The new unconditional end-marker call invokes TARGET_FUNCTION_INCOMING_ARG
 for every target. IA64, for example, emits OpenVMS argument setup when it
 sees an end marker (gcc/config/ia64/ia64.cc:4775-4785)
The new unconditional end-marker call invokes TARGET_FUNCTION_INCOMING_ARG for every target. IA64, for example, emits OpenVMS argument setup when it sees an end marker (gcc/config/ia64/ia64.cc:4775-4785)
Author
Member

Yes, but isn't that the point? My impression was that end_marker was the canonical way to indicate the end of function arguments. If we actually don't want that (or can't afford to change the targets that rely on the current behavior), I can make another hook for this place specifically, instead, too.

Yes, but isn't that the point? My impression was that `end_marker` was the canonical way to indicate the end of function arguments. If we actually don't want that (or can't afford to change the targets that rely on the current behavior), I can make another hook for this place specifically, instead, too.
@ -0,0 +235,4 @@
[(set (match_operand:SUBREGDI 0 "subregister_for_di_operand")
(match_operand:SUBREGDI 1 "memory_operand"))]
""
"(%o0 (i64.load<SUBREGSI:size>_s %m1))")
Member

I think this should be SUBREGDI:size as that's what the pattern iterator is using

I think this should be <SUBREGDI:size> as that's what the pattern iterator is using
Some checks failed
/ format-checks (pull_request) Failing after 1m32s
This pull request has changes conflicting with the target branch.
  • gcc/testsuite/gcc.dg/analyzer/mkdtemp-1.c
  • gcc/testsuite/gcc.dg/analyzer/mkostemp-1.c
  • gcc/testsuite/gcc.dg/analyzer/mkostemps-1.c
  • gcc/testsuite/gcc.dg/analyzer/mkstemp-1.c
  • gcc/testsuite/gcc.dg/analyzer/mkstemps-1.c
  • gcc/testsuite/gcc.dg/analyzer/mktemp-1.c
View command line instructions

Manual merge helper

Use this merge commit message when completing the merge manually.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u gcc-wasm-2:feedable-gcc-wasm-2
git switch feedable-gcc-wasm-2

Merge

Merge the changes and update on Forgejo.
git switch trunk
git merge --no-ff feedable-gcc-wasm-2
git switch feedable-gcc-wasm-2
git rebase trunk
git switch trunk
git merge --ff-only feedable-gcc-wasm-2
git switch feedable-gcc-wasm-2
git rebase trunk
git switch trunk
git merge --no-ff feedable-gcc-wasm-2
git switch trunk
git merge --squash feedable-gcc-wasm-2
git switch trunk
git merge --ff-only feedable-gcc-wasm-2
git switch trunk
git merge feedable-gcc-wasm-2
git push origin trunk
Sign in to join this conversation.
No reviewers
No milestone
No assignees
6 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gcc/gcc!160
No description provided.