blob: 3155d399d03e5aefb387a426ce9b52d0d64a1bc8 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s
declare void @f0()
declare void @f1()
declare void @f2()
;; Folding a chain of unpredictable equality comparisons into a switch keeps the
;; switch unpredictable.
define void @fold_into_pred_unpredictable(i32 %x) {
; CHECK-LABEL: define void @fold_into_pred_unpredictable(
; CHECK-SAME: i32 [[X:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: switch i32 [[X]], label %[[C:.*]] [
; CHECK-NEXT: i32 0, label %[[A:.*]]
; CHECK-NEXT: i32 1, label %[[B:.*]]
; CHECK-NEXT: ], !unpredictable [[META0:![0-9]+]]
; CHECK: [[A]]:
; CHECK-NEXT: call void @f0()
; CHECK-NEXT: br label %[[EXIT:.*]]
; CHECK: [[B]]:
; CHECK-NEXT: call void @f1()
; CHECK-NEXT: br label %[[EXIT]]
; CHECK: [[C]]:
; CHECK-NEXT: call void @f2()
; CHECK-NEXT: br label %[[EXIT]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
%c0 = icmp eq i32 %x, 0
br i1 %c0, label %a, label %next, !unpredictable !0
next:
%c1 = icmp eq i32 %x, 1
br i1 %c1, label %b, label %c, !unpredictable !0
a:
call void @f0()
br label %exit
b:
call void @f1()
br label %exit
c:
call void @f2()
br label %exit
exit:
ret void
}
;; If only one of the folded comparisons is unpredictable, nothing is known
;; about the resulting switch.
define void @fold_into_pred_partly_unpredictable(i32 %x) {
; CHECK-LABEL: define void @fold_into_pred_partly_unpredictable(
; CHECK-SAME: i32 [[X:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: switch i32 [[X]], label %[[C:.*]] [
; CHECK-NEXT: i32 0, label %[[A:.*]]
; CHECK-NEXT: i32 1, label %[[B:.*]]
; CHECK-NEXT: ]{{$}}
; CHECK: [[A]]:
; CHECK-NEXT: call void @f0()
; CHECK-NEXT: br label %[[EXIT:.*]]
; CHECK: [[B]]:
; CHECK-NEXT: call void @f1()
; CHECK-NEXT: br label %[[EXIT]]
; CHECK: [[C]]:
; CHECK-NEXT: call void @f2()
; CHECK-NEXT: br label %[[EXIT]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
%c0 = icmp eq i32 %x, 0
br i1 %c0, label %a, label %next, !unpredictable !0
next:
%c1 = icmp eq i32 %x, 1
br i1 %c1, label %b, label %c
a:
call void @f0()
br label %exit
b:
call void @f1()
br label %exit
c:
call void @f2()
br label %exit
exit:
ret void
}
;; An unpredictable branch on a chain of equality comparisons becomes an
;; unpredictable switch.
define void @icmp_chain_to_switch(i32 %x) {
; CHECK-LABEL: define void @icmp_chain_to_switch(
; CHECK-SAME: i32 [[X:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: switch i32 [[X]], label %[[B:.*]] [
; CHECK-NEXT: i32 9, label %[[A:.*]]
; CHECK-NEXT: i32 5, label %[[A]]
; CHECK-NEXT: i32 1, label %[[A]]
; CHECK-NEXT: ], !unpredictable [[META0]]
; CHECK: [[A]]:
; CHECK-NEXT: call void @f0()
; CHECK-NEXT: br label %[[EXIT:.*]]
; CHECK: [[B]]:
; CHECK-NEXT: call void @f1()
; CHECK-NEXT: br label %[[EXIT]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
%c0 = icmp eq i32 %x, 1
%c1 = icmp eq i32 %x, 5
%c2 = icmp eq i32 %x, 9
%o0 = or i1 %c0, %c1
%o1 = or i1 %o0, %c2
br i1 %o1, label %a, label %b, !unpredictable !0
a:
call void @f0()
br label %exit
b:
call void @f1()
br label %exit
exit:
ret void
}
;; The same chain over a contiguous range becomes an unpredictable range check.
define void @icmp_chain_to_range_check(i32 %x) {
; CHECK-LABEL: define void @icmp_chain_to_range_check(
; CHECK-SAME: i32 [[X:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[X]], -1
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], 3
; CHECK-NEXT: br i1 [[TMP1]], label %[[A:.*]], label %[[B:.*]], !unpredictable [[META0]]
; CHECK: [[A]]:
; CHECK-NEXT: call void @f0()
; CHECK-NEXT: br label %[[EXIT:.*]]
; CHECK: [[B]]:
; CHECK-NEXT: call void @f1()
; CHECK-NEXT: br label %[[EXIT]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
%c0 = icmp eq i32 %x, 1
%c1 = icmp eq i32 %x, 2
%c2 = icmp eq i32 %x, 3
%o0 = or i1 %c0, %c1
%o1 = or i1 %o0, %c2
br i1 %o1, label %a, label %b, !unpredictable !0
a:
call void @f0()
br label %exit
b:
call void @f1()
br label %exit
exit:
ret void
}
!0 = !{}
;.
; CHECK: [[META0]] = !{}
;.