1; Replace a 'select' with 'or' in 'select - cmp [eq|ne] - br' sequence
2; RUN: opt -instcombine -S < %s | FileCheck %s
3
4%C = type <{ %struct.S }>
5%struct.S = type { i64*, i32, i32 }
6
7declare void @bar(%struct.S *) #1
8declare void @foobar()
9
10define void @test1(%C*) {
11entry:
12  %1 = getelementptr inbounds %C, %C* %0, i64 0, i32 0, i32 0
13  %m = load i64*, i64** %1, align 8
14  %2 = getelementptr inbounds %C, %C* %0, i64 1, i32 0, i32 0
15  %n = load i64*, i64** %2, align 8
16  %3 = getelementptr inbounds i64, i64* %m, i64 9
17  %4 = bitcast i64* %3 to i64 (%C*)**
18  %5 = load i64 (%C*)*, i64 (%C*)** %4, align 8
19  %6 = icmp eq i64* %m, %n
20  %7 = select i1 %6, %C* %0, %C* null
21  %8 = icmp eq %C* %7, null
22  br i1 %8, label %12, label %10
23
24; <label>:9                                       ; preds = %10, %12
25  ret void
26
27; <label>:10                                      ; preds = %entry
28  %11 = getelementptr inbounds %C, %C* %7, i64 0, i32 0
29  tail call void @bar(%struct.S* %11)
30  br label %9
31
32; <label>:12                                      ; preds = %entry
33  %13 = tail call i64 %5(%C* %0)
34  br label %9
35; CHECK-LABEL: @test1(
36; CHECK-NOT: select
37; CHECK: or
38; CHECK-NOT: select
39}
40
41define void @test2(%C*) {
42entry:
43  %1 = getelementptr inbounds %C, %C* %0, i64 0, i32 0, i32 0
44  %m = load i64*, i64** %1, align 8
45  %2 = getelementptr inbounds %C, %C* %0, i64 1, i32 0, i32 0
46  %n = load i64*, i64** %2, align 8
47  %3 = getelementptr inbounds i64, i64* %m, i64 9
48  %4 = bitcast i64* %3 to i64 (%C*)**
49  %5 = load i64 (%C*)*, i64 (%C*)** %4, align 8
50  %6 = icmp eq i64* %m, %n
51  %7 = select i1 %6, %C* null, %C* %0
52  %8 = icmp eq %C* %7, null
53  br i1 %8, label %12, label %10
54
55; <label>:9                                       ; preds = %10, %12
56  ret void
57
58; <label>:10                                      ; preds = %entry
59  %11 = getelementptr inbounds %C, %C* %7, i64 0, i32 0
60  tail call void @bar(%struct.S* %11)
61  br label %9
62
63; <label>:12                                      ; preds = %entry
64  %13 = tail call i64 %5(%C* %0)
65  br label %9
66; CHECK-LABEL: @test2(
67; CHECK-NOT: select
68; CHECK: or
69; CHECK-NOT: select
70}
71
72define void @test3(%C*) {
73entry:
74  %1 = getelementptr inbounds %C, %C* %0, i64 0, i32 0, i32 0
75  %m = load i64*, i64** %1, align 8
76  %2 = getelementptr inbounds %C, %C* %0, i64 1, i32 0, i32 0
77  %n = load i64*, i64** %2, align 8
78  %3 = getelementptr inbounds i64, i64* %m, i64 9
79  %4 = bitcast i64* %3 to i64 (%C*)**
80  %5 = load i64 (%C*)*, i64 (%C*)** %4, align 8
81  %6 = icmp eq i64* %m, %n
82  %7 = select i1 %6, %C* %0, %C* null
83  %8 = icmp ne %C* %7, null
84  br i1 %8, label %10, label %12
85
86; <label>:9                                       ; preds = %10, %12
87  ret void
88
89; <label>:10                                      ; preds = %entry
90  %11 = getelementptr inbounds %C, %C* %7, i64 0, i32 0
91  tail call void @bar(%struct.S* %11)
92  br label %9
93
94; <label>:12                                      ; preds = %entry
95  %13 = tail call i64 %5(%C* %0)
96  br label %9
97; CHECK-LABEL: @test3(
98; CHECK-NOT: select
99; CHECK: or
100; CHECK-NOT: select
101}
102
103define void @test4(%C*) {
104entry:
105  %1 = getelementptr inbounds %C, %C* %0, i64 0, i32 0, i32 0
106  %m = load i64*, i64** %1, align 8
107  %2 = getelementptr inbounds %C, %C* %0, i64 1, i32 0, i32 0
108  %n = load i64*, i64** %2, align 8
109  %3 = getelementptr inbounds i64, i64* %m, i64 9
110  %4 = bitcast i64* %3 to i64 (%C*)**
111  %5 = load i64 (%C*)*, i64 (%C*)** %4, align 8
112  %6 = icmp eq i64* %m, %n
113  %7 = select i1 %6, %C* null, %C* %0
114  %8 = icmp ne %C* %7, null
115  br i1 %8, label %10, label %12
116
117; <label>:9                                       ; preds = %10, %12
118  ret void
119
120; <label>:10                                      ; preds = %entry
121  %11 = getelementptr inbounds %C, %C* %7, i64 0, i32 0
122  tail call void @bar(%struct.S* %11)
123  br label %9
124
125; <label>:12                                      ; preds = %entry
126  %13 = tail call i64 %5(%C* %0)
127  br label %9
128; CHECK-LABEL: @test4(
129; CHECK-NOT: select
130; CHECK: or
131; CHECK-NOT: select
132}
133
134define void @test5(%C*, i1) {
135entry:
136  %2 = select i1 %1, %C* null, %C* %0
137  %3 = icmp ne %C* %2, null
138  br i1 %3, label %5, label %7
139
140; <label>:4                                       ; preds = %10, %12
141  ret void
142
143; <label>:5                                      ; preds = %entry
144  %6 = getelementptr inbounds %C, %C* %2, i64 0, i32 0
145  tail call void @bar(%struct.S* %6)
146  br label %4
147
148; <label>:7                                      ; preds = %entry
149  tail call void @foobar()
150  br label %4
151; CHECK-LABEL: @test5(
152; CHECK-NOT: select
153; CHECK: or
154; CHECK-NOT: select
155}
156