[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