aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorPekka Enberg <penberg@kernel.org>2012-06-08 15:47:33 +0300
committerPekka Enberg <penberg@kernel.org>2012-06-09 14:04:28 +0300
commitccf42dc22ef4354ef6db1673a5e2b2bc0a6be273 (patch)
tree4a96a06def51fed696d7e7152a86a720c9d165e6
parent9084e55561e9aa11d291c1a9acaf1a7584651b73 (diff)
downloadsparse-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.c8
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);
}