SplitBlockPredecessors currently asserts if one of the predecessor terminators is a callbr. This limitation was originally necessary, because just like with indirectbr, it was not possible to replace successors of a callbr. However, this is no longer the case since D67252. As the requirement nowadays is that callbr must reference all blockaddrs directly in the call arguments, and these get automatically updated when setSuccessor() is called, we no longer need this limitation. The only thing we need to do here is use replaceSuccessorWith() instead of replaceUsesOfWith(), because only the former does the necessary blockaddr updating magic. I believe there's other similar limitations that can be removed, e.g. related to critical edge splitting. Differential Revision: https://reviews.llvm.org/D129205
59 lines
2.0 KiB
LLVM
59 lines
2.0 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -S -jump-threading | FileCheck %s
|
|
|
|
; This test used to cause jump threading to try to split an edge of a callbr.
|
|
|
|
@a = global i32 0
|
|
|
|
define i32 @c() {
|
|
; CHECK-LABEL: @c(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
|
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.else:
|
|
; CHECK-NEXT: callbr void asm sideeffect "", "i"(i8* blockaddress(@c, [[IF_THEN2:%.*]]))
|
|
; CHECK-NEXT: to label [[NORMAL:%.*]] [label %if.then2]
|
|
; CHECK: normal:
|
|
; CHECK-NEXT: br label [[IF_THEN2]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @b()
|
|
; CHECK-NEXT: [[PHITMP:%.*]] = icmp ne i32 [[CALL]], 0
|
|
; CHECK-NEXT: br i1 [[PHITMP]], label [[IF_THEN2]], label [[IF_END4:%.*]]
|
|
; CHECK: if.then2:
|
|
; CHECK-NEXT: [[CALL3:%.*]] = call i32 @b()
|
|
; CHECK-NEXT: br label [[IF_END4]]
|
|
; CHECK: if.end4:
|
|
; CHECK-NEXT: ret i32 undef
|
|
;
|
|
entry:
|
|
%0 = load i32, i32* @a
|
|
%tobool = icmp eq i32 %0, 0
|
|
br i1 %tobool, label %if.else, label %if.then
|
|
|
|
if.then: ; preds = %entry
|
|
%call = call i32 @b() #2
|
|
%phitmp = icmp ne i32 %call, 0
|
|
br label %if.end
|
|
|
|
if.else: ; preds = %entry
|
|
callbr void asm sideeffect "", "i"(i8* blockaddress(@c, %if.end)) #2
|
|
to label %normal [label %if.end]
|
|
|
|
normal: ; preds = %if.else
|
|
br label %if.end
|
|
|
|
if.end: ; preds = %if.else, %normal, %if.then
|
|
%d.0 = phi i1 [ %phitmp, %if.then ], [ undef, %normal ], [ undef, %if.else ]
|
|
br i1 %d.0, label %if.then2, label %if.end4
|
|
|
|
if.then2: ; preds = %if.end
|
|
%call3 = call i32 @b()
|
|
br label %if.end4
|
|
|
|
if.end4: ; preds = %if.then2, %if.end
|
|
ret i32 undef
|
|
}
|
|
|
|
declare i32 @b()
|