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
4 define 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]]
10 %sel = select i1 %c, i64 64, i64 1
11 %ext = zext i1 %c to i64
12 %add = add i64 %sel, %ext
16 define 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]]
22 %sel = select i1 %c, i64 64, i64 1
23 %ext = sext i1 %c to i64
24 %add = add i64 %sel, %ext
28 define 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]]
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
41 define 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]]
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
54 define 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]]
60 %sel = select i1 %c, i64 64, i64 %arg
61 %ext = sext i1 %c to i64
62 %sub = sub i64 %sel, %ext
66 define 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]]
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
79 define 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]]
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
92 define 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]]
98 %sel = select i1 %c, i64 %arg, i64 1
99 %ext = zext i1 %c to i64
100 %mul = mul i64 %sel, %ext
104 define 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]]
110 %sel = select i1 %c, i64 64, i64 1
111 %ext = sext i1 %c to i64
112 %mul = mul i64 %sel, %ext
116 define 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]]
124 %sel = select i1 %c, i64 64, i64 1
125 %ext = zext i1 %d to i64
126 %add = add i64 %sel, %ext
130 define <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> <i64 64, i64 64>, <2 x i64> <i64 1, 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]]
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
148 define 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]]
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
161 define 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]]
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
174 define 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]]
181 %ext = zext i1 %c to i64
182 %sel = select i1 %c, i64 %arg1, i64 %arg2
183 %sub = sub i64 %sel, %ext
187 define 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]]
195 %sel = select i1 %c, i6 %argT, i6 %argF
196 %ext = sext i1 %c to i6
197 %sub = sub i6 %ext, %sel
201 define 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]]
209 %sel = select i1 %c, i6 %argT, i6 %argF
210 %ext = zext i1 %c to i6
211 %sub = sub i6 %ext, %sel
215 define <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]], <i8 1, i8 1>
219 ; CHECK-NEXT: [[ADD:%.*]] = select <2 x i1> [[C]], <2 x i8> [[TMP1]], <2 x i8> <i8 1, i8 1>
220 ; CHECK-NEXT: ret <2 x i8> [[ADD]]
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
228 @b = external global [72 x i32]
229 @c = external global i32
231 define 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 (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]]
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