jiebi/CodeConvo huggingface dataset:
This effectively means you can't compile for these targets.
This may have been caused by the i128 PR ( ). No LLVM assertion is raised if I compile with , which removes the i128 stuff. We could try to fix this or we could cfg away the i128 stuff for the nvptx targets in the meantine. The LLVM assertions render the NVPTX backend unusable in the nightlies. cc Have you seen any LLVM assertion like the ones above while working on implementing i128? cc cfg?
no, I can't remember seeing such an assertion. It seems to be in PTX related code. but its very likely that i128 broke some of the non tier1 platforms. You can only tell whether they break once they actually do :/ Can you try to generate a minimum reproducible example? Then we might know more...
Seems like the msp430 target broke too: with Using works fine. cc
Examples
msp430 EABI doesn't specify how to return 128 bit values, and LLVM does not support them on msp430, so I don't see an easy fix for this.
These are tier 3 platforms, so basically anything goes IMO in terms of language guarantees. If they don't support i128 at a fundamental level then it seems like if we want them to compile we'll have to cfg out support.
I'm trying to understand this better: If the ABI does not specify how 128-bit values are passed/returned, does that mean that the architecture doesn't support 128-bit values at the fundamental level?Do all the ABIs of the all the other platform 2 targets (x86, ARM, MIPS, PowerPC, SystemZ) specify how 128-bit values are returned?(What about wasm and Do those even have an ABI? How does the 128-bit stuff even works there?) I'm wondering if we should: Add a field to target specifications. For targets that don't support i128 at the fundamental level.Or, maybe add Cargo feature to to cfg away the i128 stuff.Or unilateraly cfg away i128 in core for nvptx and msp430. I personally don't like either option. To me this seems like a limitation in what LLVM can do today but that can be fixed in the future.
Also, if we had pure MIR rlibs this wouldn't be a problem at all because the i128 stuff would never be passed to LLVM if it wasn't being used by the final application. To sum it up, I'm not sure what to do here ...
Right now on MSP430 values from the functions are returned using 4 16bit registers r12-r15. So in total you can return only 64 bits of data. There is an exception though, for returning large structs, the data is placed on the stack and reference is placed in the registers. So I guess it will be possible to bodge some hack that will treat i128 like a struct, but I don't know if anyone tried to implement 128 bit values on 16bit cpu, so it will be a new territory and potentially a lot of work for a feature that may not be useful at all on a small MCU.
yeah, but if LLVM can generate code for a function that returns then it should be able to use the same trick to return an . It's just that noboby has taught it how to do that. (i128 ops are totally different though but at least LLVM should emit intrinsics instead of raising assertions) How about on 8-bit AVR?
AFAIK, if Rust code calls Rust code, the ABI is totally irrelevant. We can do whatever we want. However, it starts getting a problem once we start talking to non Rust places, e.g. for FFI, or when LLVM emits a call to i128 intrinsics. For FFI we might want to end up forbidding fn's and structs that have i128 for targets where i128 is not specified by the convention or buggy in LLVM. With intrinsics, there has been major pain on Windows with because LLVM assumed a different ABI than what Rust provided with . It was "fixed" by introducing the "unadjusted" ABI, and it might work for nvptx64/msp430 as well, but it can just as well still cause an assertion failure. Real need for is only for platforms that want to cryptographic libraries, or maybe even std, as those two places might want to use . The higher stages of the compiler itself require i128 support as well, so if your platform wants to be a host platform for rustc, you'll need to support i128.
I'm okay with any of the three options (flag in , feature for , only setting it for those two platforms) for these platforms.
No. No. Namely the x64 windows ABI is kinda fuzzy about how i128 values are handled so carefully reading it we arrived at a conclusion that they ought to be handled the same way as regular 16-byte structs on 64 bit window platforms. A target cannot not support i128 at a fundamental level the same way a target cannot not support writing turing complete software. IMO what we should do here is to fudge the ABIs somewhat to take and return arguments via pointers (or the same way would be handled) on these targets. C ABI will be more complex; as already said there will always be at least one user of the C ABI with i128 arguments and stuff – LLVM with their intrinsics. The question here is how does LLVM lower to the intrinsics on these targets. If the backend does not lower and asserts for whatever reason, the targets have what’s essentially a broken backend implementation. Which seems to be broken for at least NVPTX () in exactly the place where I’d expect it to be broken if it was broken: That being said, since the C compilers do not support i128 for those targets, the actual interoperation does not matter whatsoever. All that’s really needs to be fixed is LLVM’s lowering of instructions to intrinsics using whatever ABI that works, even if its passing in arguments and taking return value via pointers. I, myself, am very strongly against splitting the language feature sets depending on the target.
How do we break the stalemate? If we submitted changes upstream for each of the smaller targets w/o support for i128 (providing indirection like large structs) it seems like it would meet resistance. As says, it's likely not considered useful since there's many targets without any native registers or support for such large values. But we also also have reluctance to limit this type to only appropriate targets. Does the "vision for 2017 cycle" provide any guidance? Does "provide a more seamless FFI story" help push us in one direction or the other?
regardless whether useful or not, we do need to support i128 on all targets, otherwise people will start using libraries that provide it across platforms.
Even if it needs to be "virtualized" in some way, and not wholly put into registers. In the worst case we'd have to provide some translation before passing things to LLVM, but it will affect things like alignment and generally looks like an ugly workaround. About FFI, I guess we can't really provide any FFI for i128 on targets where there is no C support for it, as generally the calling conventions only specify things that are part of C.
None of the targets Rust supports have native support for 128-bit integers, other than the fact that some can implement unchecked division and multiplication involving 128-bit integer operand with a single insn. Why? All that needs to be done here is to have the backends fixed. LLVM is supposed to be agnostic over bitwidth of integer, however useful or not somebody on the internet perceives such functionality to be. In other words, its a backend bug. So, its probably pretty clear that all it takes is to write a patch to fix bugs in these backends wrt operations on large values. I have no knowledge of these targets, am not familiar with the backends and haven’t the hardware to test any fixes on, so these patches will have to be written by somebody else. Late answer, but I’ve noticed this only now. This observation is wrong in multiple places. Firstly, (a.k.a. returning via pointer) is not a hack. Neither is it an exception. That’s what pretty much every single ABI¹ out there does for values that do not fit into register(s). It is most likely true that MSP430 ABI does not specify what to do with PODs this large, so it falls on us to pick whatever. ¹: For a less obscure example, x64 ABI used by code targetting Windows mandates to be used for any non-vector values over 64 bit in size, even though they could be fit it into registers. SysV ABI starts returning stuff via after some size threshold as well.
The MSP430 ABI specifies that aggregates larger than 32 bits are passed and returned via pointer. The backend just doesn't implement sret correctly yet (and in fact is implemented targeting an old and outdated ABI in any case). I'm working on fixing this in LLVM.
I'd bet that similar problems explain the NVPTX problems but I know nothing about that platform so I can't say that for sure.
I also agree that fixing backend is the right thing to do. I just think that it is not that easy as you say it is. MSP430 is the only 16bit architecture in LLVM, and this creates some trouble by itself. Good to know that someone is working on this.
does that LLVM patch really fix NVPTX as well?
No, it doesn't. this should be reopened for NVPTX.
BTW, thanks to for fixing this in LLVM upstream.
Triage: MSP430 has been fixed. No change in the NVPTX backend.
What needs to be done to get NVPTX working again?
You can see the patch I did for the MSP430 above - if it's the same problem you basically just have to add sret (structure return) support to the LLVM backend. I don't know anything about NVPTX but I'd bet it's pretty much the same procedure as what I did for the MSP.
Note that you can use the NVPTX backend today with the nightly compiler if you use a fork of the libcore crate that doesn't include 128 bit integers. Instructions .
I have some progress on the issue. First, I tried a hacky workaround with replacing with in arguments and return values with a custom FunctionPass. Can be transformed to: And compiled to PTX with vanilla LLVM (): Then, I made less hacky workaround patching LLVM NVPTX backend so it became possible to compile the code with without additional passes. Is compiled with patched to pretty much valid and working PTX assembly ;) But another related problems appears. When instead of: I write: I receive an error: And similar error when I try to compile : Does anybody have any suggestions about the problems? Looks like PTX doesn't have an instructions for the functions, and LLVM can't expand them.
Looks like the expansion from i128 to i64 is going OK but the i64 sdiv/mulo instructions aren't properly implemented. Not sure why that might be... it kind of looks like it's trying to assign the address of a library call and that's not working. Possibly the way you implemented the i128 expansion prevented a subsequent i64 expansion from running but I can't tell without seeing the code.
Run llc with -print-before-all and/or -print-machineinstrs to see where things diverge from what you expect. Look up in your platform ABI what the right action to take for 64-bit divides actually is. Post a link to your changes and someone may be able to take a look at them and see the problem.
Traditionally, in LLVM, is implemented by the library. However, its disabled on most platforms. Not sure why, but is written in C so they probably only can support i128 on platforms where they also provide C support, and clang's C support for i128 is right now very limited. Rust however the function, inside the crate (that is a wrapper for compiler-rt). There are good chances it works already!
It has pretty expected output before and after each pass. I think more interesting would be output with , but I don't really understand it. of the next commands: I tried to make changes over LLVM as minimal as possible: . I'm quite confused about and . Should they be compiled for target or host? If we can build at least for NVPTX, then can we just link against it? It still require some more changes for LLVM to be able to threat libcalls as normal calls. But then, all we would need is to link against . This blocked by but might be solved with my experimental .
For the target. At least its that way on other platforms. What is LLVM doing on 32 bit NVPTX when it encounters a 64 bit operation? On normal targets, this is one of the places compiler-rt gets used. Or idk, to cast a float to an int and back.
by the way, I didn't congratulate you yet for your progress. Really great work, loving it!
I'd like to see this move forward, so I'll summarize the above. Please correct me if I'm wrong: This issue was fixed for the MSP430 backend by submitting a patch to LLVM. worked on a patch to do the same for NVPTX, but it was not submitted to LLVM. I imagine that since that was a year ago, the patch will need some work to bring it up to date. Is this problem still happening with more recent builds? Perhaps it's been fixed by upstream in the meantime.
LLVM's MergeFunctions introduces aliases which can trigger a bug in macOS's linker when compiling with ThinLTO: For this reason Firefox has to be built with a patched version of when compiling with xLTO. Since the bug in question is pretty nasty (the above example shows a program just returning a different value with no indication that anything is wrong), we should probably try to not trigger it. Right now, however, it seems that one cannot even turn the MergeFunctions pass off in stable Rust. (I wonder if the pass should even be disabled by default on macOS?) cc & (this seems related to )
Is it a mergefunc bug or a ThinLTO bug? Can it be triggered without ThinLTO? If not, I would rather not blindly disable it on macOS, at least not when ThinLTO isn't enabled.
It's not a bug in mergefunc. It might not even be a bug in ThinLTO. It's just that mergefunc is the only thing in that generates symbol aliases in LLVM IR, and these are what can lead to "miscompilations" when using the macOS linker.
Has the ld64 bug been reported somewhere?
We could use to prevent the pass from emitting aliases on macOS, AFAIK.
This is already supported via either or in the target spec.
Do you mean that the test case also fails with enabled, or that we already have a knob to disable them?
Answering my own question, we already have a knob for that.
Which was because .
As and point to there is the unstable option which I've only tested on nightly. I guess there could be a stabilized option, but maybe what you really want to do is to patch the x8664 macos target definition (I believe this is the correct one: ).
Yes, I've been told that it has been reported to Apple. On nightly, one can already control the mergefunc pass. On stable, however, one is stuck with the default behavior. That's what this issue is mostly about.
just want to double-check my understanding: I would have thought one could use the options and to override the set of passes, even on the stable channel. Am I incorrect about this? (If I am correct, I nonetheless will admit that this is an ugly (and very fragile) method to opt out of the MergeFunctions pass)
I think that is correct, yes.
Test case: With rustc 1.20.0-nightly ( 2017-07-06), output when compiling with : correctly stops the dead code / unused type alias warning from being shown, but the trait bounds not enforced warning is shown anyway. Per and , this might be on purpose. I think this is the wrong decision. The point of is to allow Cargo to inhibit warnings in external dependencies. When building Servo it is not useful to spam the console with many warnings, future-proofing or not, about code that Servo has not direct control over. CC
Nominating for discussion. Not sure if compiler team or lang team is best, though, so tagging both...
From the lang team's point of view: definitely a bug.
Couple of bugs here: First off, we should not be ignoring the bounds in types. And sometimes they are needed. I'd like to fix this by not ignoring them, but I worry about the backcompat issues. Unknown risk there. Second, if we must warn, we should be emitting a regular lint that can be silenced. Plausibly, we should just remove the warning (eliminating the immediate problem), and prioritize trying to do a proper fix here.
Somewhat related to not ignoring bounds (but in the other direction): .
After some discussion in compiler team, decided to move this to a "future compatibility" lint, one that we will hopefully make more precise over time. Right now the check is not very good. At least this means you won't have to see it. We need some mentoring instructions though!
Some tips here:
triage: P-medium
I've hit this recently. It seems like it is possible to write code that requires exactly this bound. So it is quite bad that we cannot suppress this warning. Example code:
Agreed, this is poor. There just hasn't been a lot of energy to try and improve the situation.
Fixed in , probably by We should add a regression test for this particular case before we close this issue however, since I don't think the test in the PR detects a regression for the problem described in this issue. The problem in this issue is output on stderr, not that compilation fails ( exit code is 0 both with and without the fix in the PR). label E-needs-test
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
I suspect this is related to cc
tests/ui/suggestions/unnamable-
Very likely. I'll take a look soon.
For the record: it was that caused this.
Rust PR: This feature adds the following methods to : -
Anything in particular holding up the stabilization here? The implementation is trivial and docs lgtm.
I would like to add methods that return an exact , but that can wait.
These methods are a little odd, but seem reasonable to me following the example given:
Given how straightforward these methods are, I don't think there's any problem stabilising them?
They're straightforward in implementation, but conceptually tricky at a glance. I think the docs will need some fleshing out before stabilizing but I don't have any other concerns if somebody wants to write a PR!
This needs more testing with various interesting values that could produce interesting floating point numbers, and should not be stabilized without such.
tests were in this PR
It should work a bit like IDE's feature that finds everything that implements a given interface.
This should be a fairly small change (the most annoying part has already been done) so i'll open this up as a mentored issue. The bit that writes out the "Implementors" section is in . This is where the known implementors for a given trait are pulled out of the global context and listed out onto the rendered page. The bit that's responsible for creating links is , implemented on a local type. This kind of Item is easily made from the kind of Item that's otherwise worked on in , but there's a catch: The entries in the Implementors list aren't s. They're s, which are only a subset of the things you get on an Item. This is the "most annoying part" i mentioned earlier. Fortunately, i ran into this when creating the "Implementations on Foreign Types" section, so if you scroll up a little in , you can see so i could render the full impl block for them. The task for anyone who wants to take this on is to pull that up a little so that it's used for all the implementors, not just the foreign ones. With a in hand, combine it with the Context to create a and call to generate the link. ( This also helpfully includes the extra HTML bits that will flush the link to the right edge, which is really the final step.) And... that's it! The link should probably go between the and the where clause underneath it, so that it's aligned with the impl line and not the where clause. You may need to also close/open the that's wrapping the whole line to make sure the link itself isn't monospace. If you have any questions, let me know! Either comment here, or hop onto IRC in , or the impl period Gitter under .
On nightly (and beta I believe) the compiler will currently fail when cross compiling from x86_64 to x86 (after ensuring the standard library is in the right location) with the message: I believe this is a regression from and , which were backported, so I believe this is a stable regression. That being said I doubt anyone other than Cargo CI is doing this, so it may not be that big. I also believe that is working on a patch, but this should help track this issue.
I have been doing this with ring and ring-based projects for many months.
This issue is a proposal for the deprecation of error code . I opened a PR () as part of an effort to add long error explanations for error codes that didn't have one (). I chose and for my erroneous code example, I used the example from . I quickly realized, through running the example and other code that would also raise and through the CI failure message, that was not being raised. I went back to consult the issue I received the original code example from and noticed comments about not occurring anymore with . The issue was eventually labeled with . But, looking at the current contents of the file, can still be emitted even while it isn't: also doesn't have any UI tests as it is part of the error codes in . Since , is no longer actually emitted (although it is in code that it could) thanks to , I believe it should be deprecated. I would be happy to help deprecate the error code, if it is decided that it should happen. I would just need to know the proper steps to take to deprecate an error code. If there are reasons for why it is still an error code, I would love to be enlightened. claim <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
If is not emitted anymore then it can be removed immediately. A crater run can also be done to ensure that this is the case. I'm also happy to do this if you want.
Sure, that sounds good.
Sorry just for clarification, do you want me to do the PR or you?
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: Compiling with , after the emsdk is activated and emcc works, to compile properly Instead, this happened: Prints this error: I've tried adding to no avail <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details
runs successfully
Also is broken on ubuntu with the same error message (at least windows subsystem for linux)
rustc 1.53.0-nightly ( 2021-04-24) emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 2.0.12 () Here's some info I gathered: Rust tries to . I think Rust is assuming that this symbol comes from emscripten. emscripten has a : libc++abi.a: emscripten exceptions: this is what rustc is trying to use; libc++abi-noexcept.a: no exceptions: does not compile libc++abi-except.a: wasm exceptions: experimental; in emscripten's repo shows that was never compiled into libc++abi.a by This commit looks suspicious: Prior to emscripten SDK version 2.0.10, I think has been and never did anything. Rust probably shouldn't be calling a stubbed function. seems untested if you ask me because I don't know how it could ever have worked. I successfully compiled hello world with emscripten SDK version 2.0.9. That version still has the stub.
label I-prioritize T-compiler O-wasm
thanks for the analysis. Assigning priority as discussed in the of the Prioritization Working Group. Let's find someone who can have a look at this. label -I-prioritize +P-high +I-nominated
I recall with the LLVM 11 upgrade, the compat notes mentioned which version of Emscripten to use when compiling with the target.