User Details
- User Since
- Feb 1 2019, 9:58 AM (216 w, 2 d)
Feb 10 2023
My worry is: Does having such an indeterminate output value, combined with other optimization passes, trigger unbounded UB from the system as-a-whole? E.g., because we can duplicate and coalesce FP math instructions, and make a different optimization decision for each duplicated instance separately, a single fadd with an sNaN input could appear to be a qNaN to some of its uses and an sNaN for others. Which then as discussed changes the results of finite values from FP computations too. Could that cause problems in downstream optimization passes?
Feb 9 2023
because, from what I understand, before IEEE 754 specified how to encode quietness for NaNs, MIPS (and PA-RISC) arbitrarily chose the opposite encoding to what IEEE 754-2008 specifies, so LLVM generating quiet NaNs following IEEE 754-2008 produces NaNs that are actually signalling NaNs for old MIPS. MIPS later added a mode bit allowing swapping its interpretation of signalling/quiet NaNs to fall in line with the IEEE 754-2008 spec -- new MIPS has that set to IEEE 754-2008 mode.
Then, LLVM is broken on old MIPS. There's just no way it's okay to spuriously introduce sNaNs when the original program didn't contain sNaNs in the first place. It results in incorrect results, without the original user code breaking any assumptions.
Feb 5 2023
Regarding what LLVM actually does, I think it would be more accurate to say that floating-point IR instructions are lowered to the closest target-specific counterpart, but optimizations assume that the lowering conforms to IEEE 754 semantics
Feb 4 2023
Floating-point math operations assume that all NaNs are quiet.
Feb 1 2023
Okay, so the rules would be something like: when a floating point operation outputs a NaN, that is
- either any of its input NaNs (even if that is signaling, which violates IEEE-754)
- or an arbitrary quiet NaN
No, arithmetic operations cannot produce signaling nans. Signaling nans only come from initialization.
"undefined" is a dangerous word. I hope you didn't mean that it is literally undef.
Jan 31 2023
I agree this optimization should not be performed. Also see https://github.com/llvm/llvm-project/issues/60418 for a counterexample.
Jan 9 2023
Dec 28 2022
Dec 21 2022
I see, thanks. I guess this summary patch is then the best place for those comments still.
Hm I cannot find the diff that the 2nd and 3rd comment refer to in https://reviews.llvm.org/D104268? Am I looking at the wrong thing? It refers to the new "Scoped NoAlias Related Intrinsics" section of the LangRef.
Sorry for the noise. This patchset stuff is really confusing, I have no clue how to navigate them.
Okay I will try to post the same comments there.
How was X initialized/observed with -NaN? Testing for bit-equality requires casting to integer. There's no way to do that comparison with FP values?
Dec 11 2022
Note that semantics of fneg/fabs is irrelevant for this optimization to be a problem. That's why I keep using float Y = true ? X1 : X2; as the example. To my knowledge nobody disputes that NaN < 0.0 must deterministically return false, so X < 0.0 ? -X : X will behave the same as false ? -X : X when X is a NAN, which is the same as just X -- I hope this much is uncontroversial. The only potential question then is whether float Y = X must preserve the NAN sign bit of X.
the signbit of NAN is never meaningful in real code,
Comparisons don't look at the sign of NaN. They are not bitwise operations like fabs/fneg.
I am a bit confused by the explanation. The signbit of NaN is "insignificant" for *some* operations like + in the sense that they just pick an arbitrary sign bit if the result is NaN (and so the sign bit of a NaN input has no effect). But it affects the behavior of >, fneg, and fabs (the operations involved here) in totally deterministic ways, right? When only >, fneg, fabs are used (and copies of the floating point value from one register to another), the sign bit is fully significant, like all the others.
Dec 9 2022
Mar 7 2021
LGTM, thanks. :)
Mar 6 2021
Mar 5 2021
The exact semantics of lifetime.start depends on the pattern matching patterns in the stack coloring algorithm. So this intrinsic cannot be abused. It must be used for the uses it was created for only.
Jan 11 2021
You mean not supported by codegen, right? It would still have been possible for somebody to use them in some intermediate-only use of LLVM. I agree with your more important points, though.
+ The base pointer has an in bounds address of the allocated object it is based on [...]
Dec 26 2020
I'd say that as a matter of policy the LangRef must be a document that people can rely on, else what's the point of having it? Since it is written as-if lifetime intrinsics could be applied rather freely
Dec 21 2020
Given the proposed semantic of lifetime.start, the program had UB semantics prior to inlining, we might not have known it statically but that is not an issue.
Dec 18 2020
This mixes semantic and implementation of an alloca. Let's not do that.
Two allocas with disjoint lifetimes should be able to be overlapped.
Why wouldn't/shouldn't it mean exactly what it means for stack allocations?
"The memory region specified in the lifetime start is dead until a lifetime start makes that memory accessible, ..."
Sep 4 2020
Shouldn't it be "maynotprogress" (or "maybenoprogress" or so)? *Every* function *may* progress, but only those with this marker are also allowed to not "make progress".
Changed name from noprogress to mayprogress for clarity.
Aug 28 2020
I don't look at it as added or removed, for me it is a boolean flag, with a default that requires progress. It is more like nobuiltin, noduplicate, nomerge, returns_twice, .... The difference is that I don't see this being deduced. It is just a description of the input semantics, not a property we derive from the code (to describe the code). Unclear if the view makes a difference, let me know what u think :)
Aug 27 2020
It depends on how you look at it:
From the perspective of optimizations we can do, sure absence is the one that enables more.
From the perspective of source behavior, it just distinguishes between two alternatives, so both option w/ and w/o flag have the same information value.
Aug 20 2020
This attribute indicates that the function is guaranteed to not make progress
Aug 10 2020
It isn't contradiction, but about whether noprogress brings useful information or not, though.
Aug 9 2020
No happens-before rule is needed for sequential programs. The compiled program must exhibit all observable events in the same order as the source program.
Yes, C++ makes infinite loops UB (and C, under some conditions). This PR is about making LLVM support languages like JavaScript or Rust that do not have such UB.
I don't know what this statement is based on.
Aug 8 2020
If there are no accesses to the variable, there are no calls of the function. Throwing away the loop is valid, analysis of whether it is finite is not required.
Aug 6 2020
Either should do the trick after a while given that all optimizations need to preserve/handle attribute already, you cannot just drop them and so noprogress should be sufficient.
I am going solely off the description here as I am not familiar with LLVM internals. Looking forward to the LangRef update. :)
Nov 27 2019
Nov 21 2019
Aug 15 2019
A fence is not an atomic operation on its own in C++. See http://eel.is/c++draft/atomics.fences where it says "is a synchronization operation *if* [...]".
Aug 12 2019
Does this need a side effect? Per the current definition, no. Per C++, yes.
Jul 23 2019
I cannot land commits myself, could you help with that?
Feb 26 2019
I fixed the typo.
Fix typo.
Please make sure you have llvm-commits added as a subscriber when creating patches in the future