Replacing Branch Instructions in LLVM IR: what am I missing?

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”

; :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

; :15: ; preds = %11
%16 = load i32, i32* %5, align 4
store i32 %16, i32* %4, align 4
br label %19

; :17: ; preds = %11, %3
%18 = load i32, i32* %6, align 4
store i32 %18, i32* %4, align 4
br label %19

; :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

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.