2
votes

Found the problem, it turned out I forget set the initial value of vari in set_array.

which is

  store i32 0, i32* %vari

in the code

However it is strange that opt optimize it out.

// ----- original ---------

Below is the code generated in LLVM IR. Notice I called malloc in main function.

When I use opt to optimize the code, malloc is gone and the optimized generated code doesn't match what I expect. (Even if I use printf to print some values in the allocated array to prevent it gets optimized out).

Same thing happens using llc.

How should I create a "complete" program entirely in LLVM IR (be able to call malloc), and compile it to an executable binary.

; ModuleID = 'my_module'
source_filename = "my_module"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"

define i32 @main(i32 %0, i8** %1) {
main_basicblock:
  %malloc_ret = call i8* @malloc(i64 30)
  %temp = bitcast i8* %malloc_ret to i32*
  call void @set_array(i32* %temp, i32 30, i32 2)
  %temp1 = getelementptr i32, i32* %temp, i32 2
  %f2 = load i32, i32* %temp1
  %temp2 = getelementptr i32, i32* %temp, i32 10
  %f23 = load i32, i32* %temp2
  ret i32 0
}

define void @set_array(i32* %0, i32 %1, i32 %2) {
set_array_basicblock:
  %vari = alloca i32
  **store i32 0, i32* %vari**
  br label %loop_basicblock

loop_basicblock:                                          ; preds = %set_array_basicblock, %set_array_basicblock2
  %temp = load i32, i32* %vari
  %temp1 = icmp slt i32 %temp, %1
  br i1 %temp1, label %set_array_basicblock2, label %set_array_basicblock4

set_array_basicblock2:                                    ; preds = %loop_basicblock
  %i_value = load i32, i32* %vari
  %ptr = getelementptr i32, i32* %0, i32 %i_value
  store i32 %1, i32* %ptr
  %temp3 = add i32 %i_value, 1
  store i32 %temp3, i32* %vari
  br label %loop_basicblock

set_array_basicblock4:                                    ; preds = %loop_basicblock
  ret void
}

declare i8* @malloc(i64)
1

1 Answers

1
votes

The allocated memory is not used for anything observable so the optimizer can remove it completely.

You can avoid that disabling optimizations or doing something meaningful with it. For instance, you can print it, call an external function, perform a volatile store...

store volatile i32 0, i32* %temp

Even if I use printf to print some values in the allocated array to prevent it get optimized out

This may happen if the optimizer can compute everything during compilation time. You can add unknown values from some input source, increase the complexity of the code or use one of the other solutions.