xref: /llvm-project/llvm/test/Transforms/SimplifyCFG/switch-on-const-select.ll (revision 6fa8244eb6cc4d2a079c347f7c44d842fc83a913)
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 basic folding to a conditional branch.
5define i32 @foo(i64 %x, i64 %y) nounwind {
6; CHECK-LABEL: @foo(
7; CHECK-NEXT:  entry:
8; CHECK-NEXT:    [[EQ:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
9; CHECK-NEXT:    br i1 [[EQ]], label [[B:%.*]], label [[SWITCH:%.*]]
10; CHECK:       switch:
11; CHECK-NEXT:    [[LT:%.*]] = icmp slt i64 [[X]], [[Y]]
12; CHECK-NEXT:    br i1 [[LT]], label [[A:%.*]], label [[B]]
13; CHECK:       common.ret:
14; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = phi i32 [ 1, [[A]] ], [ [[RETVAL:%.*]], [[B]] ]
15; CHECK-NEXT:    ret i32 [[COMMON_RET_OP]]
16; CHECK:       a:
17; CHECK-NEXT:    tail call void @bees.a() #[[ATTR0:[0-9]+]]
18; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
19; CHECK:       b:
20; CHECK-NEXT:    [[RETVAL]] = phi i32 [ 0, [[SWITCH]] ], [ 2, [[ENTRY:%.*]] ]
21; CHECK-NEXT:    tail call void @bees.b() #[[ATTR0]]
22; CHECK-NEXT:    br label [[COMMON_RET]]
23;
24entry:
25  %eq = icmp eq i64 %x, %y
26  br i1 %eq, label %b, label %switch
27switch:
28  %lt = icmp slt i64 %x, %y
29  %qux = select i1 %lt, i32 0, i32 2
30  switch i32 %qux, label %bees [
31  i32 0, label %a
32  i32 1, label %b
33  i32 2, label %b
34  ]
35a:
36  tail call void @bees.a() nounwind
37  ret i32 1
38b:
39  %retval = phi i32 [0, %switch], [0, %switch], [2, %entry]
40  tail call void @bees.b() nounwind
41  ret i32 %retval
42bees:
43  tail call void @llvm.trap() nounwind
44  unreachable
45}
46
47; Test basic folding to an unconditional branch.
48define i32 @bar(i64 %x, i64 %y) nounwind {
49; CHECK-LABEL: @bar(
50; CHECK-NEXT:  entry:
51; CHECK-NEXT:    tail call void @bees.a() #[[ATTR0]]
52; CHECK-NEXT:    ret i32 0
53;
54entry:
55  %lt = icmp slt i64 %x, %y
56  %qux = select i1 %lt, i32 0, i32 2
57  switch i32 %qux, label %bees [
58  i32 0, label %a
59  i32 1, label %b
60  i32 2, label %a
61  ]
62a:
63  %retval = phi i32 [0, %entry], [0, %entry], [1, %b]
64  tail call void @bees.a() nounwind
65  ret i32 0
66b:
67  tail call void @bees.b() nounwind
68  br label %a
69bees:
70  tail call void @llvm.trap() nounwind
71  unreachable
72}
73
74; Test the edge case where both values from the select are the default case.
75define void @bazz(i64 %x, i64 %y) nounwind {
76; CHECK-LABEL: @bazz(
77; CHECK-NEXT:  entry:
78; CHECK-NEXT:    tail call void @bees.b() #[[ATTR0]]
79; CHECK-NEXT:    ret void
80;
81entry:
82  %lt = icmp slt i64 %x, %y
83  %qux = select i1 %lt, i32 10, i32 12
84  switch i32 %qux, label %b [
85  i32 0, label %a
86  i32 1, label %bees
87  i32 2, label %bees
88  ]
89a:
90  tail call void @bees.a() nounwind
91  ret void
92b:
93  tail call void @bees.b() nounwind
94  ret void
95bees:
96  tail call void @llvm.trap()
97  unreachable
98}
99
100; Test the edge case where both values from the select are equal.
101define void @quux(i64 %x, i64 %y) nounwind {
102; CHECK-LABEL: @quux(
103; CHECK-NEXT:  entry:
104; CHECK-NEXT:    tail call void @bees.a() #[[ATTR0]]
105; CHECK-NEXT:    ret void
106;
107entry:
108  %lt = icmp slt i64 %x, %y
109  %qux = select i1 %lt, i32 0, i32 0
110  switch i32 %qux, label %b [
111  i32 0, label %a
112  i32 1, label %bees
113  i32 2, label %bees
114  ]
115a:
116  tail call void @bees.a() nounwind
117  ret void
118b:
119  tail call void @bees.b() nounwind
120  ret void
121bees:
122  tail call void @llvm.trap()
123  unreachable
124}
125
126; A final test, for phi node munging.
127define i32 @xyzzy(i64 %x, i64 %y) {
128; CHECK-LABEL: @xyzzy(
129; CHECK-NEXT:  entry:
130; CHECK-NEXT:    [[EQ:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
131; CHECK-NEXT:    [[LT:%.*]] = icmp slt i64 [[X]], [[Y]]
132; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[LT]], i32 -1, i32 1
133; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = select i1 [[EQ]], i32 0, i32 [[SPEC_SELECT]]
134; CHECK-NEXT:    ret i32 [[COMMON_RET_OP]]
135;
136entry:
137  %eq = icmp eq i64 %x, %y
138  br i1 %eq, label %r, label %cont
139cont:
140  %lt = icmp slt i64 %x, %y
141  %qux = select i1 %lt, i32 0, i32 2
142  switch i32 %qux, label %bees [
143  i32 0, label %a
144  i32 1, label %r
145  i32 2, label %r
146  ]
147r:
148  %val = phi i32 [0, %entry], [1, %cont], [1, %cont]
149  ret i32 %val
150a:
151  ret i32 -1
152bees:
153  tail call void @llvm.trap()
154  unreachable
155}
156
157declare void @llvm.trap() nounwind noreturn
158declare void @bees.a() nounwind
159declare void @bees.b() nounwind
160
161; CHECK: attributes #1 = { cold noreturn nounwind memory(inaccessiblemem: write) }
162