106 lines
3 KiB
LLVM
106 lines
3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -S -passes="simplifycfg<sink-common-insts>" \
|
|
; RUN: -simplifycfg-require-and-preserve-domtree=1 | FileCheck %s
|
|
|
|
define void @callbr_duplicate_dest() {
|
|
; CHECK-LABEL: @callbr_duplicate_dest(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: callbr void asm sideeffect "", "!i"()
|
|
; CHECK-NEXT: to label [[BB:%.*]] [label %bb]
|
|
; CHECK: bb:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
callbr void asm sideeffect "", "!i"()
|
|
to label %bb [label %bb]
|
|
|
|
bb:
|
|
ret void
|
|
}
|
|
|
|
define void @callbr_can_fold_to_duplicate_dest1() {
|
|
; CHECK-LABEL: @callbr_can_fold_to_duplicate_dest1(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: callbr void asm sideeffect "", "!i"()
|
|
; CHECK-NEXT: to label [[COMMON_RET:%.*]] [label %common.ret]
|
|
; CHECK: common.ret:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
callbr void asm sideeffect "", "!i"()
|
|
to label %bb2 [label %bb1]
|
|
|
|
bb1:
|
|
ret void
|
|
|
|
bb2:
|
|
ret void
|
|
}
|
|
|
|
define void @callbr_can_fold_to_duplicate_dest2() {
|
|
; CHECK-LABEL: @callbr_can_fold_to_duplicate_dest2(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: callbr void asm sideeffect "", "!i,!i"()
|
|
; CHECK-NEXT: to label [[COMMON_RET:%.*]] [label [[COMMON_RET]], label %common.ret]
|
|
; CHECK: common.ret:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
callbr void asm sideeffect "", "!i,!i"()
|
|
to label %bb1 [label %bb2, label %bb3]
|
|
|
|
bb1:
|
|
ret void
|
|
|
|
bb2:
|
|
ret void
|
|
|
|
bb3:
|
|
ret void
|
|
}
|
|
|
|
; Validate that callbr landingpad intrinsics do not get merged (via the
|
|
; IntrNoMerge attribute).
|
|
define i32 @callbr_landingpad_nomerge() {
|
|
; CHECK-LABEL: @callbr_landingpad_nomerge(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[OUT:%.*]] = callbr i32 asm "# $0", "=r,!i"()
|
|
; CHECK-NEXT: to label [[DIRECT:%.*]] [label %entry.indirect_crit_edge]
|
|
; CHECK: entry.indirect_crit_edge:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[OUT]])
|
|
; CHECK-NEXT: br label [[COMMON_RET:%.*]]
|
|
; CHECK: direct:
|
|
; CHECK-NEXT: [[OUT2:%.*]] = callbr i32 asm "# $0", "=r,!i"()
|
|
; CHECK-NEXT: to label [[COMMON_RET]] [label %direct.indirect_crit_edge]
|
|
; CHECK: direct.indirect_crit_edge:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[OUT2]])
|
|
; CHECK-NEXT: br label [[COMMON_RET]]
|
|
; CHECK: common.ret:
|
|
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ 0, [[DIRECT]] ], [ [[TMP0]], [[ENTRY_INDIRECT_CRIT_EDGE:%.*]] ], [ [[TMP1]], [[DIRECT_INDIRECT_CRIT_EDGE:%.*]] ]
|
|
; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
|
|
;
|
|
entry:
|
|
%out = callbr i32 asm "# $0", "=r,!i"()
|
|
to label %direct [label %entry.indirect_crit_edge]
|
|
|
|
entry.indirect_crit_edge:
|
|
%0 = call i32 @llvm.callbr.landingpad.i32(i32 %out)
|
|
br label %indirect
|
|
|
|
direct:
|
|
%out2 = callbr i32 asm "# $0", "=r,!i"()
|
|
to label %direct2 [label %direct.indirect_crit_edge]
|
|
|
|
direct.indirect_crit_edge:
|
|
%1 = call i32 @llvm.callbr.landingpad.i32(i32 %out2)
|
|
br label %indirect
|
|
|
|
direct2:
|
|
ret i32 0
|
|
|
|
indirect:
|
|
%out3 = phi i32 [ %0, %entry.indirect_crit_edge ], [ %1, %direct.indirect_crit_edge ]
|
|
ret i32 %out3
|
|
}
|
|
|
|
declare i32 @llvm.callbr.landingpad.i32(i32)
|