1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -instcombine -S < %s | FileCheck %s
3; RUN: opt -passes=instcombine -S < %s | FileCheck %s
4
5declare void @use(i32 %x)
6declare i1 @cond()
7
8define void @test_01(i32 %x, i32 %y) {
9; CHECK-LABEL: @test_01(
10; CHECK-NEXT:  entry:
11; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
12; CHECK-NEXT:    br i1 [[C2]], label [[EXIT:%.*]], label [[UNREACHED:%.*]]
13; CHECK:       unreached:
14; CHECK-NEXT:    [[C1:%.*]] = icmp ne i32 [[X]], [[Y]]
15; CHECK-NEXT:    [[COMPARATOR:%.*]] = zext i1 [[C1]] to i32
16; CHECK-NEXT:    call void @use(i32 [[COMPARATOR]])
17; CHECK-NEXT:    unreachable
18; CHECK:       exit:
19; CHECK-NEXT:    ret void
20;
21entry:
22  %c1 = icmp eq i32 %x, %y
23  %c2 = icmp slt i32 %x, %y
24  %signed = select i1 %c2, i32 -1, i32 1
25  %comparator = select i1 %c1, i32 0, i32 %signed
26  br i1 %c2, label %exit, label %unreached
27
28unreached:
29  call void @use(i32 %comparator)
30  unreachable
31
32exit:
33  ret void
34}
35
36
37define void @test_02(i32 %x, i32 %y) {
38; CHECK-LABEL: @test_02(
39; CHECK-NEXT:  entry:
40; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
41; CHECK-NEXT:    br i1 [[C2]], label [[EXIT:%.*]], label [[MEDIUM:%.*]]
42; CHECK:       medium:
43; CHECK-NEXT:    [[C3:%.*]] = icmp sgt i32 [[X]], [[Y]]
44; CHECK-NEXT:    br i1 [[C3]], label [[EXIT]], label [[UNREACHED:%.*]]
45; CHECK:       unreached:
46; CHECK-NEXT:    [[C1:%.*]] = icmp eq i32 [[X]], [[Y]]
47; CHECK-NEXT:    [[SIGNED:%.*]] = select i1 [[C2]], i32 -1, i32 1
48; CHECK-NEXT:    [[COMPARATOR:%.*]] = select i1 [[C1]], i32 0, i32 [[SIGNED]]
49; CHECK-NEXT:    call void @use(i32 [[COMPARATOR]])
50; CHECK-NEXT:    unreachable
51; CHECK:       exit:
52; CHECK-NEXT:    ret void
53;
54entry:
55  %c1 = icmp eq i32 %x, %y
56  %c2 = icmp slt i32 %x, %y
57  %signed = select i1 %c2, i32 -1, i32 1
58  %comparator = select i1 %c1, i32 0, i32 %signed
59  br i1 %c2, label %exit, label %medium
60
61medium:
62  %c3 = icmp sgt i32 %x, %y
63  br i1 %c3, label %exit, label %unreached
64
65unreached:
66  call void @use(i32 %comparator)
67  unreachable
68
69exit:
70  ret void
71}
72
73define i32 @test_03(i32 %x, i32 %y) {
74; CHECK-LABEL: @test_03(
75; CHECK-NEXT:  entry:
76; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
77; CHECK-NEXT:    br i1 [[C2]], label [[EXIT:%.*]], label [[MEDIUM:%.*]]
78; CHECK:       medium:
79; CHECK-NEXT:    [[C3:%.*]] = icmp sgt i32 [[X]], [[Y]]
80; CHECK-NEXT:    br i1 [[C3]], label [[EXIT]], label [[UNREACHED:%.*]]
81; CHECK:       unreached:
82; CHECK-NEXT:    [[C1:%.*]] = icmp eq i32 [[X]], [[Y]]
83; CHECK-NEXT:    [[SIGNED:%.*]] = select i1 [[C2]], i32 -1, i32 1
84; CHECK-NEXT:    [[COMPARATOR:%.*]] = select i1 [[C1]], i32 0, i32 [[SIGNED]]
85; CHECK-NEXT:    ret i32 [[COMPARATOR]]
86; CHECK:       exit:
87; CHECK-NEXT:    ret i32 0
88;
89entry:
90  %c1 = icmp eq i32 %x, %y
91  %c2 = icmp slt i32 %x, %y
92  %signed = select i1 %c2, i32 -1, i32 1
93  %comparator = select i1 %c1, i32 0, i32 %signed
94  br i1 %c2, label %exit, label %medium
95
96medium:
97  %c3 = icmp sgt i32 %x, %y
98  br i1 %c3, label %exit, label %unreached
99
100unreached:
101  ret i32 %comparator
102
103exit:
104  ret i32 0
105}
106
107define i32 @test_04(i32 %x, i1 %c) {
108; CHECK-LABEL: @test_04(
109; CHECK-NEXT:  bb0:
110; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
111; CHECK:       bb1:
112; CHECK-NEXT:    br label [[BB3:%.*]]
113; CHECK:       bb2:
114; CHECK-NEXT:    br label [[BB3]]
115; CHECK:       bb3:
116; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[BB1]] ], [ 1, [[BB2]] ]
117; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], 1
118; CHECK-NEXT:    [[R:%.*]] = add i32 [[P]], [[A]]
119; CHECK-NEXT:    ret i32 [[R]]
120;
121bb0:
122  %a = add i32 %x, 1
123  br i1 %c, label %bb1, label %bb2
124bb1:
125  br label %bb3
126bb2:
127  br label %bb3
128bb3:
129  %p = phi i32 [0, %bb1], [1, %bb2]
130  %r = add i32 %p, %a
131  ret i32 %r
132}
133
134; Do not sink into a potentially hotter block.
135define i32 @test_05_neg(i32 %x, i1 %cond) {
136; CHECK-LABEL: @test_05_neg(
137; CHECK-NEXT:  bb0:
138; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], 1
139; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
140; CHECK:       bb1:
141; CHECK-NEXT:    br label [[BB3:%.*]]
142; CHECK:       bb2:
143; CHECK-NEXT:    [[CALL:%.*]] = call i1 @cond()
144; CHECK-NEXT:    br i1 [[CALL]], label [[BB2]], label [[BB3]]
145; CHECK:       bb3:
146; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[BB1]] ], [ [[A]], [[BB2]] ]
147; CHECK-NEXT:    ret i32 [[P]]
148;
149bb0:
150  %a = add i32 %x, 1
151  br i1 %cond, label %bb1, label %bb2
152bb1:
153  br label %bb3
154bb2:
155  %call = call i1 @cond()
156  br i1 %call, label %bb2, label %bb3
157bb3:
158  %p = phi i32 [0, %bb1], [%a, %bb2]
159  ret i32 %p
160}
161