[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