Summary:
This patch implements the `fgets`, `getc`, `fgetc`, and `getchar`
functions on the GPU. Their implementations are straightforward enough.
One thing worth noting is that the implementation of `fgets` will be
extremely slow due to the high latency to read a single char. A faster
solution would be to make a new RPC call to call `fgets` (due to the
special rule that newline or null breaks the stream). But this is left
out because performance isn't the primary concern here.
Summary:
This patch improves the implementation of the standard `rand()` function
by implementing it in terms of the xorshift64star pRNG as described in
https://en.wikipedia.org/wiki/Xorshift#xorshift*. This is a good,
general purpose random number generator that is sufficient for most
applications that do not require an extremely long period. This patch
also correctly initializes the seed to be `1` as described by the
standard. We also increase the `RAND_MAX` value to be `INT_MAX` as the
standard only specifies that it can be larger than 32768.
Summary:
There is currently effort to change over the default AMDGPU code object
version https://github.com/llvm/llvm-project/pull/65410. However, this
unfortunately causes problems in the LLVM LibC test suite that leads to
a hang while executing. This is most likely a bug to do with indirect
call optimization, as it can be avoided without optimizations or with
manually preventing inlining in the AMDGPU startup code.
This patch sets the AMDGPU code object version to be four explicitly on
the LibC test suite. This should unblock the efforts to move the default
to 5 without breaking the test suite. This isn't a great solution, but
there is currently some time pressure to get COV5 landed and this seems
to be the easiest solution.
Summary:
This patch implements fwrite, putc, putchar, and fputc on the GPU. These
are very straightforward, the main difference for the GPU implementation
is that we are currently ignoring `errno`. This patch also introduces a
minimal smoke test for `putc` that is an exact copy of the `puts` test
except we print the string char by char. This also modifies the `fopen`
test to use `fwrite` to mirror its use of `fread` so that it is tested
as well.
The %p format wasn't correctly passing along flags and modifiers to the
integer conversion behind the scenes. This patch fixes that behavior, as
well as changing the nullptr behavior to be a string conversion behind
the scenes.
Reviewed By: lntue, jhuber6
Differential Revision: https://reviews.llvm.org/D159458
This test creates a time_t variable and assigns 0xfffffffffe1d7b01 which
overflows the maximum time_t value for 64-bit time_t, then checks if the
syscall fails and errno was set.
In systems with sizeof(time_t) == 4, the value is narrowed down to
0xfe1d7b01 and doesn't overflow, causing the test to fail.
This patch then disables the test on systems with 32 bits long time_t.
Previously, these tests expected that calling mktime with a struct tm
that caused overlow to succeed with return -1
(TimeConstants::OUT_OF_RANGE_RETURN_VALUE), however, the Succeeds call
expects the errno to be zero (no failure).
This patch fixes the expected calls to fail with EOVERFLOW. These tests
are only enabled to 32-bit systems, and are probably not being tested on
the arm32 buildbot, that's why this was not a problem before.
This test was setting tv_nsec to a negative value, which as per the
standard this is an EINVAL:
The value in the tv_nsec field was not in the range [0, 999999999] or
tv_sec was negative.
https://man7.org/linux/man-pages/man2/nanosleep.2.html
The inbox/outbox loads are performed by the current warp, not a single thread.
The outbox load indicates whether a port has been successfully opened. If some
lanes in the warp think it has and others think the port open failed, as the
warp happened to be diverged when the load occurred, all the subsequent control
flow will be incorrect.
The inbox load indicates whether the machine on the other side of the RPC channel
has progressed. If lanes in the warp have different ideas about that, some will
try to progress their state transition while others won't. As far as the RPC layer
is concerned this is a performance problem and not a correctness one - none of the lanes
can start the transition early, only miss it and start late - but in practice the calls
layered on top of RPC do not have the interface required to detect this event and retry
the load on the stalled lanes, so the calls layered on top will be broken.
None of this is broken on amdgpu, but it's likely that the readfirstlane will have
beneficial performance properties there. Possible significant enough that it's
worth landing this ahead of fixing gpu::broadcast_value on volta.
Essentially volta wasn't adequately considered when writing this part of the protocol.
It's a bug present in the initial prototype and propagated thus far, because none of
the test cases push volta into a warp diverged state in the middle of the RPC sequence.
We should have some test cases for volta where port_open and equivalent are called
from diverged warps.
Reviewed By: jhuber6
Differential Revision: https://reviews.llvm.org/D159276
The GPU has the ability to sleep for very short periods of time. We can
map this to the existing `nanosleep` utility. This patch maps the
nanosleep utility to the existing hardware instructions as best as
possible.
Depends on D159118
Reviewed By: JonChesterfield, sivachandra
Differential Revision: https://reviews.llvm.org/D159225
Summary:
We should check for the GPU architectures first, since `__linux__` can
be set potentially during these compilations. Also the test needs to be
a hermetic test.
This patch changes a test case that tests for overflow when time_t is
32-bit long, however, it was checking size_t instead of time_t.
This in on par with other testcases that correctly check the size of
time_t (asctime_test.cpp, gmtime_r_test.cpp and gmtime_test.cpp).
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D159113
This patch adds some extra cases to the existing argument list test in
`libc`, mainly dealing with arguments of varying sizes and primitive
types.
The purpose of this patch is to provide a wider test area when we begin
to provide varargs support on the GPU as there is no other runtime code
that really tests it. So, running these tests more exhaustively in the
GPU libc project will serve as the runtime tests for GPU vararg support in
D158246.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D158867
Implement double precision exp2 function correctly rounded for all
rounding modes. Using the same algorithm as double precision exp function in
https://reviews.llvm.org/D158551.
Reviewed By: zimmermann6
Differential Revision: https://reviews.llvm.org/D158812
Implement double precision exp function correctly rounded for all
rounding modes. Using 4 stages:
- Range reduction: reduce to `exp(x) = 2^hi * 2^mid1 * 2^mid2 * exp(lo)`.
- Use 64 + 64 LUT for 2^mid1 and 2^mid2, and use cubic Taylor polynomial to
approximate `(exp(lo) - 1) / lo` in double precision. Relative error in this
step is bounded by 1.5 * 2^-63.
- If the rounding test fails, use degree-6 Taylor polynomial to approximate
`exp(lo)` in double-double precision. Relative error in this step is bounded by
2^-99.
- If the rounding test still fails, use degree-7 Taylor polynomial to compute
`exp(lo)` in ~128-bit precision.
Reviewed By: zimmermann6
Differential Revision: https://reviews.llvm.org/D158551
The fuzzer found that a 100,000 digit number could possibly return an
incorrect result. This patch fixes the issue.
Reviewed By: lntue
Differential Revision: https://reviews.llvm.org/D158118
Fuzzing revealed bugs in the %e and %g conversions. Since these are very
similar, they are grouped together. Again, most of the bugs were related
to rounding. As an example, previously the code to check if the number
was truncated only worked for digits below the decimal point, due to it
being originally designed for %f. This patch adds a mechanism to check
the digits above the decimal point for both %e and %g.
Reviewed By: sivachandra, lntue
Differential Revision: https://reviews.llvm.org/D157536
Fuzzing revealed several bugs in the %f float conversion. This patch
fixes them. Most of these bugs are related to rounding, such as
1.999...999 being rounded to 2.999...999 instead of 2.000...000 due to
rounding up not properly changing the nines to zeros. Additionally, much
of the rounding infrastructure has been refactored out so it can be
shared with the other conversions.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D157535
The trailing zeroes were previously not counted when calculating the
padding, which caused a high-precision number to get too much padding.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D157534
The GPU has much tighter requirements for handling IO functions.
Previously we attempted to define the GPU as one of the platform files.
Using a common interface allowed us to easily define these functions
without much extra work. However, it became more clear that this was a
poor fit for the GPU. The file interface uses function pointers, which
prevented inlining and caused bad perfromance and resource usage on the
GPU. Further, using an actual `FILE` type rather than referring to it as
a host stub prevented us from usin files coming from the host on the GPU
device.
After talking with @sivachandra, the approach now is to simply define
GPU specific versions of the functions we intend to support. Also, we
are ignoring `errno` for the time being as it is unlikely we will ever
care about supporting it fully.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D157427
Sometimes the vfprintf test was failing, I suspect that's due to it
using the same filename as the fprintf test. This patch fixes that
problem by changing the filename of the vfprintf output file.
Reviewed By: lntue
Differential Revision: https://reviews.llvm.org/D157523
This patch is an alternative to D155902. It provides the following benefits:
- No buffer manual allocation and error handling for the general case
- More flexible API : width specifier, sign and prefix handling
- Simpler code
The more flexible API removes the need for manually tweaking the buffer afterwards, and so prevents relying on implementation details of IntegerToString.
Reviewed By: michaelrj, jhuber6
Differential Revision: https://reviews.llvm.org/D156981
This patch is an alternative to D155902. It provides the following benefits:
- No buffer manual allocation and error handling for the general case
- More flexible API : width specifier, sign and prefix handling
- Simpler code
The more flexible API removes the need for manually tweaking the buffer afterwards, and so prevents relying on implementation details of IntegerToString.
Reviewed By: michaelrj, jhuber6
Differential Revision: https://reviews.llvm.org/D156981
This patch is large, but is almost entirely just adding casts to calls
to syscall_impl. Much of the work was done programatically, with human
checking when the syntax or types got confusing.
Reviewed By: mcgrathr
Differential Revision: https://reviews.llvm.org/D156950
Some printf implementations perform a null check on pointers passed to
%s. While that's not in the standard, this patch adds it as an option
for compatibility. It also puts a similar check in %n behind the same
flag.
Reviewed By: lntue
Differential Revision: https://reviews.llvm.org/D156923
The v variants of the printf functions take their variadic arguments as
a va_list instead of as individual arguments. They are otherwise
identical to the corresponding printf variants. This patch adds them
(vprintf, vfprintf, vsprintf, and vsnprintf) as well as tests.
Reviewed By: phosek
Differential Revision: https://reviews.llvm.org/D157138
This patch adds a bunch of ifdefs to handle the 32 bit versions of
some syscalls, which often only append a 64 to the name of the syscall
(with exception of SYS_lseek -> SYS_llseek and SYS_futex ->
SYS_futex_time64)
This patch also tries to handle cases where wait4 is not available
(as in riscv32): to implement wait, wait4 and waitpid when wait4 is
not available, we check for alternative wait calls and ultimately rely
on waitid to implement them all.
In riscv32, only waitid is available, so we need it to support this
platform.
Reviewed By: michaelrj
Differential Revision: https://reviews.llvm.org/D148371
The Fuchsia zxtest library has ASSERT_DEATH but not EXPECT_DEATH.
The latter may be added in the future, but for now just use the
former as substitute.
Reviewed By: abrachet
Differential Revision: https://reviews.llvm.org/D156940
Other libc implementations support underscores in NaN(n-char-sequence)
strings. Us not supporting that is causing fuzz failures, so this patch
solves the problem.
Reviewed By: lntue
Differential Revision: https://reviews.llvm.org/D156927
This patch fixes the return time for sched_getscheduler which was set to
always zero. The syscall documentation, however, defines:
On success, sched_getscheduler() returns the policy for the thread (a
nonnegative integer).
I also changed the return type for sched_setscheduler, but this change
didn't impact and test case.
This patch also removes the duplicated code from param_and_scheduler_test.cpp
and adds SCHED_BATCH and SCHED_IDLE to the tests.
Reviewed By: michaelrj
Differential Revision: https://reviews.llvm.org/D156700
The number of trailing zeroes was being calculated incorrectly. It was
assuming that it could add all of the implicit leading zeroes in the
final block, not accounting for the number of digits actually reqested
by the precision.
Reviewed By: lntue
Differential Revision: https://reviews.llvm.org/D156489
This patch adds support for `fread` on the GPU via the RPC mechanism.
Here we simply pass the size of the read to the server and then copy it
back to the client via the RPC channel. This should allow us to do the
basic operations on files now. This will obviously be slow for large
sizes due ot the number of RPC calls involved, this could be optimized
further by having a special RPC call that can initiate a memcpy between
the two pointers.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D155121
The expected number for the max ptrdiff value was expected to be exactly
4294967296 (2**32) for 32 bit systems, when it should be
4294967295 (2**32 - 1). This also adds a second test to check for this
case on non-32 bit systems.
Reviewed By: lntue, mikhail.ramalho
Differential Revision: https://reviews.llvm.org/D156257
Summray:
We landed some extra math support, which is apparently broken on the
max / min functions. the `mod` functions cannot be tested as they use
`std::limits` which don't exist in a freestanding environment. Also the
`blockstore` test seems to be broken. We will need to fix these in the
future but for now we need something in a workable state.
Reviewed By: jplehr
Differential Revision: https://reviews.llvm.org/D156329
This patch does the noisy work of removing the test opcodes from the
exported interface to an interface that is only visible in `libc`. The
benefit of this is that we both test the exported RPC registration more
directly, and we do not need to give this interface to users.
I have decided to export any opcode that is not a "core" libc feature as
having its MSB set in the opcode. We can think of these as non-libc
"extensions".
Reviewed By: JonChesterfield
Differential Revision: https://reviews.llvm.org/D154848