Steps to addDestination

Hi,

I need to addDestination to some basic blocks

I used the following code

Value* Address;
IndirectBrInst *IBI = IndirectBrInst::Create(Address, Result.size(),i->getTerminator() );

IBI->addDestination(i);

The following error was issued

void llvm::IndirectBrInst::init(llvm::Value *, unsigned int): Assertion `Address && Address->getType()->isPointerTy() && “Address of indirectbr must be a pointer”’ failed.

I need to know the steps to add new indirect branch to a basic block with this method

Hi Rasha,

I need to addDestination to some basic blocks

Just to make sure there's no confusion here: you really are trying to
create code like:

define i32 @foo(i1 %tst) {
  %Address = select i1 %tst, i8* blockaddress(@foo, %true), i8*
blockaddress(@foo, %false)
  indirectbr i8* %Address, [label %true, label %false] ; This is what
you're creating
true:
  ret i32 42
false:
  ret i32 0
}

and not:

define i32 @bar(i1 %tst) {
  br i1 %tst, label %true, label %false ; You're not trying to create this
true:
  ret i32 42
false:
  ret i32 0
}

If that's incorrect, you're going about it entirely the wrong way. We
can help with either, but it's best not to go too far on a
misunderstanding.

Value* Address;
  IndirectBrInst *IBI = IndirectBrInst::Create(Address, Result.size(),i->getTerminator() );

IBI->addDestination(i);

The problem seems to be that "Address" is uninitialised but it needs
to be set to some valid pointer value before creating your IndirectBr.
To replicate my first example it would be set to the "select"
instruction, for example; whatever produces your testination
blockaddress.

Cheers.

Tim.

1- I need the first example.

2- I set the Address uninitialized according to the documentation
" Setting the name on the Value automatically updates the module’s symbol table"

from Value.h source code

3- I’m not sure about “select” instruction, you mean that the address is the new destination (basic block)that will be added

Thanks

Hi Rasha,

1- I need the first example.

Oh good.

2- I set the Address uninitialized according to the documentation
" Setting the name on the Value automatically updates the module's symbol
table" from Value.h source code

That's referring to a string name, and is only really important for
clarity and debugging the IR being produced. It means you could start
out with something like

    [...]
    %1 = add i32 %lhs, %rhs
    ret i32 %1
    [...]

(where the %1 is just an automatically incrementing label provided by
LLVM) then call MyAddInst.setName("theSum") and LLVM would
automatically convert this to:

    %theSum = add i32 %lhs, %rhs
    ret i32 %theSum

You still have to have an initialised, valid Value pointer to be able
to do this.

3- I'm not sure about "select" instruction, you mean that the address is the
new destination (basic block)that will be added

The address will be, directly or indirectly, the result of a
"BlockAddress::get(...)" call. Perhaps directly (though that would be
rather useless since then you'd just as well create a direct branch to
that block, perhaps via a "select" as in my code, or via load/store.
Perhaps even passed into the function as a parameter in a rather
bizarre set of circumstances.

Do you know about the Cpp backend, by the way? It can be very useful
for working out just what you have to write to emit certain LLVM IR.

What you do is write your own .ll file by hand, having the features
you want, then run

$ llc -march=cpp example_file.ll -o -

LLVM will produce some C++ code that generates the module you wrote.
It's not necessarily in the best of styles, but shows you roughly
which calls you should be making.

Cheers.

Tim.

Hi
1-
for(rit=Result.begin();rit!=Result.end();++rit)
{
Value* Address= BlockAddress::get (*rit);
IndirectBrInst *IBI = IndirectBrInst::Create(Address, Result.size(),i->getTerminator() );
IBI->addDestination((*rit));
}

I tried this code , but the needed destination wasn’t added.

2- About LLVM backend
$ llc -march=cpp example_file.ll -o

I think it will be so helpful for my work

Thanks

Hi Rasha,

for(rit=Result.begin();rit!=Result.end();++rit)
  {
          Value* Address= BlockAddress::get (*rit);

           IndirectBrInst *IBI = IndirectBrInst::Create(Address, Result.size(),i->getTerminator() );
           IBI->addDestination((*rit));
  }

This would be creating a block looking something like:
    [ Do stuff ]
    indirectbr i8* blockaddress(@foo, %result1), [label %result1]
    indirectbr i8* blockaddress(@foo, %result2), [label %result2]
    [...]
    indirectbr i8* blockaddress(@foo, %resultN), [label %resultN]

which isn't valid LLVM IR. Each basic block has to have a single
branch at the end so you need to create the IndirectBrInst outside the
loop.

How do you decide which of the results you want to jump to at
run-time? I think that's the key question you have to answer. You want
to emit LLVM IR to make this decision and produce a single Value
representing it, then use the value just once to create a single
indirectbr.

Your code might look like:
    Value *Address = emitCodeToChooseResult(Results, Loc);

    IndirectBrInst *IBI = IndirectBrInst::Create(Address, Result.size(), i);
    for (rit = Result.begin(); rit != Result.end(); ++rit)
      IBI->addDestination(*rit);

Cheers.

Tim.

Your code might look like:
    Value *Address = emitCodeToChooseResult(Results, InsertLoc);

And a particularly silly implementation of emitCodeToChooseResults
might decide to call rand() at runtime and jump to whichever block it
decided. In that case you'd be trying to write code to produce IR
resembling:

@.blocks = private unnamed_addr constant [2 x i8*] [i8*
blockaddress(@foo, %block1), i8* blockaddress(@foo, %block2)]
declare i32 @rand()

; This whole block would actually be inside
define i32 @foo() {
   %RandomNumber = call i32 @rand()
   %ResultIndex = urem i32 %RandomNumber, 2
   %ResultBlock = getelementptr [2 x i8*]* @.blocks, i32 0, i32 %ResultIndex
   %block = load i8** %ResultBlock

   ; Code above produced by emitCodeToChooseResults, code below
produced elsewhere
   indirectbr i8* %block, [label %block1, label %block2]
block1:
   ret i32 0
block2:
   ret i32 42
}

For this, emitCodeToChooseResult would go through the stages:
1. ConstantArray::get to create the array of each blockaddress in Results.
2. Create a new GlobalVariable to store these addresses
3. Get a reference to rand() using Module->getOrInsertFunction
4. Emit calls to this RandFunction and a urem to calculate the block index.
5. Create a getelementptr instruction referring to the GlobalVariable
and the random result
6. Create a load from the address calculated.
7. Done, return this loaded value (as in "return LoadedPtr" rather
than "ReturnInst::Create(LoadedPtr, ...)").

There are obviously many other ways you could make the decision.

Cheers.

Tim.