[llvm-diff] Add support for diffing the callbr instruction

The only wrinkle is that we can't process the "blockaddress" arguments
of the callbr until the blocks have been equated. So we force them to be
"unified" before checking.

This was left out when the callbr instruction was added.

Differential Revision: https://reviews.llvm.org/D104606
This commit is contained in:
Bill Wendling 2021-06-20 14:45:12 -07:00
parent ae1093921f
commit ab6002871d
2 changed files with 60 additions and 0 deletions

View File

@ -0,0 +1,39 @@
; RUN: not llvm-diff %s %s 2>&1 | FileCheck %s
define void @foo() {
entry:
callbr void asm sideeffect "", "X,X,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@foo, %return), i8* blockaddress(@foo, %t_no))
to label %asm.fallthrough [label %return, label %t_no]
asm.fallthrough:
br label %return
t_no:
br label %return
return:
ret void
}
; CHECK: in function bar:
; CHECK-NOT: in function foo:
; CHECK-NEXT: in block %entry:
; CHECK-NEXT: > callbr void asm sideeffect "", "X,X,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@foo, %t_no), i8* blockaddress(@foo, %return))
; CHECK-NEXT: to label %asm.fallthrough [label %return, label %t_no]
; CHECK-NEXT: < callbr void asm sideeffect "", "X,X,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@foo, %t_no), i8* blockaddress(@foo, %return))
; CHECK-NEXT: to label %asm.fallthrough [label %return, label %t_no]
define void @bar() {
entry:
callbr void asm sideeffect "", "X,X,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@foo, %t_no), i8* blockaddress(@foo, %return))
to label %asm.fallthrough [label %return, label %t_no]
asm.fallthrough:
br label %return
t_no:
br label %return
return:
ret void
}

View File

@ -287,6 +287,27 @@ class FunctionDifferenceEngine {
}
return false;
} else if (isa<CallBrInst>(L)) {
const CallBrInst &LI = cast<CallBrInst>(*L);
const CallBrInst &RI = cast<CallBrInst>(*R);
if (LI.getNumIndirectDests() != RI.getNumIndirectDests()) {
if (Complain)
Engine.log("callbr # of indirect destinations differ");
return true;
}
// Perform the "try unify" step so that we can equate the indirect
// destinations before checking the call site.
for (unsigned I = 0; I < LI.getNumIndirectDests(); I++)
tryUnify(LI.getIndirectDest(I), RI.getIndirectDest(I));
if (diffCallSites(LI, RI, Complain))
return true;
if (TryUnify)
tryUnify(LI.getDefaultDest(), RI.getDefaultDest());
return false;
} else if (isa<BranchInst>(L)) {
const BranchInst *LI = cast<BranchInst>(L);
const BranchInst *RI = cast<BranchInst>(R);