I'm using the prebuilt LLVM 6.0, when I perform llvm pass -mem2reg
to generate SSA, the IR code remains as is without being changed. But when I use the prebuilt LLVM 3.8 to do the same thing, the llvm pass works. However, I need to use LLVM 6.0 because I'm using other tools that leverage this LLVM version.
To give a concrete example: Here is the c code
int main(int argc, char** argv){
int total_lines = 0;
int total_chars = 0;
int count_chars = 0;
int count_lines = 0;
if(argc == 1){
printf("Please specify count line and chars\n");
} else if (argc ==2){
if (!strcmp(argv[1], "-c")){
count_chars = 1;
}else if (!strcmp(argv[1], "-l")){
count_lines = 1;
}
}
char buffer[1024];
while (fgets(buffer, 1024,stdin)){
if (count_chars)
total_chars += sizeof(buffer);
if (count_lines)
total_lines += lineCount();
}
if (count_chars)
printf("Count chars is:: %d\n", total_chars);
if (count_lines)
printf("Count Lines is:: %d\n", total_lines);
return 0;
}
I run the LLVM pass to generate the SSA and then generate the human readable IR code using the following commands:
LLVM_6.0_bin/bin/clang -c -emit-llvm example.c
LLVM_6.0_bin/bin/llvm-dis example.bc -o h1.ll
//SSA LLVM pass
LLVM_6.0_bin/bin/opt -mem2reg example.bc -o example_SSA.bc
LLVM_6.0_bin/bin/llvm-dis example_SSA.bc -o h2.ll
diff h1 h2 //I receive the following
< ; ModuleID = 'example.bc'
---
> ; ModuleID = 'example_SSA.bc'
While when I do the same previous steps but using prebuilt LLVM 3.8, and diff h1 h2
I get many differences including the following
< ; <label>:50 ; preds = %29
< %51 = load i32, i32* %count_chars, align 4
< %52 = icmp ne i32 %51, 0
< br i1 %52, label %53, label %56
<
< ; <label>:53 ; preds = %50
< %54 = load i32, i32* %total_chars, align 4
< %55 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.4, i32 0, i32 0), i32 %54)
< br label %56
<
< ; <label>:56 ; preds = %53, %50
< %57 = load i32, i32* %count_lines, align 4
< %58 = icmp ne i32 %57, 0
< br i1 %58, label %59, label %62
<
< ; <label>:59 ; preds = %56
< %60 = load i32, i32* %total_lines, align 4
< %61 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.5, i32 0, i32 0), i32 %60)
< br label %62
---
> ; <label>:22 ; preds = %38, %21
> %total_lines.0 = phi i32 [ 0, %21 ], [ %total_lines.1, %38 ]
> %total_chars.0 = phi i32 [ 0, %21 ], [ %total_chars.1, %38 ]
> %23 = getelementptr inbounds [1024 x i8], [1024 x i8]* %buffer, i32 0, i32 0
> %24 = load %struct._IO_FILE*, %struct._IO_FILE** @stdin, align 8
> %25 = call i8* @fgets(i8* %23, i32 1024, %struct._IO_FILE* %24)
> %26 = icmp ne i8* %25, null
> br i1 %26, label %27, label %39