Emit a jump instruction to a place inside basicblock

Hi all,

I’m a beginner in LLVM. Currently, I want to implement a pass that generates a jump table. The entry in that table is a jump to some place (may be an instruction) in a basic block.

I’m reading the JumpTable code in llvm 3.5, there is a table which contains jump entries to functions. In AsmPrinter::doFinalization function from file lib/CodeGen/AsmPrinter/AsmPrinter.cpp, it gets a MCSymbolRefExpr from the function symbol.

While my question is, is there a way to insert jump to place inside a basic block?



ISTM you can split a basic bloc in two using ``llvm::SplitBlock'' then
jump to the begining of the second part?


Best regards,

Thanks you all! I'm looking at splitBasicBlock and trying to use that.
BTW, is there a way at lower level of LLVM that can implement this
functionality? E.g. MCBasicBlock or MCInst?


You are unlikely to want to do this at the MC level, maybe the MI level. What are you trying to accomplish?


Thanks for the answer. I want to construct a table which can jump to the
address after a call instruction. And replace the call/ret instructions
with that indirection table. So to protect return address on stack.


An MI level pass will likely work, but you might end up having issues replacing instructions. It’ll be some effort though.


Thanks Eric for your help. I'm reading the function
&MF)* in lib/Target/X86/X86CodeEmitter.cpp. And I hope this is the place I
have to modify for my purpose.


I might make an MI pass and make sure it happens last in the pipeline for this, but I haven’t given it a lot of thought.


Hi, I tried splitBasicBlock after the specific place in IR, and saved the
newly created BasicBlock*. This works well to create a basic block with a
LABEL to jump back. Then I modified the doFinalization method in AsmPrinter
to add a jump instruction to the LABEL. The result is it can create the
jump to the LABEL, but the LABEL just disappeared. It is like:

*The original IR before I use splitBasicBlock:*
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([8 x i8]*
@.str, i32 0, i32 0))
  ret i32 0

*The transformed IR code by using splitBasicBlock:*
  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([8 x
i8]* @.str, i32 0, i32 0))
  br label %RET_TABLE_0

RET_TABLE_0: ; preds = %entry
  ret i32 0

*The final assembly when I modified AsmPrinter:doFinalization to print the
jump instruction back to LABEL:*
    calll printf
    movl %eax, -4(%ebp) # 4-byte Spill
# BB#1: # %.RET_TABLE_0
    movl $0, %eax
... ...
    .align 8, 0x90
    jmp .RET_TABLE_0

So the LLVM will optimize this branch in the pass? Can I disable this
optimization or is there other way to reserve the LABEL?