diff options
| author | Pekka Enberg <penberg@kernel.org> | 2012-06-08 15:47:33 +0300 |
|---|---|---|
| committer | Pekka Enberg <penberg@kernel.org> | 2012-06-09 14:04:28 +0300 |
| commit | ccf42dc22ef4354ef6db1673a5e2b2bc0a6be273 (patch) | |
| tree | 4a96a06def51fed696d7e7152a86a720c9d165e6 | |
| parent | 9084e55561e9aa11d291c1a9acaf1a7584651b73 (diff) | |
| download | sparse-dev-ccf42dc22ef4354ef6db1673a5e2b2bc0a6be273.tar.gz | |
sparse, llvm: Fix global string access code generation
This patch attempts to fix code generation for global string access:
static char *foo = "Foo !\n";
extern int puts(const char *s);
int main(int argc, char *argv[])
{
puts(foo);
return 0;
}
The generated executable causes a SIGSEGV:
[penberg@tux sparse]$ ./sparsec foo.c && ./a.out
Segmentation fault
But as pointed out by Xi Wang, the problem is in "output_load()":
I guess the problem is that sparse-llvm generates an incorrect type `load i64*'
in llvm from the sparse instruction load.64.
load.64 %r2 <- 0[foo]
call.32 %r1 <- puts, %r2
ret.32 $0
With the new ->ctype in pseudo sparse-llvm should be able to generate the
correct type. I am playing with an LLVM backend with typed pseudos; it
generates the following code, which seems okay.
@0 = internal global [7 x i8] c"Foo !\0A\00", align 1
@foo = internal global i8* getelementptr inbounds ([7 x i8]* @0, i64 0, i64 0), align 8
define i32 @main(i32 %argc, i8** %argv) {
entry:
%0 = load i8** @foo
%1 = call i32 @puts(i8* %0)
ret i32 0
}
So I'll leave the output_load() fix to a separate patch for now.
Cc: Xi Wang <xi.wang@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Christopher Li <sparse@chrisli.org>
Acked-by: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
| -rw-r--r-- | sparse-llvm.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/sparse-llvm.c b/sparse-llvm.c index 89c6a2e6..6b94205d 100644 --- a/sparse-llvm.c +++ b/sparse-llvm.c @@ -308,7 +308,6 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *ins struct expression *expr; assert(sym->bb_target == NULL); - assert(sym->ident == NULL); expr = sym->initializer; if (expr) { @@ -326,6 +325,13 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *ins result = LLVMConstGEP(data, indices, ARRAY_SIZE(indices)); break; } + case EXPR_SYMBOL: { + struct symbol *sym = expr->symbol; + + result = LLVMGetNamedGlobal(fn->module, show_ident(sym->ident)); + assert(result != NULL); + break; + } default: assert(0); } |
