[llvm-dev] Replacing Branch Instructions in LLVM IR: what am I missing?

Stanislav Pankevich via llvm-dev llvm-dev at lists.llvm.org
Thu May 18 09:06:41 PDT 2017


I apologize for this message. It was based on a wrong precondition.

I was doing a replacement on original module while at the same time I ran
JIT on a clone of that original module. Now everything is working perfectly.

On Thu, May 18, 2017 at 4:08 PM, Stanislav Pankevich <s.pankevich at gmail.com>
wrote:

> Hello,
>
> I understand that my question is very specific, but I do hope to find
> someone who could have an insight into this matter.
>
> I am trying to replace a branch instruction that represents Cond1 && Cond2
> with a branch instruction that would represent a Cond1 || Cond2.
>
> int testee_and_operator(int a, int b, int c) {
>   if (a < b && b < c) {
>     printf("left branch\n");
>     return a;
>   } else {
>     printf("right branch\n");
>     return b;
>   }
> }
>
> I use the following code to test the flow inside the function above:
>
> int test_and_operator() {
>   int result = (testee_and_operator(1, 3, 2) == 3);
>   return result;
> }
>
> Before replacement result is 1, the code goes through the right branch.
> After replacement I expect the code to return 0 and go through the left
> branch.
>
> IR-wise, this code appears to be the following:
>
> define i32 @testee_and_operator(i32, i32, i32) #0 {
>   %4 = alloca i32, align 4
>   %5 = alloca i32, align 4
>   %6 = alloca i32, align 4
>   %7 = alloca i32, align 4
>   store i32 %0, i32* %5, align 4
>   store i32 %1, i32* %6, align 4
>   store i32 %2, i32* %7, align 4
>   %8 = load i32, i32* %5, align 4
>   %9 = load i32, i32* %6, align 4
>   %10 = icmp slt i32 %8, %9
>   br i1 %10, label %11, label %17 <-- replacing with another BranchInst
> pointing to "br i1 %10, label %15, label %11"
>
> ; <label>:11:                                     ; preds = %3
>   %12 = load i32, i32* %6, align 4
>   %13 = load i32, i32* %7, align 4
>   %14 = icmp slt i32 %12, %13
>   br i1 %14, label %15, label %17
>
> ; <label>:15:                                     ; preds = %11
>   %16 = load i32, i32* %5, align 4
>   store i32 %16, i32* %4, align 4
>   br label %19
>
> ; <label>:17:                                     ; preds = %11, %3
>   %18 = load i32, i32* %6, align 4
>   store i32 %18, i32* %4, align 4
>   br label %19
>
> ; <label>:19:                                     ; preds = %17, %15
>   %20 = load i32, i32* %4, align 4
>   ret i32 %20
>
> I am trying to switch the branches of a BranchInst using the following
> code:
>
>   BranchInst *replacement = BranchInst::Create(leftBranchSubbranchInst_
> leftBranchBB,
>                                                leftBranchBB,
>                                                cmpInst);
>
>   replacement->insertAfter(branchInst);
>   branchInst->replaceAllUsesWith(replacement);
>   branchInst->eraseFromParent();
>
>   replacement->getFunction()->dump();
>
> And I am indeed seeing a dump that does correspond to LLVM bitcode created
> manually from a code that has if (a < b || b < c).
>
> However, when I run this code using JIT, the code still goes through a
> right branch as it used to.
>
> It is important to note that if I put the dump of the modified code to an
> .ll file I do see my code going through the left branch which makes me
> think that there is some sort of caching: dependency which exists between
> original `br` instruction and its basic blocks which still hangs in memory
> this is why I do not see my replacement to take any effect.
>
> What am I missing in my code to make this transformation correct? My dump
> is valid but JIT seems to execute old, unmodified code.
>
> Thanks,
>
> Stanislav
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170518/278dae2f/attachment.html>


More information about the llvm-dev mailing list