Peng Yu via llvm-dev
2019-Jan-25 20:57 UTC
[llvm-dev] Can the entry of a function be messed up in a slightly edited IR .ll file?
Hi, I manually added the following code (labeled with ADDED, lines without ADDED are to show the context) to a .ll file compiled from a .bc file. (This .bc file can run correctly.) No other lines are changed in the .ll file. declare void @__trace_init() ; ADDED declare void @__trace_block_enter(i8*, i8*) ; ADDED @mystr.1 = private unnamed_addr constant [5 x i8] c"main\00", align 1 ; ADDED @mystr.2 = private unnamed_addr constant [3 x i8] c"bb\00", align ; ADDED ; Function Attrs: noinline nounwind optnone uwtable define dso_local i32 @main(i32 %arg, i8** %arg1, i8** %arg2) #0 !dbg !10092 { bb: call void @__trace_init() ; ADDED call void @__trace_block_enter(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @mystr.1, i32 0, i32 0), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @mystr.2, i32 0, i32 0)) ; ADDED %tmp = alloca i32, align 4 __trace_init() and __trace_block_enter() are defined in trace.c as shown below. Then I compile the .ll file and trace.c to two new .bc files, and llvm-link them to generate a single final .bc file. Then I run the final .bc file using lli with the environment variable TRACE_OUTFILE set. Depending on the command line options to the final .bc file, sometimes, the TRACE_OUTFILE contains more lines than the number of times "__trace_block_enter" printed to the screen. This is really strange to me. I can only think of one possibility, __trace_block_enter() may be entered multiple times not at the entry points. Could this ever happen? Are there any other hypotheses why this could happen and how to test them? Thanks. $ cat trace.c /* vim: set noexpandtab tabstop=2: */ #include <stdio.h> #include <stdlib.h> static FILE *fp; void __trace_init() { puts("__trace_init"); const char *s=getenv("TRACE_OUTFILE"); if(s) { fp = fopen(s, "w"); if(!fp) { perror("Failed to open TRACE_OUTFILE"); exit(1); } } else { fputs( "\x1b[31;1mThe environment variable TRACE_OUTFILE must be set.\x1b[m\n" , stderr ); exit(1); } } void __trace_block_enter(char *caller, char *basic_block) { puts("__trace_block_enter"); fprintf(fp, "%s\t%s\n", caller, basic_block); } void __trace_func_enter(char *caller, char *basic_block, char *callee) { fprintf(fp, "%s\t%s\t%s\n", caller, basic_block, callee); } -- Regards, Peng