1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4define i1 @cond_eq_and(i8 %X, i8 %Y, i8 noundef %C) {
5; CHECK-LABEL: @cond_eq_and(
6; CHECK-NEXT:    [[COND:%.*]] = icmp eq i8 [[X:%.*]], [[C:%.*]]
7; CHECK-NEXT:    [[LHS:%.*]] = icmp ult i8 [[X]], [[Y:%.*]]
8; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND]], i1 [[LHS]], i1 false
9; CHECK-NEXT:    ret i1 [[RES]]
10;
11  %cond = icmp eq i8 %X, %C
12  %lhs = icmp ult i8 %X, %Y
13  %res = select i1 %cond, i1 %lhs, i1 false
14  ret i1 %res
15}
16
17define i1 @cond_eq_and_const(i8 %X, i8 %Y) {
18; CHECK-LABEL: @cond_eq_and_const(
19; CHECK-NEXT:    [[COND:%.*]] = icmp eq i8 [[X:%.*]], 10
20; CHECK-NEXT:    [[LHS:%.*]] = icmp ugt i8 [[Y:%.*]], 10
21; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND]], i1 [[LHS]], i1 false
22; CHECK-NEXT:    ret i1 [[RES]]
23;
24  %cond = icmp eq i8 %X, 10
25  %lhs = icmp ult i8 %X, %Y
26  %res = select i1 %cond, i1 %lhs, i1 false
27  ret i1 %res
28}
29
30define i1 @cond_eq_or(i8 %X, i8 %Y, i8 noundef %C) {
31; CHECK-LABEL: @cond_eq_or(
32; CHECK-NEXT:    [[COND:%.*]] = icmp ne i8 [[X:%.*]], [[C:%.*]]
33; CHECK-NEXT:    [[LHS:%.*]] = icmp ult i8 [[X]], [[Y:%.*]]
34; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND]], i1 true, i1 [[LHS]]
35; CHECK-NEXT:    ret i1 [[RES]]
36;
37  %cond = icmp ne i8 %X, %C
38  %lhs = icmp ult i8 %X, %Y
39  %res = select i1 %cond, i1 true, i1 %lhs
40  ret i1 %res
41}
42
43define i1 @cond_eq_or_const(i8 %X, i8 %Y) {
44; CHECK-LABEL: @cond_eq_or_const(
45; CHECK-NEXT:    [[COND:%.*]] = icmp ne i8 [[X:%.*]], 10
46; CHECK-NEXT:    [[LHS:%.*]] = icmp ugt i8 [[Y:%.*]], 10
47; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND]], i1 true, i1 [[LHS]]
48; CHECK-NEXT:    ret i1 [[RES]]
49;
50  %cond = icmp ne i8 %X, 10
51  %lhs = icmp ult i8 %X, %Y
52  %res = select i1 %cond, i1 true, i1 %lhs
53  ret i1 %res
54}
55
56define i1 @xor_and(i1 %c, i32 %X, i32 %Y) {
57; CHECK-LABEL: @xor_and(
58; CHECK-NEXT:    [[COMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
59; CHECK-NEXT:    [[NOT_C:%.*]] = xor i1 [[C:%.*]], true
60; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[COMP]]
61; CHECK-NEXT:    ret i1 [[SEL]]
62;
63  %comp = icmp ult i32 %X, %Y
64  %sel = select i1 %c, i1 %comp, i1 false
65  %res = xor i1 %sel, true
66  ret i1 %res
67}
68
69define <2 x i1> @xor_and2(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) {
70; CHECK-LABEL: @xor_and2(
71; CHECK-NEXT:    [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]]
72; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[COMP]], <2 x i1> <i1 false, i1 true>
73; CHECK-NEXT:    ret <2 x i1> [[SEL]]
74;
75  %comp = icmp ult <2 x i32> %X, %Y
76  %sel = select <2 x i1> %c, <2 x i1> %comp, <2 x i1> <i1 true, i1 false>
77  %res = xor <2 x i1> %sel, <i1 true, i1 true>
78  ret <2 x i1> %res
79}
80
81@glb = global i8 0
82
83define <2 x i1> @xor_and3(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) {
84; CHECK-LABEL: @xor_and3(
85; CHECK-NEXT:    [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]]
86; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[COMP]], <2 x i1> <i1 icmp ne (i8* inttoptr (i64 1234 to i8*), i8* @glb), i1 true>
87; CHECK-NEXT:    ret <2 x i1> [[SEL]]
88;
89  %comp = icmp ult <2 x i32> %X, %Y
90  %sel = select <2 x i1> %c, <2 x i1> %comp, <2 x i1> <i1 icmp eq (i8* @glb, i8* inttoptr (i64 1234 to i8*)), i1 false>
91  %res = xor <2 x i1> %sel, <i1 true, i1 true>
92  ret <2 x i1> %res
93}
94
95define i1 @xor_or(i1 %c, i32 %X, i32 %Y) {
96; CHECK-LABEL: @xor_or(
97; CHECK-NEXT:    [[COMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
98; CHECK-NEXT:    [[NOT_C:%.*]] = xor i1 [[C:%.*]], true
99; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[NOT_C]], i1 [[COMP]], i1 false
100; CHECK-NEXT:    ret i1 [[SEL]]
101;
102  %comp = icmp ult i32 %X, %Y
103  %sel = select i1 %c, i1 true, i1 %comp
104  %res = xor i1 %sel, true
105  ret i1 %res
106}
107
108define <2 x i1> @xor_or2(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) {
109; CHECK-LABEL: @xor_or2(
110; CHECK-NEXT:    [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]]
111; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> <i1 false, i1 true>, <2 x i1> [[COMP]]
112; CHECK-NEXT:    ret <2 x i1> [[SEL]]
113;
114  %comp = icmp ult <2 x i32> %X, %Y
115  %sel = select <2 x i1> %c, <2 x i1> <i1 true, i1 false>, <2 x i1> %comp
116  %res = xor <2 x i1> %sel, <i1 true, i1 true>
117  ret <2 x i1> %res
118}
119
120define <2 x i1> @xor_or3(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) {
121; CHECK-LABEL: @xor_or3(
122; CHECK-NEXT:    [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]]
123; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> <i1 icmp ne (i8* inttoptr (i64 1234 to i8*), i8* @glb), i1 true>, <2 x i1> [[COMP]]
124; CHECK-NEXT:    ret <2 x i1> [[SEL]]
125;
126  %comp = icmp ult <2 x i32> %X, %Y
127  %sel = select <2 x i1> %c, <2 x i1> <i1 icmp eq (i8* @glb, i8* inttoptr (i64 1234 to i8*)), i1 false>, <2 x i1> %comp
128  %res = xor <2 x i1> %sel, <i1 true, i1 true>
129  ret <2 x i1> %res
130}
131
132define i1 @and_orn_cmp_1_logical(i32 %a, i32 %b, i1 %y) {
133; CHECK-LABEL: @and_orn_cmp_1_logical(
134; CHECK-NEXT:    [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
135; CHECK-NEXT:    [[AND:%.*]] = select i1 [[X]], i1 [[Y:%.*]], i1 false
136; CHECK-NEXT:    ret i1 [[AND]]
137;
138  %x = icmp sgt i32 %a, %b
139  %x_inv = icmp sle i32 %a, %b
140  %or = select i1 %y, i1 true, i1 %x_inv
141  %and = select i1 %x, i1 %or, i1 false
142  ret i1 %and
143}
144
145define i1 @andn_or_cmp_2_logical(i16 %a, i16 %b, i1 %y) {
146; CHECK-LABEL: @andn_or_cmp_2_logical(
147; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
148; CHECK-NEXT:    [[AND:%.*]] = select i1 [[Y:%.*]], i1 [[X_INV]], i1 false
149; CHECK-NEXT:    ret i1 [[AND]]
150;
151  %x = icmp sge i16 %a, %b
152  %x_inv = icmp slt i16 %a, %b
153  %or = select i1 %y, i1 true, i1 %x
154  %and = select i1 %or, i1 %x_inv, i1 false
155  ret i1 %and
156}
157
158define i1 @bools_logical(i1 %a, i1 %b, i1 %c) {
159; CHECK-LABEL: @bools_logical(
160; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]
161; CHECK-NEXT:    ret i1 [[OR]]
162;
163  %not = xor i1 %c, -1
164  %and1 = select i1 %not, i1 %a, i1 false
165  %and2 = select i1 %c, i1 %b, i1 false
166  %or = select i1 %and1, i1 true, i1 %and2
167  ret i1 %or
168}
169
170define i1 @bools2_logical(i1 %a, i1 %b, i1 %c) {
171; CHECK-LABEL: @bools2_logical(
172; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]
173; CHECK-NEXT:    ret i1 [[OR]]
174;
175  %not = xor i1 %c, -1
176  %and1 = select i1 %c, i1 %a, i1 false
177  %and2 = select i1 %not, i1 %b, i1 false
178  %or = select i1 %and1, i1 true, i1 %and2
179  ret i1 %or
180}
181
182define i1 @orn_and_cmp_1_logical(i37 %a, i37 %b, i1 %y) {
183; CHECK-LABEL: @orn_and_cmp_1_logical(
184; CHECK-NEXT:    [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
185; CHECK-NEXT:    [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y:%.*]]
186; CHECK-NEXT:    ret i1 [[OR]]
187;
188  %x = icmp sgt i37 %a, %b
189  %x_inv = icmp sle i37 %a, %b
190  %and = select i1 %y, i1 %x, i1 false
191  %or = select i1 %x_inv, i1 true, i1 %and
192  ret i1 %or
193}
194
195define i1 @orn_and_cmp_2_logical(i16 %a, i16 %b, i1 %y) {
196; CHECK-LABEL: @orn_and_cmp_2_logical(
197; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
198; CHECK-NEXT:    [[OR:%.*]] = select i1 [[Y:%.*]], i1 true, i1 [[X_INV]]
199; CHECK-NEXT:    ret i1 [[OR]]
200;
201  %x = icmp sge i16 %a, %b
202  %x_inv = icmp slt i16 %a, %b
203  %and = select i1 %y, i1 %x, i1 false
204  %or = select i1 %and, i1 true, i1 %x_inv
205  ret i1 %or
206}
207