| Age | Commit message (Collapse) | Author | Files | Lines |
|
LLVM 15 switched to opaque pointers by default and no longer supports typed pointers.
Remove deprecated LLVM calls and update test.
Original-patch-by: Vladimir Petko <vladimir.petko@canonical.com>
Signed-off-by: Luc Van Oostenryck <lucvoo@kernel.org>
|
|
Signed-off-by: Luc Van Oostenryck <lucvoo@kernel.org>
|
|
These headers are often complex and full of implementation
specificities. They have no place in the testsuite.
So, remove these includes and replace them by the prototype
of the function being used.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
On the cygwin platform, a 'sparsei' backend test, which uses the llvm
'lli' tool, fails due to a dynamic linking error:
$ make check
...
TEST sum from 1 to n (backend/sum.c)
error: actual output text does not match expected output text.
error: see backend/sum.c.output.* for further investigation.
--- backend/sum.c.output.expected 2018-06-03 18:27:11.502760500 +0100
+++ backend/sum.c.output.got 2018-06-03 18:27:11.307670000 +0100
@@ -1,2 +0,0 @@
-15
-5050
error: actual error text does not match expected error text.
error: see backend/sum.c.error.* for further investigation.
--- backend/sum.c.error.expected 2018-06-03 18:27:11.562997400 +0100
+++ backend/sum.c.error.got 2018-06-03 18:27:11.481038800 +0100
@@ -0,0 +1 @@
+LLVM ERROR: Program used external function 'printf' which could not be resolved!
error: Actual exit value does not match the expected one.
error: expected 0, got 1.
...
Out of 288 tests, 277 passed, 11 failed (10 of them are known to fail)
make: *** [Makefile:236: check] Error 1
$
Note the 'LLVM ERROR' about the 'printf' external function which could
not be resolved (linked). On Linux, it seems that the 'lli' tool (JIT
compiler) can resolve the 'printf' symbol, with the help of the dynamic
linker, since the tool itself is linked to the (dynamic) C library.
On windows (hence also on cygwin), the 'lli' tool fails to resolve the
external symbol, since it is not exported from the '.exe'.
The 'lli' tool can be used as an interpreter, so that the JIT compiler
is disabled, which also side-steps this external symbol linking problem.
Add the --[no-]jit options to the 'sparsei' tool, which in turn uses
(or not) the '-force-interpreter' option to 'lli'. In order to fix the
failing test-case, simply pass the '--no-jit' option to 'sparsei'.
Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Currently all casts to pointers are processed alike.
This is simple but rather unconvenient as it correspond to
different operations that obeys to different rules and
which later need extra checks.
Change this by using a specific instructions (OP_UTPTR) for
unsigned integer to pointers.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
In sparse-llvm, when a reference to a function is made via
get_sym_value(), for example for a call, the reference is
created with LLVMAddFunction() and if needed later, the existing
reference is returned via LLVMGetNamedFunction().
This is the correct way to do it.
However, when emitting the code for a function definition, a fresh
reference is always made. If a previous reference to this function
already existed, the second one will have a slightly different name:
the given name suffixed by ".<somenumber>". LLVM does this for every
created references, to disambiguate them. As consequence, the
compiled function will not be name "<functionname>", as expected,
but "<functionname>.<somenumber>".
Fix this by always using get_sym_value() when emitting the code
for the function definition as this will return the reference
for the given function name if it already exist.
This has the added bonus to remove some code duplication.
CC: Dibyendu Majumdar <mobile@majumdar.org.uk>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Some testcases have their command specified as './<command name>'
but the './' part is unneeded as all commands are first prefixed
with '../' before being run.
Furthermore, the presence of these './' inhibit simple
filtering of the disabled commands.
Fix this by stripping the './' where it was used.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Floating-point arithmetic is quite different from the
arithmetic on integers or the one of real numbers.
In particular, most transformations, simplifications that can
be done on integers are invalid when done on floats.
For example:
- associativity doesn't hold
- distributivity doesn't hold
- comparison is tricky & complex
This is because (among others things):
- limited precision, rounding everywhere
- presence of signed zeroes
- presence of infinities
- presence of NaNs (signaling or quiet)
- presence of numbers without inverse
- several kind of exceptions.
Since they don't follow the same rules as their integer
counterpart, better to give them a specific opcode
instead of having to test the type of the operands at
each manipulation.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
LLVM automatically add an numeric suffix for names
automatically created. So, if intermediate names must
be created for a pseudo whose name was, for example, "%R4",
these new names will be "%R41", "%R42".
This is quite annoying because we can't make the distinction
between these names and the original names, (maybe of some other
pseudos whose names were "%R41" & "%R42).
Change this by adding a "." at the end of each name, as this will
then allow to see what the original name was.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The linearized code, sparse's IR, have no use of C's complex type
system. Those types are checked in previous phases and the pseudos
doesn't have a type directly attached to them as all the needed
typing info info are conveyed by the instructions.
In particular, PSEUDO_VAL (used for integer and address constants)
are completely typeless.
There is a problem with this when calling a variadic function
with a constant argument as in this case there is no type in the
function prototype (for the variadic part, of course) and there is
no defining instructions holding the type of the argument.
Fiw this by using the type of the arguments explicitly given
in the OP_CALL instructions.
Reported-by: Dibyendu Majumdar <mobile@majumdar.org.uk>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Pointer arithmetic and/or simplification can mixup pointer
and integer types.
Fix this by adding casts before all non-floating point binops
and adjust the result type if needed to match the instructio.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Since sparse's constant are typeless comparing a pointer with
an address constant lack correct type information.
Fix this by casting the constant to the same type as the LHS.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
In output_op_compare() everything that is not of interger
type is treated as floats. Pointers disagree.
Fix this by rearranging the code and treat pointers like integers
as required for LLVM's icmp.
Reported-by: Dibyendu Majumdar <mobile@majumdar.org.uk>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
In sparse-llvm the field 'priv' of a pseudo is used to store
the corresponding LLVMValueRef. This field is normaly assigned
when processing the instruction that produces the speudo.
In output_op_store(), the field insn->target->priv is overwritten
by the LLVMValueRef returned by LLVMBuildStore().
It's unclear what this return value is:
- this corrupts the pseudo, making it unusable in subsequent
instructions.
- there is no reason to change this field anyway.
Fix this by removing the assignment to insn->target->priv
in output_op_store().
Reported-by: Dibyendu Majumdar <mobile@majumdar.org.uk>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
In sparse-llvm there is the assumption that a PSEUDO_VAL is always
of integer type. But this is not always the case: constant pointers,
like NULL, are also of the PSEUDO_VAL kind.
Fix this by adding a helper 'val_to_value()' and using the
instruction's type where this pseudo is used as the type of the value.
Note: while this patch improve the situation, like for example for the
test cases added here, it's still not correct because now we're making
the assumption that 'insn->type' is the type we need for the pseudo.
This is often true, but certainly not always.
For example this is not true for:
- OP_STORE/OP_LOAD's insn->src
- OP_SET{EQ,...}'s insn->src[12]
- probably some others ones
- in general, obviously, for any instructions where the target has
a different type than the operands.
Reported-by: Dibyendu Majumdar <mobile@majumdar.org.uk>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Some testcase have their command specified as './<command name>'
but the './' part is unneeded as all commands are first prefixed
with '../' before being run.
Furthermore, the possible presence of these './' force the
use of 'basename' when filtering out the disabled commands.
Change this by stripping the './' where is was used.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Avoid null pointer dereference when ->ident is null (e.g., anonymous
struct). Also, use ->aux to avoid recursion.
Signed-off-by: Xi Wang <xi.wang@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Xi Wang <xi.wang@gmail.com>
Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Use the fix from d5bd3662 ("sparse, llvm: Fix type of loaded values").
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Xi Wang <xi.wang@gmail.com>
Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Remove repeated code, such as get_func_type() vs sym_func_type(),
pseudo_type() vs symbol_type().
Fix generating variadic functions.
Add a test case using printf().
Cc: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: Xi Wang <xi.wang@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
PHI in LLVM is different from that in sparse. LLVM requires PHI "for
each predecessor basic block of the current block" even if the current
block doesn't use it. It's tricky to correctly place PHI.
This patch implements a simpler and safer strategy:
1) allocate an alloca for each phi, and
2) translate phi/phisrc to load/store alloca.
LLVM optimizations will promote load/store to registers.
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Signed-off-by: Xi Wang <xi.wang@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Instead of making the computed address a pointer to an int type
large enough to hold a pointer, make it a pointer to the memory
object being loaded. This fixes another LLVM warning.
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Christopher Li <sparse@chrisli.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Acked-by: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
LLVM expects the first argument of "br" and "select" to be of type i1,
so add an "icmp ne <srcty> %src, 0" for other types.
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Jonathan Neuschäfer reports:
A simple function like this will compile to the following llvm
bitcode:
/* C */
void func(void) {
return;
}
/* LLVM */
define i8 @func() {
L0:
ret void
}
The return type of the function and the type in the return instruction
don't match.
I found this inconsistency by running LLVM's bitcode validation on the
bitcode produced by sparse-llvm.
Move 'void *' special-casing from sym_basetype_type() to sym_ptr_type()
to fix the issue.
Reported by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Jonathan Neuschäfer writes:
compiling a little real-world program with sparse-llvm, it segfaulted.
Using a tool called "delta"[1] and some bash scripting, I managed to
reduce the code to this test case:
extern struct foo *foop;
extern void func(struct foo *f);
int main(int argc, char **argv) {
func(foop);
}
The problem is that pseudo_to_value() does not know abou the extern
symbol because Sparse never calls output_data() on it which registers
globals with LLVMAddGlobal().
As explained by Linus, 'extern' symbols are just names with types. They
don't have any value associated with them, they just have the type and
the name. Therefore we need to explicitly call LLVMAddGlobal() for
symbols we have not encountered in pseudo_to_value().
Reported by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
This patch adds casting backend validation test cases for the _Bool data type.
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
As it turns out, our validation test harness doesn't catch <stdbool.h> related
breakage so add a minimal test case that does.
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
|
|
This patch implements code generation for floating point versions of OP_BINCMP.
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
This patch implements LLVM code generation for OP_SET_LE, OP_SET_GE, OP_SET_BE,
and OP_SET_AE.
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
This patch implement unsigned less than and greater than comparison operator
LLVM code generation.
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
This patch implement code generation for OP_PTRCAST using LLVMBuildBitCast().
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
This patch implements support for function pointer types and function pointer
calls to the LLVM backend.
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
This patch adds support for SYM_UNION in symbol_type(). The LLVM API does not
provide support for unions so we treat them as opaque structs.
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
This patch adds support for SYM_ARRAY in symbol_type().
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Use LLVMGetTypeByName() to look up struct data types to fix code generation for
structs that refer to themselves.
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
The generated asm for logical-ops.c test case looks as follows on x86-64:
GCC 4.6:
0000000000000000 <and_bool>:
0: 31 c0 xor %eax,%eax
2: 85 f6 test %esi,%esi
4: 0f 95 c0 setne %al
7: 31 d2 xor %edx,%edx
9: 85 ff test %edi,%edi
b: 0f 95 c2 setne %dl
e: 21 d0 and %edx,%eax
10: c3 retq
0000000000000020 <uand_bool>:
20: 31 c0 xor %eax,%eax
22: 85 f6 test %esi,%esi
24: 0f 95 c0 setne %al
27: 31 d2 xor %edx,%edx
29: 85 ff test %edi,%edi
2b: 0f 95 c2 setne %dl
2e: 21 d0 and %edx,%eax
30: c3 retq
0000000000000040 <or_bool>:
40: 09 fe or %edi,%esi
42: 0f 95 c0 setne %al
45: 0f b6 c0 movzbl %al,%eax
48: c3 retq
0000000000000050 <uor_bool>:
50: 09 fe or %edi,%esi
52: 0f 95 c0 setne %al
55: 0f b6 c0 movzbl %al,%eax
58: c3 retq
Sparse/LLVM:
0000000000000000 <and_bool>:
0: 85 f6 test %esi,%esi
2: 0f 95 c0 setne %al
5: 85 ff test %edi,%edi
7: 0f 95 c1 setne %cl
a: 20 c1 and %al,%cl
c: 0f b6 c1 movzbl %cl,%eax
f: c3 retq
0000000000000010 <uand_bool>:
10: 85 f6 test %esi,%esi
12: 0f 95 c0 setne %al
15: 85 ff test %edi,%edi
17: 0f 95 c1 setne %cl
1a: 20 c1 and %al,%cl
1c: 0f b6 c1 movzbl %cl,%eax
1f: c3 retq
0000000000000020 <or_bool>:
20: 09 f7 or %esi,%edi
22: 0f 95 c0 setne %al
25: 0f b6 c0 movzbl %al,%eax
28: c3 retq
0000000000000030 <uor_bool>:
30: 09 f7 or %esi,%edi
32: 0f 95 c0 setne %al
35: 0f b6 c0 movzbl %al,%eax
38: c3 retq
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|