Stanislav Pankevich via llvm-dev
2017-May-18 14:08 UTC
[llvm-dev] 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" ; <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>
Stanislav Pankevich via llvm-dev
2017-May-18 16:06 UTC
[llvm-dev] Replacing Branch Instructions in LLVM IR: what am I missing?
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>