aboutsummaryrefslogtreecommitdiff
path: root/llvm/test/Transforms/SimplifyCFG
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/Transforms/SimplifyCFG')
-rw-r--r--llvm/test/Transforms/SimplifyCFG/pr166369.ll37
-rw-r--r--llvm/test/Transforms/SimplifyCFG/rangereduce.ll2
-rw-r--r--llvm/test/Transforms/SimplifyCFG/switch-on-const.ll (renamed from llvm/test/Transforms/SimplifyCFG/switch-on-const-select.ll)126
-rw-r--r--llvm/test/Transforms/SimplifyCFG/switch-umin.ll246
-rw-r--r--llvm/test/Transforms/SimplifyCFG/switch_mask.ll1
-rw-r--r--llvm/test/Transforms/SimplifyCFG/switch_undef.ll7
6 files changed, 414 insertions, 5 deletions
diff --git a/llvm/test/Transforms/SimplifyCFG/pr166369.ll b/llvm/test/Transforms/SimplifyCFG/pr166369.ll
new file mode 100644
index 0000000..c0a85c0
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/pr166369.ll
@@ -0,0 +1,37 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=simplifycfg < %s | FileCheck %s
+
+; Make sure we handle full-set ranges correctly.
+define void @test_i1() {
+; CHECK-LABEL: define void @test_i1() {
+; CHECK-NEXT: [[BB:.*:]]
+; CHECK-NEXT: ret void
+;
+bb:
+ %icmp = icmp ugt i1 false, true
+ br label %bb5
+
+bb5:
+ %select = select i1 %icmp, i1 %icmp, i1 false
+ br i1 %select, label %bb5, label %bb6
+
+bb6:
+ ret void
+}
+
+define void @test_i3() {
+; CHECK-LABEL: define void @test_i3() {
+; CHECK-NEXT: [[BB:.*:]]
+; CHECK-NEXT: ret void
+;
+bb:
+ %icmp = icmp ugt i3 0, 7
+ br label %bb5
+
+bb5:
+ %select = select i1 %icmp, i1 %icmp, i1 false
+ br i1 %select, label %bb5, label %bb6
+
+bb6:
+ ret void
+}
diff --git a/llvm/test/Transforms/SimplifyCFG/rangereduce.ll b/llvm/test/Transforms/SimplifyCFG/rangereduce.ll
index d1fba91..169803f 100644
--- a/llvm/test/Transforms/SimplifyCFG/rangereduce.ll
+++ b/llvm/test/Transforms/SimplifyCFG/rangereduce.ll
@@ -321,7 +321,7 @@ three:
!1 = !{!"branch_weights", i32 5, i32 7, i32 11, i32 13, i32 17}
;.
; CHECK: attributes #[[ATTR0:[0-9]+]] = { optsize }
-; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
;.
; CHECK: [[META0:![0-9]+]] = !{!"function_entry_count", i32 100}
; CHECK: [[PROF1]] = !{!"branch_weights", i32 48, i32 5}
diff --git a/llvm/test/Transforms/SimplifyCFG/switch-on-const-select.ll b/llvm/test/Transforms/SimplifyCFG/switch-on-const.ll
index e8b5863..1ab1b5e 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch-on-const-select.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch-on-const.ll
@@ -154,6 +154,132 @@ bees:
unreachable
}
+define void @pr165179(i1 %cond) {
+; CHECK-LABEL: @pr165179(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+; CHECK: if.then:
+; CHECK-NEXT: tail call void @bees.a() #[[ATTR0]]
+; CHECK-NEXT: br label [[SWITCHBB:%.*]]
+; CHECK: if.else:
+; CHECK-NEXT: tail call void @bees.b() #[[ATTR0]]
+; CHECK-NEXT: br label [[SWITCHBB]]
+; CHECK: exit:
+; CHECK-NEXT: tail call void @bees.a() #[[ATTR0]]
+; CHECK-NEXT: ret void
+;
+entry:
+ br i1 %cond, label %if.then, label %if.else
+
+if.then:
+ tail call void @bees.a() nounwind
+ br label %switchbb
+
+if.else:
+ tail call void @bees.b() nounwind
+ br label %switchbb
+
+switchbb:
+ %cond1 = phi i32 [ 1, %if.else ], [ -1, %if.then ]
+ switch i32 %cond1, label %default [
+ i32 1, label %exit
+ i32 -1, label %exit
+ ]
+
+exit:
+ tail call void @bees.a() nounwind
+ ret void
+
+default:
+ tail call void @bees.b() nounwind
+ ret void
+}
+
+define void @switch_remove_dead_case_phi(i1 %cond1, i1 %cond2) {
+; CHECK-LABEL: @switch_remove_dead_case_phi(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[COND1:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+; CHECK: if.then:
+; CHECK-NEXT: tail call void @bees.a() #[[ATTR0]]
+; CHECK-NEXT: br i1 [[COND2:%.*]], label [[SWITCHBB:%.*]], label [[IF_ELSE]]
+; CHECK: if.else:
+; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 3, [[ENTRY:%.*]] ], [ -1, [[IF_THEN]] ]
+; CHECK-NEXT: tail call void @bees.b() #[[ATTR0]]
+; CHECK-NEXT: br label [[SWITCHBB]]
+; CHECK: switchbb:
+; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[PHI]], [[IF_ELSE]] ], [ 5, [[IF_THEN]] ]
+; CHECK-NEXT: [[COND3:%.*]] = icmp eq i32 [[COND]], -1
+; CHECK-NEXT: br i1 [[COND3]], label [[EXIT:%.*]], label [[DEFAULT:%.*]]
+; CHECK: common.ret:
+; CHECK-NEXT: ret void
+; CHECK: exit:
+; CHECK-NEXT: tail call void @bees.a() #[[ATTR0]]
+; CHECK-NEXT: br label [[COMMON_RET:%.*]]
+; CHECK: default:
+; CHECK-NEXT: tail call void @bees.b() #[[ATTR0]]
+; CHECK-NEXT: br label [[COMMON_RET]]
+;
+entry:
+ br i1 %cond1, label %if.then, label %if.else
+
+if.then:
+ tail call void @bees.a() nounwind
+ br i1 %cond2, label %switchbb, label %if.else
+
+if.else:
+ %phi = phi i32 [ 3, %entry ], [ -1, %if.then ]
+ tail call void @bees.b() nounwind
+ br label %switchbb
+
+switchbb:
+ %cond = phi i32 [ %phi, %if.else ], [ 5, %if.then ]
+ switch i32 %cond, label %default [
+ i32 1, label %exit
+ i32 -1, label %exit
+ ]
+
+exit:
+ tail call void @bees.a() nounwind
+ ret void
+
+default:
+ tail call void @bees.b() nounwind
+ ret void
+}
+
+define void @switch_remove_dead_case_select(i1 %cond1, i1 %cond2) {
+; CHECK-LABEL: @switch_remove_dead_case_select(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[X:%.*]] = select i1 [[COND1:%.*]], i32 -1, i32 3
+; CHECK-NEXT: [[Y:%.*]] = select i1 [[COND2:%.*]], i32 [[X]], i32 5
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[Y]], -1
+; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[DEFAULT:%.*]]
+; CHECK: common.ret:
+; CHECK-NEXT: ret void
+; CHECK: exit:
+; CHECK-NEXT: tail call void @bees.a() #[[ATTR0]]
+; CHECK-NEXT: br label [[COMMON_RET:%.*]]
+; CHECK: default:
+; CHECK-NEXT: tail call void @bees.b() #[[ATTR0]]
+; CHECK-NEXT: br label [[COMMON_RET]]
+;
+entry:
+ %x = select i1 %cond1, i32 -1, i32 3
+ %y = select i1 %cond2, i32 %x, i32 5
+ switch i32 %y, label %default [
+ i32 1, label %exit
+ i32 -1, label %exit
+ ]
+
+exit:
+ tail call void @bees.a() nounwind
+ ret void
+
+default:
+ tail call void @bees.b() nounwind
+ ret void
+}
+
declare void @llvm.trap() nounwind noreturn
declare void @bees.a() nounwind
declare void @bees.b() nounwind
diff --git a/llvm/test/Transforms/SimplifyCFG/switch-umin.ll b/llvm/test/Transforms/SimplifyCFG/switch-umin.ll
new file mode 100644
index 0000000..4466536
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/switch-umin.ll
@@ -0,0 +1,246 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=simplifycfg < %s | FileCheck %s
+
+declare void @a()
+declare void @b()
+declare void @c()
+declare void @d()
+
+define void @switch_replace_default(i32 %x) {
+; CHECK-LABEL: define void @switch_replace_default(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 3)
+; CHECK-NEXT: switch i32 [[X]], label %[[COMMON_RET:.*]] [
+; CHECK-NEXT: i32 0, label %[[CASE0:.*]]
+; CHECK-NEXT: i32 1, label %[[CASE1:.*]]
+; CHECK-NEXT: i32 2, label %[[CASE2:.*]]
+; CHECK-NEXT: ], !prof [[PROF0:![0-9]+]]
+; CHECK: [[COMMON_RET]]:
+; CHECK-NEXT: ret void
+; CHECK: [[CASE0]]:
+; CHECK-NEXT: call void @a()
+; CHECK-NEXT: br label %[[COMMON_RET]]
+; CHECK: [[CASE1]]:
+; CHECK-NEXT: call void @b()
+; CHECK-NEXT: br label %[[COMMON_RET]]
+; CHECK: [[CASE2]]:
+; CHECK-NEXT: call void @c()
+; CHECK-NEXT: br label %[[COMMON_RET]]
+;
+ %min = call i32 @llvm.umin.i32(i32 %x, i32 3)
+ switch i32 %min, label %unreachable [
+ i32 0, label %case0
+ i32 1, label %case1
+ i32 2, label %case2
+ i32 3, label %case3
+ ], !prof !0
+
+case0:
+ call void @a()
+ ret void
+
+case1:
+ call void @b()
+ ret void
+
+case2:
+ call void @c()
+ ret void
+
+case3:
+ ret void
+
+unreachable:
+ unreachable
+}
+
+define void @switch_replace_default_and_remove_dead_cases(i32 %x) {
+; CHECK-LABEL: define void @switch_replace_default_and_remove_dead_cases(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 3)
+; CHECK-NEXT: switch i32 [[X]], label %[[COMMON_RET:.*]] [
+; CHECK-NEXT: i32 2, label %[[CASE2:.*]]
+; CHECK-NEXT: i32 1, label %[[CASE1:.*]]
+; CHECK-NEXT: ]
+; CHECK: [[COMMON_RET]]:
+; CHECK-NEXT: ret void
+; CHECK: [[CASE1]]:
+; CHECK-NEXT: call void @b()
+; CHECK-NEXT: br label %[[COMMON_RET]]
+; CHECK: [[CASE2]]:
+; CHECK-NEXT: call void @c()
+; CHECK-NEXT: br label %[[COMMON_RET]]
+;
+ %min = call i32 @llvm.umin.i32(i32 %x, i32 3)
+ switch i32 %min, label %unreachable [
+ i32 4, label %case4
+ i32 1, label %case1
+ i32 2, label %case2
+ i32 3, label %case3
+ ]
+
+case4:
+ call void @a()
+ ret void
+
+case1:
+ call void @b()
+ ret void
+
+case2:
+ call void @c()
+ ret void
+
+case3:
+ ret void
+
+unreachable:
+ unreachable
+}
+
+define void @switch_replace_default_when_holes(i32 %x) {
+; CHECK-LABEL: define void @switch_replace_default_when_holes(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 3)
+; CHECK-NEXT: switch i32 [[X]], label %[[COMMON_RET:.*]] [
+; CHECK-NEXT: i32 1, label %[[CASE1:.*]]
+; CHECK-NEXT: i32 2, label %[[CASE2:.*]]
+; CHECK-NEXT: ]
+; CHECK: [[COMMON_RET]]:
+; CHECK-NEXT: ret void
+; CHECK: [[CASE1]]:
+; CHECK-NEXT: call void @b()
+; CHECK-NEXT: br label %[[COMMON_RET]]
+; CHECK: [[CASE2]]:
+; CHECK-NEXT: call void @c()
+; CHECK-NEXT: br label %[[COMMON_RET]]
+;
+ %min = call i32 @llvm.umin.i32(i32 %x, i32 3)
+ switch i32 %min, label %unreachable [
+ i32 1, label %case1
+ i32 2, label %case2
+ i32 3, label %case3
+ ]
+
+case1:
+ call void @b()
+ ret void
+
+case2:
+ call void @c()
+ ret void
+
+case3:
+ ret void
+
+unreachable:
+ unreachable
+}
+
+define void @do_not_switch_replace_default(i32 %x, i32 %y) {
+; CHECK-LABEL: define void @do_not_switch_replace_default(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: switch i32 [[MIN]], label %[[UNREACHABLE:.*]] [
+; CHECK-NEXT: i32 0, label %[[CASE0:.*]]
+; CHECK-NEXT: i32 1, label %[[CASE1:.*]]
+; CHECK-NEXT: i32 2, label %[[CASE2:.*]]
+; CHECK-NEXT: i32 3, label %[[COMMON_RET:.*]]
+; CHECK-NEXT: ]
+; CHECK: [[COMMON_RET]]:
+; CHECK-NEXT: ret void
+; CHECK: [[CASE0]]:
+; CHECK-NEXT: call void @a()
+; CHECK-NEXT: br label %[[COMMON_RET]]
+; CHECK: [[CASE1]]:
+; CHECK-NEXT: call void @b()
+; CHECK-NEXT: br label %[[COMMON_RET]]
+; CHECK: [[CASE2]]:
+; CHECK-NEXT: call void @c()
+; CHECK-NEXT: br label %[[COMMON_RET]]
+; CHECK: [[UNREACHABLE]]:
+; CHECK-NEXT: unreachable
+;
+ %min = call i32 @llvm.umin.i32(i32 %x, i32 %y)
+ switch i32 %min, label %unreachable [
+ i32 0, label %case0
+ i32 1, label %case1
+ i32 2, label %case2
+ i32 3, label %case3
+ ]
+
+case0:
+ call void @a()
+ ret void
+
+case1:
+ call void @b()
+ ret void
+
+case2:
+ call void @c()
+ ret void
+
+case3:
+ ret void
+
+unreachable:
+ unreachable
+}
+
+define void @do_not_replace_switch_default_but_remove_dead_cases(i32 %x) {
+; CHECK-LABEL: define void @do_not_replace_switch_default_but_remove_dead_cases(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 3)
+; CHECK-NEXT: switch i32 [[MIN]], label %[[CASE0:.*]] [
+; CHECK-NEXT: i32 3, label %[[COMMON_RET:.*]]
+; CHECK-NEXT: i32 1, label %[[CASE1:.*]]
+; CHECK-NEXT: i32 2, label %[[CASE2:.*]]
+; CHECK-NEXT: ]
+; CHECK: [[COMMON_RET]]:
+; CHECK-NEXT: ret void
+; CHECK: [[CASE0]]:
+; CHECK-NEXT: call void @a()
+; CHECK-NEXT: br label %[[COMMON_RET]]
+; CHECK: [[CASE1]]:
+; CHECK-NEXT: call void @b()
+; CHECK-NEXT: br label %[[COMMON_RET]]
+; CHECK: [[CASE2]]:
+; CHECK-NEXT: call void @c()
+; CHECK-NEXT: br label %[[COMMON_RET]]
+;
+ %min = call i32 @llvm.umin.i32(i32 %x, i32 3)
+ switch i32 %min, label %case0 [ ; default is reachable, therefore simplification not triggered
+ i32 0, label %case0
+ i32 1, label %case1
+ i32 2, label %case2
+ i32 3, label %case3
+ i32 4, label %case4
+ ]
+
+case0:
+ call void @a()
+ ret void
+
+case1:
+ call void @b()
+ ret void
+
+case2:
+ call void @c()
+ ret void
+
+case3:
+ ret void
+
+case4:
+ call void @d()
+ ret void
+
+}
+
+
+!0 = !{!"branch_weights", i32 1, i32 2, i32 3, i32 99, i32 5}
+;.
+; CHECK: [[PROF0]] = !{!"branch_weights", i32 5, i32 2, i32 3, i32 99}
+;.
diff --git a/llvm/test/Transforms/SimplifyCFG/switch_mask.ll b/llvm/test/Transforms/SimplifyCFG/switch_mask.ll
index f8bcbc0..428c18f 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch_mask.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch_mask.ll
@@ -221,6 +221,7 @@ define i1 @pr88607() {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COND:%.*]] = select i1 false, i32 4, i32 1
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 false, i32 2, i32 [[COND]]
+; CHECK-NEXT: [[COND1:%.*]] = icmp eq i32 [[SPEC_SELECT]], 1
; CHECK-NEXT: ret i1 false
;
entry:
diff --git a/llvm/test/Transforms/SimplifyCFG/switch_undef.ll b/llvm/test/Transforms/SimplifyCFG/switch_undef.ll
index 88a729b..4de5ea9 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch_undef.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch_undef.ll
@@ -5,12 +5,11 @@
define void @f6() #0 {
; CHECK-LABEL: @f6(
; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[FOR_COND_I:%.*]]
-; CHECK: for.cond.i:
+; CHECK-NEXT: br label [[F1_EXIT_I:%.*]]
+; CHECK: f1.exit.i:
; CHECK-NEXT: [[TOBOOL7_I:%.*]] = icmp ne i16 1, 0
-; CHECK-NEXT: br label [[FOR_COND_I]]
+; CHECK-NEXT: br label [[F1_EXIT_I]]
;
-
entry:
br label %for.cond.i