blob: ec068358099a919f22022860848dede9e0f97f7e [file]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -passes='simplifycfg<sink-common-insts>,verify' -S %s | FileCheck %s
declare void @clobber1()
declare void @clobber2()
declare void @f()
; Both bundle operands are variable, so the calls can be sunk and the bundle
; operand merged by a PHI.
define void @sink_variable_bundle_operands(i1 %c, i32 %a, i32 %b) {
; CHECK-LABEL: define void @sink_variable_bundle_operands(
; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
; CHECK-NEXT: [[BB:.*:]]
; CHECK-NEXT: br i1 [[C]], label %[[THEN:.*]], label %[[ELSE:.*]]
; CHECK: [[THEN]]:
; CHECK-NEXT: call void @clobber1()
; CHECK-NEXT: br label %[[EXIT:.*]]
; CHECK: [[ELSE]]:
; CHECK-NEXT: call void @clobber2()
; CHECK-NEXT: br label %[[EXIT]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: [[B_SINK:%.*]] = phi i32 [ [[B]], %[[ELSE]] ], [ [[A]], %[[THEN]] ]
; CHECK-NEXT: call void @f() [ "deopt"(i32 [[B_SINK]]) ]
; CHECK-NEXT: ret void
;
bb:
br i1 %c, label %then, label %else
then:
call void @clobber1()
call void @f() [ "deopt"(i32 %a) ]
br label %exit
else:
call void @clobber2()
call void @f() [ "deopt"(i32 %b) ]
br label %exit
exit:
ret void
}
; The bundle operand of the call in %then is constant, so the calls must not be
; sunk.
define void @no_sink_constant_bundle_operand_in_then(i1 %c, i32 %b) {
; CHECK-LABEL: define void @no_sink_constant_bundle_operand_in_then(
; CHECK-SAME: i1 [[C:%.*]], i32 [[B:%.*]]) {
; CHECK-NEXT: [[BB:.*:]]
; CHECK-NEXT: br i1 [[C]], label %[[THEN:.*]], label %[[ELSE:.*]]
; CHECK: [[THEN]]:
; CHECK-NEXT: call void @clobber1()
; CHECK-NEXT: call void @f() [ "deopt"(i32 7) ]
; CHECK-NEXT: br label %[[EXIT:.*]]
; CHECK: [[ELSE]]:
; CHECK-NEXT: call void @clobber2()
; CHECK-NEXT: call void @f() [ "deopt"(i32 [[B]]) ]
; CHECK-NEXT: br label %[[EXIT]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
bb:
br i1 %c, label %then, label %else
then:
call void @clobber1()
call void @f() [ "deopt"(i32 7) ]
br label %exit
else:
call void @clobber2()
call void @f() [ "deopt"(i32 %b) ]
br label %exit
exit:
ret void
}
; Same as above, with the constant bundle operand in the other predecessor.
define void @no_sink_constant_bundle_operand_in_else(i1 %c, i32 %b) {
; CHECK-LABEL: define void @no_sink_constant_bundle_operand_in_else(
; CHECK-SAME: i1 [[C:%.*]], i32 [[B:%.*]]) {
; CHECK-NEXT: [[BB:.*:]]
; CHECK-NEXT: br i1 [[C]], label %[[THEN:.*]], label %[[ELSE:.*]]
; CHECK: [[THEN]]:
; CHECK-NEXT: call void @clobber1()
; CHECK-NEXT: call void @f() [ "deopt"(i32 [[B]]) ]
; CHECK-NEXT: br label %[[EXIT:.*]]
; CHECK: [[ELSE]]:
; CHECK-NEXT: call void @clobber2()
; CHECK-NEXT: call void @f() [ "deopt"(i32 7) ]
; CHECK-NEXT: br label %[[EXIT]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
bb:
br i1 %c, label %then, label %else
then:
call void @clobber1()
call void @f() [ "deopt"(i32 %b) ]
br label %exit
else:
call void @clobber2()
call void @f() [ "deopt"(i32 7) ]
br label %exit
exit:
ret void
}