blob: 068ff72cde1c3f4f92a197cfd9a49d81543863a3 [file] [log] [blame] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
; RUN: opt -S -passes=instcombine -instcombine-infinite-loop-threshold=2 < %s | FileCheck %s --check-prefixes=CHECK,DEFAULT_ITER
; RUN: opt -S -passes='instcombine<max-iterations=1>' < %s | FileCheck %s --check-prefixes=CHECK,MAX1
declare void @dummy()
define i32 @br_true(i1 %x) {
; CHECK-LABEL: define i32 @br_true
; CHECK-SAME: (i1 [[X:%.*]]) {
; CHECK-NEXT: br i1 true, label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
; CHECK-NEXT: call void @dummy()
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: ret i32 1
;
%c = or i1 %x, true
br i1 %c, label %if, label %else
if:
call void @dummy()
br label %join
else:
call void @dummy()
br label %join
join:
%phi = phi i32 [ 1, %if ], [ 2, %else ]
ret i32 %phi
}
define i32 @br_false(i1 %x) {
; CHECK-LABEL: define i32 @br_false
; CHECK-SAME: (i1 [[X:%.*]]) {
; CHECK-NEXT: br i1 false, label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: call void @dummy()
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: ret i32 2
;
%c = and i1 %x, false
br i1 %c, label %if, label %else
if:
call void @dummy()
br label %join
else:
call void @dummy()
br label %join
join:
%phi = phi i32 [ 1, %if ], [ 2, %else ]
ret i32 %phi
}
define i32 @br_undef(i1 %x) {
; CHECK-LABEL: define i32 @br_undef
; CHECK-SAME: (i1 [[X:%.*]]) {
; CHECK-NEXT: br i1 undef, label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: ret i32 undef
;
%c = xor i1 %x, undef
br i1 %c, label %if, label %else
if:
call void @dummy()
br label %join
else:
call void @dummy()
br label %join
join:
%phi = phi i32 [ 1, %if ], [ 2, %else ]
ret i32 %phi
}
define i32 @br_true_phi_with_repeated_preds(i1 %x) {
; CHECK-LABEL: define i32 @br_true_phi_with_repeated_preds
; CHECK-SAME: (i1 [[X:%.*]]) {
; CHECK-NEXT: br i1 true, label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
; CHECK-NEXT: call void @dummy()
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: br i1 false, label [[JOIN]], label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: ret i32 1
;
%c = or i1 %x, true
br i1 %c, label %if, label %else
if:
call void @dummy()
br label %join
else:
br i1 false, label %join, label %join
join:
%phi = phi i32 [ 1, %if ], [ 2, %else ], [ 2, %else ]
ret i32 %phi
}
define void @switch_case(i32 %x) {
; CHECK-LABEL: define void @switch_case
; CHECK-SAME: (i32 [[X:%.*]]) {
; CHECK-NEXT: switch i32 0, label [[DEFAULT:%.*]] [
; CHECK-NEXT: i32 0, label [[CASE0:%.*]]
; CHECK-NEXT: ]
; CHECK: case0:
; CHECK-NEXT: call void @dummy()
; CHECK-NEXT: ret void
; CHECK: default:
; CHECK-NEXT: ret void
;
%v = and i32 %x, 0
switch i32 %v, label %default [
i32 0, label %case0
]
case0:
call void @dummy()
ret void
default:
call void @dummy()
ret void
}
define void @switch_default(i32 %x) {
; CHECK-LABEL: define void @switch_default
; CHECK-SAME: (i32 [[X:%.*]]) {
; CHECK-NEXT: switch i32 -1, label [[DEFAULT:%.*]] [
; CHECK-NEXT: i32 0, label [[CASE0:%.*]]
; CHECK-NEXT: ]
; CHECK: case0:
; CHECK-NEXT: ret void
; CHECK: default:
; CHECK-NEXT: call void @dummy()
; CHECK-NEXT: ret void
;
%v = or i32 %x, -1
switch i32 %v, label %default [
i32 0, label %case0
]
case0:
call void @dummy()
ret void
default:
call void @dummy()
ret void
}
define void @switch_undef(i32 %x) {
; CHECK-LABEL: define void @switch_undef
; CHECK-SAME: (i32 [[X:%.*]]) {
; CHECK-NEXT: switch i32 undef, label [[DEFAULT:%.*]] [
; CHECK-NEXT: i32 0, label [[CASE0:%.*]]
; CHECK-NEXT: ]
; CHECK: case0:
; CHECK-NEXT: ret void
; CHECK: default:
; CHECK-NEXT: ret void
;
%v = xor i32 %x, undef
switch i32 %v, label %default [
i32 0, label %case0
]
case0:
call void @dummy()
ret void
default:
call void @dummy()
ret void
}
define void @non_term_unreachable() {
; CHECK-LABEL: define void @non_term_unreachable() {
; CHECK-NEXT: call void @dummy()
; CHECK-NEXT: store i1 true, ptr poison, align 1
; CHECK-NEXT: ret void
;
call void @dummy()
call void @dummy() nounwind willreturn
store i1 true, ptr poison
call void @dummy()
ret void
}
define i32 @non_term_unreachable_phi(i1 %c) {
; CHECK-LABEL: define i32 @non_term_unreachable_phi
; CHECK-SAME: (i1 [[C:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[JOIN:%.*]]
; CHECK: if:
; CHECK-NEXT: store i1 true, ptr poison, align 1
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: ret i32 2
;
entry:
br i1 %c, label %if, label %join
if:
store i1 true, ptr poison
call void @dummy()
br label %join
join:
%phi = phi i32 [ 1, %if], [ 2, %entry ]
ret i32 %phi
}
define void @br_not_into_loop(i1 %x) {
; CHECK-LABEL: define void @br_not_into_loop
; CHECK-SAME: (i1 [[X:%.*]]) {
; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: call void @dummy()
; CHECK-NEXT: ret void
;
%c = or i1 %x, true
br i1 %c, label %exit, label %loop
loop:
call void @dummy()
br label %loop
exit:
call void @dummy()
ret void
}
define void @br_into_loop(i1 %x) {
; CHECK-LABEL: define void @br_into_loop
; CHECK-SAME: (i1 [[X:%.*]]) {
; CHECK-NEXT: br i1 true, label [[LOOP:%.*]], label [[EXIT:%.*]]
; CHECK: loop:
; CHECK-NEXT: call void @dummy()
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
%c = or i1 %x, true
br i1 %c, label %loop, label %exit
loop:
call void @dummy()
br label %loop
exit:
call void @dummy()
ret void
}
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; DEFAULT_ITER: {{.*}}
; MAX1: {{.*}}