1 ; Replace a 'select' with 'or' in 'select - cmp [eq|ne] - br' sequence
2 ; RUN: opt -instcombine -S < %s | FileCheck %s
4 %C = type <{ %struct.S }>
5 %struct.S = type { i64*, i32, i32 }
7 declare void @bar(%struct.S *) #1
10 define void @test1(%C*) {
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
24 ; <label>:9 ; preds = %10, %12
27 ; <label>:10 ; preds = %entry
28 %11 = getelementptr inbounds %C, %C* %7, i64 0, i32 0
29 tail call void @bar(%struct.S* %11)
32 ; <label>:12 ; preds = %entry
33 %13 = tail call i64 %5(%C* %0)
35 ; CHECK-LABEL: @test1(
41 define void @test2(%C*) {
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
55 ; <label>:9 ; preds = %10, %12
58 ; <label>:10 ; preds = %entry
59 %11 = getelementptr inbounds %C, %C* %7, i64 0, i32 0
60 tail call void @bar(%struct.S* %11)
63 ; <label>:12 ; preds = %entry
64 %13 = tail call i64 %5(%C* %0)
66 ; CHECK-LABEL: @test2(
72 define void @test3(%C*) {
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
86 ; <label>:9 ; preds = %10, %12
89 ; <label>:10 ; preds = %entry
90 %11 = getelementptr inbounds %C, %C* %7, i64 0, i32 0
91 tail call void @bar(%struct.S* %11)
94 ; <label>:12 ; preds = %entry
95 %13 = tail call i64 %5(%C* %0)
97 ; CHECK-LABEL: @test3(
103 define void @test4(%C*) {
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
117 ; <label>:9 ; preds = %10, %12
120 ; <label>:10 ; preds = %entry
121 %11 = getelementptr inbounds %C, %C* %7, i64 0, i32 0
122 tail call void @bar(%struct.S* %11)
125 ; <label>:12 ; preds = %entry
126 %13 = tail call i64 %5(%C* %0)
128 ; CHECK-LABEL: @test4(
134 define void @test5(%C*, i1) {
136 %2 = select i1 %1, %C* null, %C* %0
137 %3 = icmp ne %C* %2, null
138 br i1 %3, label %5, label %7
140 ; <label>:4 ; preds = %10, %12
143 ; <label>:5 ; preds = %entry
144 %6 = getelementptr inbounds %C, %C* %2, i64 0, i32 0
145 tail call void @bar(%struct.S* %6)
148 ; <label>:7 ; preds = %entry
149 tail call void @foobar()
151 ; CHECK-LABEL: @test5(