-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Miscompilation of _BitInt passed as variadic argument #62261
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
Comments
@llvm/issue-subscribers-c2x |
Looking at the IR transformation here (relying on x86-64 ABI), the key difference is that in -O0, the code looks like this: %3 = load i13, ptr %vaarg.addr, align 2
store i13 %3, ptr %P1, align 2
%4 = load i13, ptr %P1, align 2
%conv = sext i13 %4 to i32
%cmp = icmp eq i32 %conv, -42 ( After a bout of -O1 opts, this becomes: %4 = load i13, ptr %vaarg.addr, align 2
%cmp = icmp eq i13 %4, -42 If I reintroduce the Per the LangRef, |
This sounds like the same problem as #62032, but in the ARM ABI. |
The initial code example:
has UB. 7.16.1p2, in part:
_BitInt does not undergo default argument promotions per 6.5.2.2p6 because _BitInt does not get integer promoted (per 6.3.1.1p2). So it boils down to type compatibility, and Does a slight tweak to the example to remove that UB demonstrates the same behavior?
|
I think there is still a bug - https://godbolt.org/z/bWKEnr9Ex . |
Thanks! For x64 there is, but I was curious if ARM also had the same failure. I'm still trying to wrap my mind around whether this is a clang IR generation issue or an LLVM backend issue. |
I have a small suspicion that it might be LLVM/CodeGen issue in missing support for |
That's correct for arithmetic types, but not in general (you can pass structure types or whatever, if you want to).
Yeah, the behavior at -O0 is why I also think this is an LLVM issue. From @jcranmer-intel's comment:
We see that passing an i13 through llvm.va_start also has the same behavior as passing an i32 (which is UB), so I think it may not be Clang's lowering. WDYT? |
If i32 in function arguments of the original example is the only problem, I agree. Although I can't really identify other problems that might be clang's fault. |
Note that this seems to be working now https://godbolt.org/z/hW9KMEr5b . |
This code is miscompiled at all optimisation levels except for
-O0
, and for all (or many) targets (I've tried Arm v7M, AArch64 and x86_64):Generated code for v7M:
The draft ABI spec for
_BitInt
(https://github.com/ARM-software/abi-aa/pull/191/files) says that the non-significant bits are unspecified, but the generated code for F8 compares the 16-bit chunk (loaded with the LDRH instruction) containing the argument and 3 unspecified bits to a constant which has those bits set to zero, which fails because main sign-extended the value into those bits, setting them to 1.For a non-variadic version of the function, we emit a
BFC
instruction to clear the unspecified bits before comparing them, which is correct:The text was updated successfully, but these errors were encountered: