llvmllc

Broken module error in llc when compiling manually edited IR file


I tried to insert line 35 and line 36 into the code, but an error happened when I tried to use llc to generate an .o file.

 35   %12 = ptrtoint i32* %1 to i64 
 36   call void @__Storemy(i32 10, i64 %12) 
 37   store i32 %10, i32* %1 
 38   br label %18 

error information:

Instruction does not dominate all uses! 
  %12 = ptrtoint i32* %1 to i64 
  call void @__StoreTo(i32 15, i64 %12) 
Broken module found, compilation aborted! 
0  libLLVM-3.4.so.1 0x00007f6d31fe25d2 llvm::sys::PrintStackTrace(_IO_FILE*) + 34 
1  libLLVM-3.4.so.1 0x00007f6d31fe23c4 
2  libc.so.6        0x00007f6d30a62d40 
3  libc.so.6        0x00007f6d30a62cc9 gsignal + 57 
4  libc.so.6        0x00007f6d30a660d8 abort + 328 
5  libLLVM-3.4.so.1 0x00007f6d319d2a41 
6  libLLVM-3.4.so.1 0x00007f6d319dbb03 
7  libLLVM-3.4.so.1 0x00007f6d319b2f77 llvm::FPPassManager::runOnFunction(llvm::Function&) + 471 
8  libLLVM-3.4.so.1 0x00007f6d319b2ffb llvm::FPPassManager::runOnModule(llvm::Module&) + 43 
9  libLLVM-3.4.so.1 0x00007f6d319b54b5 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 693 
10 llc              0x000000000040c0d4 
11 llc              0x000000000040b150 main + 368 
12 libc.so.6        0x00007f6d30a4dec5 __libc_start_main + 245 
13 llc              0x000000000040b1a9 
Stack dump: 
0.  Program arguments: llc -filetype=obj test.bc -o test.o 
1.  Running pass 'Function Pass Manager' on module 'test.bc'. 
2.  Running pass 'Module Verifier' on function '@dblfun' 

this is the whole IR for this function:

define i32 @dbl(i32* %a, i32 %x) #0 {
  call void @__myFuncCall(i32 1, i32 1)
  %1 = alloca i32, align 4
  %2 = alloca i32*, align 8
  %3 = alloca i32, align 4
  store i32* %a, i32** %2, align 8
  %4 = ptrtoint i32* %3 to i64
  call void @__myStore(i32 2, i64 %4)
  store i32 %x, i32* %3, align 4
  %5 = load i32* %3, align 4
  %6 = ptrtoint i32* %3 to i64
  call void @__myLoad(i32 3, i64 %6, i32 %5)
  call void @__myLoad(i32 4, i64 0, i32 5)
  %7 = icmp sgt i32 %5, 5
  call void @__myApply(i32 5, i32 14, i1 %7)
  br i1 %7, label %_then, label %_else

; <label>:8                                       ; preds = %_then
  %9 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0))
  call void @__Clear(i32 8)
  %10 = load i32* %3, align 4
  %11 = ptrtoint i32* %3 to i64
  call void @__myLoad(i32 9, i64 %11, i32 %10)
  %12 = ptrtoint i32* %1 to i64
  call void @__StoreTo(i32 10, i64 %12)
  store i32 %10, i32* %1
  br label %18

_else:                                            ; preds = %0
  call void @__test(i32 7, i32 2, i32 0)
  br label %13

_then:                                            ; preds = %0
  call void @__test(i32 6, i32 1, i32 1)
  br label %8

; <label>:13                                      ; preds = %_else
  %14 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([3 x i8]* @.str1, i32 0, i32 0))
  call void @__Clear(i32 11)
  %15 = load i32* %3, align 4
  %16 = ptrtoint i32* %3 to i64
  call void @__myLoad(i32 12, i64 0, i32 2)
  call void @__myLoad(i32 13, i64 %16, i32 %15)
  %17 = mul nsw i32 2, %15
  call void @__myApply(i32 14, i32 2, i32 %17)
  call void @__myStore(i32 15, i64 %12)
  store i32 %17, i32* %1
  br label %18

; <label>:18                                      ; preds = %13, %8
  %19 = load i32* %1
  %20 = ptrtoint i32* %1 to i64
  call void @__myLoad(i32 16, i64 %20, i32 %19)
  call void @__myReturn(i32 17)
  ret i32 %19
}

I can't find any problems with this code, anyone can give me some suggestions?


Solution

  • The control flow graph of your function looks like this:

          entry
          /   \
         /     \
      _then   _else
        |       | 
        8       13
         \     /
          \   /
           18
    

    %12 is defined in block 8. It's used once immediately afterwards which is fine, and then there is another use in block 13, which you can see from the diagram is not dominated by 8 (actually it's not even reachable from 8).

    In this case, you should be able to move the ptrtoint instruction up to the entry block -- that way it'll be accessible in every other block.