xref: /llvm-project/llvm/test/Transforms/InstCombine/binop-select-cast-of-select-cond.ll (revision 10f315dc9c96ec2413881ab55a285e35d80def88)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4define i64 @add_select_zext(i1 %c) {
5; CHECK-LABEL: define i64 @add_select_zext
6; CHECK-SAME: (i1 [[C:%.*]]) {
7; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[C]], i64 65, i64 1
8; CHECK-NEXT:    ret i64 [[ADD]]
9;
10  %sel = select i1 %c, i64 64, i64 1
11  %ext = zext i1 %c to i64
12  %add = add i64 %sel, %ext
13  ret i64 %add
14}
15
16define i64 @add_select_sext(i1 %c) {
17; CHECK-LABEL: define i64 @add_select_sext
18; CHECK-SAME: (i1 [[C:%.*]]) {
19; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[C]], i64 63, i64 1
20; CHECK-NEXT:    ret i64 [[ADD]]
21;
22  %sel = select i1 %c, i64 64, i64 1
23  %ext = sext i1 %c to i64
24  %add = add i64 %sel, %ext
25  ret i64 %add
26}
27
28define i64 @add_select_not_zext(i1 %c) {
29; CHECK-LABEL: define i64 @add_select_not_zext
30; CHECK-SAME: (i1 [[C:%.*]]) {
31; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[C]], i64 64, i64 2
32; CHECK-NEXT:    ret i64 [[ADD]]
33;
34  %sel = select i1 %c, i64 64, i64 1
35  %not.c = xor i1 %c, true
36  %ext = zext i1 %not.c to i64
37  %add = add i64 %sel, %ext
38  ret i64 %add
39}
40
41define i64 @add_select_not_sext(i1 %c) {
42; CHECK-LABEL: define i64 @add_select_not_sext
43; CHECK-SAME: (i1 [[C:%.*]]) {
44; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[C]], i64 64, i64 0
45; CHECK-NEXT:    ret i64 [[ADD]]
46;
47  %sel = select i1 %c, i64 64, i64 1
48  %not.c = xor i1 %c, true
49  %ext = sext i1 %not.c to i64
50  %add = add i64 %sel, %ext
51  ret i64 %add
52}
53
54define i64 @sub_select_sext(i1 %c, i64 %arg) {
55; CHECK-LABEL: define i64 @sub_select_sext
56; CHECK-SAME: (i1 [[C:%.*]], i64 [[ARG:%.*]]) {
57; CHECK-NEXT:    [[SUB:%.*]] = select i1 [[C]], i64 65, i64 [[ARG]]
58; CHECK-NEXT:    ret i64 [[SUB]]
59;
60  %sel = select i1 %c, i64 64, i64 %arg
61  %ext = sext i1 %c to i64
62  %sub = sub i64 %sel, %ext
63  ret i64 %sub
64}
65
66define i64 @sub_select_not_zext(i1 %c, i64 %arg) {
67; CHECK-LABEL: define i64 @sub_select_not_zext
68; CHECK-SAME: (i1 [[C:%.*]], i64 [[ARG:%.*]]) {
69; CHECK-NEXT:    [[SUB:%.*]] = select i1 [[C]], i64 [[ARG]], i64 63
70; CHECK-NEXT:    ret i64 [[SUB]]
71;
72  %sel = select i1 %c, i64 %arg, i64 64
73  %not.c = xor i1 %c, true
74  %ext = zext i1 %not.c to i64
75  %sub = sub i64 %sel, %ext
76  ret i64 %sub
77}
78
79define i64 @sub_select_not_sext(i1 %c, i64 %arg) {
80; CHECK-LABEL: define i64 @sub_select_not_sext
81; CHECK-SAME: (i1 [[C:%.*]], i64 [[ARG:%.*]]) {
82; CHECK-NEXT:    [[SUB:%.*]] = select i1 [[C]], i64 [[ARG]], i64 65
83; CHECK-NEXT:    ret i64 [[SUB]]
84;
85  %sel = select i1 %c, i64 %arg, i64 64
86  %not.c = xor i1 %c, true
87  %ext = sext i1 %not.c to i64
88  %sub = sub i64 %sel, %ext
89  ret i64 %sub
90}
91
92define i64 @mul_select_zext(i1 %c, i64 %arg) {
93; CHECK-LABEL: define i64 @mul_select_zext
94; CHECK-SAME: (i1 [[C:%.*]], i64 [[ARG:%.*]]) {
95; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[C]], i64 [[ARG]], i64 0
96; CHECK-NEXT:    ret i64 [[MUL]]
97;
98  %sel = select i1 %c, i64 %arg, i64 1
99  %ext = zext i1 %c to i64
100  %mul = mul i64 %sel, %ext
101  ret i64 %mul
102}
103
104define i64 @mul_select_sext(i1 %c) {
105; CHECK-LABEL: define i64 @mul_select_sext
106; CHECK-SAME: (i1 [[C:%.*]]) {
107; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[C]], i64 -64, i64 0
108; CHECK-NEXT:    ret i64 [[MUL]]
109;
110  %sel = select i1 %c, i64 64, i64 1
111  %ext = sext i1 %c to i64
112  %mul = mul i64 %sel, %ext
113  ret i64 %mul
114}
115
116define i64 @select_zext_different_condition(i1 %c, i1 %d) {
117; CHECK-LABEL: define i64 @select_zext_different_condition
118; CHECK-SAME: (i1 [[C:%.*]], i1 [[D:%.*]]) {
119; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C]], i64 64, i64 1
120; CHECK-NEXT:    [[EXT:%.*]] = zext i1 [[D]] to i64
121; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i64 [[SEL]], [[EXT]]
122; CHECK-NEXT:    ret i64 [[ADD]]
123;
124  %sel = select i1 %c, i64 64, i64 1
125  %ext = zext i1 %d to i64
126  %add = add i64 %sel, %ext
127  ret i64 %add
128}
129
130define <2 x i64> @vector_test(i1 %c) {
131; CHECK-LABEL: define <2 x i64> @vector_test
132; CHECK-SAME: (i1 [[C:%.*]]) {
133; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C]], <2 x i64> splat (i64 64), <2 x i64> splat (i64 1)
134; CHECK-NEXT:    [[EXT:%.*]] = zext i1 [[C]] to i64
135; CHECK-NEXT:    [[VEC0:%.*]] = insertelement <2 x i64> poison, i64 [[EXT]], i64 0
136; CHECK-NEXT:    [[VEC1:%.*]] = shufflevector <2 x i64> [[VEC0]], <2 x i64> poison, <2 x i32> zeroinitializer
137; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw <2 x i64> [[SEL]], [[VEC1]]
138; CHECK-NEXT:    ret <2 x i64> [[ADD]]
139;
140  %sel = select i1 %c, <2 x i64> <i64 64, i64 64>, <2 x i64> <i64 1, i64 1>
141  %ext = zext i1 %c to i64
142  %vec0 = insertelement <2 x i64> undef, i64 %ext, i32 0
143  %vec1 = insertelement <2 x i64> %vec0, i64 %ext, i32 1
144  %add = add <2 x i64> %sel, %vec1
145  ret <2 x i64> %add
146}
147
148define i64 @multiuse_add(i1 %c) {
149; CHECK-LABEL: define i64 @multiuse_add
150; CHECK-SAME: (i1 [[C:%.*]]) {
151; CHECK-NEXT:    [[ADD2:%.*]] = select i1 [[C]], i64 66, i64 2
152; CHECK-NEXT:    ret i64 [[ADD2]]
153;
154  %sel = select i1 %c, i64 64, i64 1
155  %ext = zext i1 %c to i64
156  %add = add i64 %sel, %ext
157  %add2 = add i64 %add, 1
158  ret i64 %add2
159}
160
161define i64 @multiuse_select(i1 %c) {
162; CHECK-LABEL: define i64 @multiuse_select
163; CHECK-SAME: (i1 [[C:%.*]]) {
164; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[C]], i64 4032, i64 0
165; CHECK-NEXT:    ret i64 [[MUL]]
166;
167  %sel = select i1 %c, i64 64, i64 0
168  %ext = zext i1 %c to i64
169  %add = sub i64 %sel, %ext
170  %mul = mul i64 %sel, %add
171  ret i64 %mul
172}
173
174define i64 @select_non_const_sides(i1 %c, i64 %arg1, i64 %arg2) {
175; CHECK-LABEL: define i64 @select_non_const_sides
176; CHECK-SAME: (i1 [[C:%.*]], i64 [[ARG1:%.*]], i64 [[ARG2:%.*]]) {
177; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[ARG1]], -1
178; CHECK-NEXT:    [[SUB:%.*]] = select i1 [[C]], i64 [[TMP1]], i64 [[ARG2]]
179; CHECK-NEXT:    ret i64 [[SUB]]
180;
181  %ext = zext i1 %c to i64
182  %sel = select i1 %c, i64 %arg1, i64 %arg2
183  %sub = sub i64 %sel, %ext
184  ret i64 %sub
185}
186
187define i6 @sub_select_sext_op_swapped_non_const_args(i1 %c, i6 %argT, i6 %argF) {
188; CHECK-LABEL: define i6 @sub_select_sext_op_swapped_non_const_args
189; CHECK-SAME: (i1 [[C:%.*]], i6 [[ARGT:%.*]], i6 [[ARGF:%.*]]) {
190; CHECK-NEXT:    [[TMP1:%.*]] = xor i6 [[ARGT]], -1
191; CHECK-NEXT:    [[TMP2:%.*]] = sub i6 0, [[ARGF]]
192; CHECK-NEXT:    [[SUB:%.*]] = select i1 [[C]], i6 [[TMP1]], i6 [[TMP2]]
193; CHECK-NEXT:    ret i6 [[SUB]]
194;
195  %sel = select i1 %c, i6 %argT, i6 %argF
196  %ext = sext i1 %c to i6
197  %sub = sub i6 %ext, %sel
198  ret i6 %sub
199}
200
201define i6 @sub_select_zext_op_swapped_non_const_args(i1 %c, i6 %argT, i6 %argF) {
202; CHECK-LABEL: define i6 @sub_select_zext_op_swapped_non_const_args
203; CHECK-SAME: (i1 [[C:%.*]], i6 [[ARGT:%.*]], i6 [[ARGF:%.*]]) {
204; CHECK-NEXT:    [[TMP1:%.*]] = sub i6 1, [[ARGT]]
205; CHECK-NEXT:    [[TMP2:%.*]] = sub i6 0, [[ARGF]]
206; CHECK-NEXT:    [[SUB:%.*]] = select i1 [[C]], i6 [[TMP1]], i6 [[TMP2]]
207; CHECK-NEXT:    ret i6 [[SUB]]
208;
209  %sel = select i1 %c, i6 %argT, i6 %argF
210  %ext = zext i1 %c to i6
211  %sub = sub i6 %ext, %sel
212  ret i6 %sub
213}
214
215define <2 x i8> @vectorized_add(<2 x i1> %c, <2 x i8> %arg) {
216; CHECK-LABEL: define <2 x i8> @vectorized_add
217; CHECK-SAME: (<2 x i1> [[C:%.*]], <2 x i8> [[ARG:%.*]]) {
218; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[ARG]], splat (i8 1)
219; CHECK-NEXT:    [[ADD:%.*]] = select <2 x i1> [[C]], <2 x i8> [[TMP1]], <2 x i8> splat (i8 1)
220; CHECK-NEXT:    ret <2 x i8> [[ADD]]
221;
222  %zext = zext <2 x i1> %c to <2 x i8>
223  %sel = select <2 x i1> %c, <2 x i8> %arg, <2 x i8> <i8 1, i8 1>
224  %add = add <2 x i8> %sel, %zext
225  ret <2 x i8> %add
226}
227
228@b = external global [72 x i32]
229@c = external global i32
230
231define i64 @pr64669(i64 %a) {
232; CHECK-LABEL: define i64 @pr64669
233; CHECK-SAME: (i64 [[A:%.*]]) {
234; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq ptr getelementptr inbounds nuw (i8, ptr @b, i64 100), @c
235; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[A]], 1
236; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[CMP_NOT]], i64 0, i64 [[TMP1]]
237; CHECK-NEXT:    ret i64 [[ADD]]
238;
239  %cmp = icmp ne ptr getelementptr inbounds ([72 x i32], ptr @b, i64 0, i64 25), @c
240  %mul = select i1 %cmp, i64 %a, i64 0
241  %conv3 = zext i1 %cmp to i64
242  %add = add nsw i64 %mul, %conv3
243  ret i64 %add
244}
245