[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 07:08:06 PDT 2017


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/a1a38c9b/attachment.html>


More information about the llvm-dev mailing list