xref: /llvm-project/llvm/test/Transforms/SimplifyCFG/switch_thread.ll (revision 07b9d231ff9baa6473b0dd588a3ce5330d3e4871)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
3
4; Test that we can thread a simple known condition through switch statements.
5
6declare void @foo1()
7
8declare void @foo2()
9
10declare void @DEAD()
11
12define void @test1(i32 %V) {
13; CHECK-LABEL: @test1(
14; CHECK-NEXT:    switch i32 [[V:%.*]], label [[A:%.*]] [
15; CHECK-NEXT:      i32 4, label [[T:%.*]]
16; CHECK-NEXT:      i32 17, label [[COMMON_RET:%.*]]
17; CHECK-NEXT:    ]
18; CHECK:       T:
19; CHECK-NEXT:    call void @foo1()
20; CHECK-NEXT:    call void @foo2()
21; CHECK-NEXT:    br label [[COMMON_RET]]
22; CHECK:       A:
23; CHECK-NEXT:    call void @foo1()
24; CHECK-NEXT:    br label [[COMMON_RET]]
25; CHECK:       common.ret:
26; CHECK-NEXT:    ret void
27;
28  switch i32 %V, label %A [
29  i32 4, label %T
30  i32 17, label %Done
31  i32 1234, label %A
32  ]
33;; V == 4 if we get here.
34T:              ; preds = %0
35  call void @foo1( )
36  ;; This switch is always statically determined.
37  switch i32 %V, label %A2 [
38  i32 4, label %B
39  i32 17, label %C
40  i32 42, label %C
41  ]
42A2:             ; preds = %T
43  call void @DEAD( )
44  call void @DEAD( )
45  ;; always true
46  %cond2 = icmp eq i32 %V, 4              ; <i1> [#uses=1]
47  br i1 %cond2, label %Done, label %C
48A:              ; preds = %0, %0
49  call void @foo1( )
50  ;; always true
51  %cond = icmp ne i32 %V, 4               ; <i1> [#uses=1]
52  br i1 %cond, label %Done, label %C
53Done:           ; preds = %B, %A, %A2, %0
54  ret void
55B:              ; preds = %T
56  call void @foo2( )
57  ;; always true
58  %cond3 = icmp eq i32 %V, 4              ; <i1> [#uses=1]
59  br i1 %cond3, label %Done, label %C
60C:              ; preds = %B, %A, %A2, %T, %T
61  call void @DEAD( )
62  ret void
63
64}
65
66define void @test2(i32 %V) {
67; CHECK-LABEL: @test2(
68; CHECK-NEXT:    switch i32 [[V:%.*]], label [[A:%.*]] [
69; CHECK-NEXT:      i32 4, label [[T:%.*]]
70; CHECK-NEXT:      i32 17, label [[D:%.*]]
71; CHECK-NEXT:      i32 1234, label [[COMMON_RET:%.*]]
72; CHECK-NEXT:    ]
73; CHECK:       A:
74; CHECK-NEXT:    call void @foo1()
75; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[V]], 42
76; CHECK-NEXT:    br i1 [[COND]], label [[D]], label [[COMMON_RET]]
77; CHECK:       common.ret:
78; CHECK-NEXT:    ret void
79; CHECK:       T:
80; CHECK-NEXT:    call void @foo1()
81; CHECK-NEXT:    call void @foo1()
82; CHECK-NEXT:    br label [[COMMON_RET]]
83; CHECK:       D:
84; CHECK-NEXT:    call void @foo1()
85; CHECK-NEXT:    br label [[COMMON_RET]]
86;
87  switch i32 %V, label %A [
88  i32 4, label %T
89  i32 17, label %D
90  i32 1234, label %E
91  ]
92;; V != 4, 17, 1234 here.
93A:              ; preds = %0
94  call void @foo1( )
95  ;; This switch is always statically determined.
96  switch i32 %V, label %E [
97  i32 4, label %C
98  i32 17, label %C
99  i32 42, label %D
100  ]
101;; unreacahble.
102C:              ; preds = %A, %A
103  call void @DEAD( )
104  ret void
105T:              ; preds = %0
106  call void @foo1( )
107  call void @foo1( )
108  ret void
109D:              ; preds = %A, %0
110  call void @foo1( )
111  ret void
112E:              ; preds = %A, %0
113  ret void
114
115}
116
117