1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2 ; RUN: opt < %s -instcombine -S | FileCheck %s 3 4 ; Widen a select of constants to eliminate an extend. 5 6 define i16 @sel_sext_constants(i1 %cmp) { 7 ; CHECK-LABEL: @sel_sext_constants( 8 ; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i16 -1, i16 42 9 ; CHECK-NEXT: ret i16 [[EXT]] 10 ; 11 %sel = select i1 %cmp, i8 255, i8 42 12 %ext = sext i8 %sel to i16 13 ret i16 %ext 14 } 15 16 define i16 @sel_zext_constants(i1 %cmp) { 17 ; CHECK-LABEL: @sel_zext_constants( 18 ; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i16 255, i16 42 19 ; CHECK-NEXT: ret i16 [[EXT]] 20 ; 21 %sel = select i1 %cmp, i8 255, i8 42 22 %ext = zext i8 %sel to i16 23 ret i16 %ext 24 } 25 26 define double @sel_fpext_constants(i1 %cmp) { 27 ; CHECK-LABEL: @sel_fpext_constants( 28 ; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, double -2.550000e+02, double 4.200000e+01 29 ; CHECK-NEXT: ret double [[EXT]] 30 ; 31 %sel = select i1 %cmp, float -255.0, float 42.0 32 %ext = fpext float %sel to double 33 ret double %ext 34 } 35 36 ; FIXME: We should not grow the size of the select in the next 4 cases. 37 38 define i64 @sel_sext(i32 %a, i1 %cmp) { 39 ; CHECK-LABEL: @sel_sext( 40 ; CHECK-NEXT: [[TMP1:%.*]] = sext i32 %a to i64 41 ; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i64 [[TMP1]], i64 42 42 ; CHECK-NEXT: ret i64 [[EXT]] 43 ; 44 %sel = select i1 %cmp, i32 %a, i32 42 45 %ext = sext i32 %sel to i64 46 ret i64 %ext 47 } 48 49 define <4 x i64> @sel_sext_vec(<4 x i32> %a, <4 x i1> %cmp) { 50 ; CHECK-LABEL: @sel_sext_vec( 51 ; CHECK-NEXT: [[TMP1:%.*]] = sext <4 x i32> %a to <4 x i64> 52 ; CHECK-NEXT: [[EXT:%.*]] = select <4 x i1> %cmp, <4 x i64> [[TMP1]], <4 x i64> <i64 42, i64 42, i64 42, i64 42> 53 ; CHECK-NEXT: ret <4 x i64> [[EXT]] 54 ; 55 %sel = select <4 x i1> %cmp, <4 x i32> %a, <4 x i32> <i32 42, i32 42, i32 42, i32 42> 56 %ext = sext <4 x i32> %sel to <4 x i64> 57 ret <4 x i64> %ext 58 } 59 60 define i64 @sel_zext(i32 %a, i1 %cmp) { 61 ; CHECK-LABEL: @sel_zext( 62 ; CHECK-NEXT: [[TMP1:%.*]] = zext i32 %a to i64 63 ; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i64 [[TMP1]], i64 42 64 ; CHECK-NEXT: ret i64 [[EXT]] 65 ; 66 %sel = select i1 %cmp, i32 %a, i32 42 67 %ext = zext i32 %sel to i64 68 ret i64 %ext 69 } 70 71 define <4 x i64> @sel_zext_vec(<4 x i32> %a, <4 x i1> %cmp) { 72 ; CHECK-LABEL: @sel_zext_vec( 73 ; CHECK-NEXT: [[TMP1:%.*]] = zext <4 x i32> %a to <4 x i64> 74 ; CHECK-NEXT: [[EXT:%.*]] = select <4 x i1> %cmp, <4 x i64> [[TMP1]], <4 x i64> <i64 42, i64 42, i64 42, i64 42> 75 ; CHECK-NEXT: ret <4 x i64> [[EXT]] 76 ; 77 %sel = select <4 x i1> %cmp, <4 x i32> %a, <4 x i32> <i32 42, i32 42, i32 42, i32 42> 78 %ext = zext <4 x i32> %sel to <4 x i64> 79 ret <4 x i64> %ext 80 } 81 82 ; FIXME: The next 18 tests cycle through trunc+select and {larger,smaller,equal} {sext,zext,fpext} {scalar,vector}. 83 ; The only cases where we eliminate an instruction are equal zext with scalar/vector, so that's probably the only 84 ; way to justify widening the select. 85 86 define i64 @trunc_sel_larger_sext(i32 %a, i1 %cmp) { 87 ; CHECK-LABEL: @trunc_sel_larger_sext( 88 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 %a to i16 89 ; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[TRUNC]] to i64 90 ; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i64 [[TMP1]], i64 42 91 ; CHECK-NEXT: ret i64 [[EXT]] 92 ; 93 %trunc = trunc i32 %a to i16 94 %sel = select i1 %cmp, i16 %trunc, i16 42 95 %ext = sext i16 %sel to i64 96 ret i64 %ext 97 } 98 99 define <2 x i64> @trunc_sel_larger_sext_vec(<2 x i32> %a, <2 x i1> %cmp) { 100 ; CHECK-LABEL: @trunc_sel_larger_sext_vec( 101 ; CHECK-NEXT: [[TRUNC:%.*]] = zext <2 x i32> %a to <2 x i64> 102 ; CHECK-NEXT: [[SEXT:%.*]] = shl <2 x i64> [[TRUNC]], <i64 48, i64 48> 103 ; CHECK-NEXT: [[TMP1:%.*]] = ashr exact <2 x i64> [[SEXT]], <i64 48, i64 48> 104 ; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x i64> [[TMP1]], <2 x i64> <i64 42, i64 43> 105 ; CHECK-NEXT: ret <2 x i64> [[EXT]] 106 ; 107 %trunc = trunc <2 x i32> %a to <2 x i16> 108 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 109 %ext = sext <2 x i16> %sel to <2 x i64> 110 ret <2 x i64> %ext 111 } 112 113 define i32 @trunc_sel_smaller_sext(i64 %a, i1 %cmp) { 114 ; CHECK-LABEL: @trunc_sel_smaller_sext( 115 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 %a to i16 116 ; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[TRUNC]] to i32 117 ; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i32 [[TMP1]], i32 42 118 ; CHECK-NEXT: ret i32 [[EXT]] 119 ; 120 %trunc = trunc i64 %a to i16 121 %sel = select i1 %cmp, i16 %trunc, i16 42 122 %ext = sext i16 %sel to i32 123 ret i32 %ext 124 } 125 126 define <2 x i32> @trunc_sel_smaller_sext_vec(<2 x i64> %a, <2 x i1> %cmp) { 127 ; CHECK-LABEL: @trunc_sel_smaller_sext_vec( 128 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i64> %a to <2 x i32> 129 ; CHECK-NEXT: [[SEXT:%.*]] = shl <2 x i32> [[TRUNC]], <i32 16, i32 16> 130 ; CHECK-NEXT: [[TMP1:%.*]] = ashr exact <2 x i32> [[SEXT]], <i32 16, i32 16> 131 ; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x i32> [[TMP1]], <2 x i32> <i32 42, i32 43> 132 ; CHECK-NEXT: ret <2 x i32> [[EXT]] 133 ; 134 %trunc = trunc <2 x i64> %a to <2 x i16> 135 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 136 %ext = sext <2 x i16> %sel to <2 x i32> 137 ret <2 x i32> %ext 138 } 139 140 define i32 @trunc_sel_equal_sext(i32 %a, i1 %cmp) { 141 ; CHECK-LABEL: @trunc_sel_equal_sext( 142 ; CHECK-NEXT: [[SEXT:%.*]] = shl i32 %a, 16 143 ; CHECK-NEXT: [[TMP1:%.*]] = ashr exact i32 [[SEXT]], 16 144 ; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i32 [[TMP1]], i32 42 145 ; CHECK-NEXT: ret i32 [[EXT]] 146 ; 147 %trunc = trunc i32 %a to i16 148 %sel = select i1 %cmp, i16 %trunc, i16 42 149 %ext = sext i16 %sel to i32 150 ret i32 %ext 151 } 152 153 define <2 x i32> @trunc_sel_equal_sext_vec(<2 x i32> %a, <2 x i1> %cmp) { 154 ; CHECK-LABEL: @trunc_sel_equal_sext_vec( 155 ; CHECK-NEXT: [[SEXT:%.*]] = shl <2 x i32> %a, <i32 16, i32 16> 156 ; CHECK-NEXT: [[TMP1:%.*]] = ashr exact <2 x i32> [[SEXT]], <i32 16, i32 16> 157 ; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x i32> [[TMP1]], <2 x i32> <i32 42, i32 43> 158 ; CHECK-NEXT: ret <2 x i32> [[EXT]] 159 ; 160 %trunc = trunc <2 x i32> %a to <2 x i16> 161 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 162 %ext = sext <2 x i16> %sel to <2 x i32> 163 ret <2 x i32> %ext 164 } 165 166 define i64 @trunc_sel_larger_zext(i32 %a, i1 %cmp) { 167 ; CHECK-LABEL: @trunc_sel_larger_zext( 168 ; CHECK-NEXT: [[TRUNC_MASK:%.*]] = and i32 %a, 65535 169 ; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TRUNC_MASK]] to i64 170 ; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i64 [[TMP1]], i64 42 171 ; CHECK-NEXT: ret i64 [[EXT]] 172 ; 173 %trunc = trunc i32 %a to i16 174 %sel = select i1 %cmp, i16 %trunc, i16 42 175 %ext = zext i16 %sel to i64 176 ret i64 %ext 177 } 178 179 define <2 x i64> @trunc_sel_larger_zext_vec(<2 x i32> %a, <2 x i1> %cmp) { 180 ; CHECK-LABEL: @trunc_sel_larger_zext_vec( 181 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> %a, <i32 65535, i32 65535> 182 ; CHECK-NEXT: [[TMP2:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64> 183 ; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x i64> [[TMP2]], <2 x i64> <i64 42, i64 43> 184 ; CHECK-NEXT: ret <2 x i64> [[EXT]] 185 ; 186 %trunc = trunc <2 x i32> %a to <2 x i16> 187 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 188 %ext = zext <2 x i16> %sel to <2 x i64> 189 ret <2 x i64> %ext 190 } 191 192 define i32 @trunc_sel_smaller_zext(i64 %a, i1 %cmp) { 193 ; CHECK-LABEL: @trunc_sel_smaller_zext( 194 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 %a to i32 195 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 65535 196 ; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i32 [[TMP2]], i32 42 197 ; CHECK-NEXT: ret i32 [[EXT]] 198 ; 199 %trunc = trunc i64 %a to i16 200 %sel = select i1 %cmp, i16 %trunc, i16 42 201 %ext = zext i16 %sel to i32 202 ret i32 %ext 203 } 204 205 define <2 x i32> @trunc_sel_smaller_zext_vec(<2 x i64> %a, <2 x i1> %cmp) { 206 ; CHECK-LABEL: @trunc_sel_smaller_zext_vec( 207 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i64> %a to <2 x i32> 208 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[TRUNC]], <i32 65535, i32 65535> 209 ; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x i32> [[TMP1]], <2 x i32> <i32 42, i32 43> 210 ; CHECK-NEXT: ret <2 x i32> [[EXT]] 211 ; 212 %trunc = trunc <2 x i64> %a to <2 x i16> 213 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 214 %ext = zext <2 x i16> %sel to <2 x i32> 215 ret <2 x i32> %ext 216 } 217 218 define i32 @trunc_sel_equal_zext(i32 %a, i1 %cmp) { 219 ; CHECK-LABEL: @trunc_sel_equal_zext( 220 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 %a, 65535 221 ; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, i32 [[TMP1]], i32 42 222 ; CHECK-NEXT: ret i32 [[EXT]] 223 ; 224 %trunc = trunc i32 %a to i16 225 %sel = select i1 %cmp, i16 %trunc, i16 42 226 %ext = zext i16 %sel to i32 227 ret i32 %ext 228 } 229 230 define <2 x i32> @trunc_sel_equal_zext_vec(<2 x i32> %a, <2 x i1> %cmp) { 231 ; CHECK-LABEL: @trunc_sel_equal_zext_vec( 232 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> %a, <i32 65535, i32 65535> 233 ; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x i32> [[TMP1]], <2 x i32> <i32 42, i32 43> 234 ; CHECK-NEXT: ret <2 x i32> [[EXT]] 235 ; 236 %trunc = trunc <2 x i32> %a to <2 x i16> 237 %sel = select <2 x i1> %cmp, <2 x i16> %trunc, <2 x i16> <i16 42, i16 43> 238 %ext = zext <2 x i16> %sel to <2 x i32> 239 ret <2 x i32> %ext 240 } 241 242 define double @trunc_sel_larger_fpext(float %a, i1 %cmp) { 243 ; CHECK-LABEL: @trunc_sel_larger_fpext( 244 ; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc float %a to half 245 ; CHECK-NEXT: [[TMP1:%.*]] = fpext half [[TRUNC]] to double 246 ; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, double [[TMP1]], double 4.200000e+01 247 ; CHECK-NEXT: ret double [[EXT]] 248 ; 249 %trunc = fptrunc float %a to half 250 %sel = select i1 %cmp, half %trunc, half 42.0 251 %ext = fpext half %sel to double 252 ret double %ext 253 } 254 255 define <2 x double> @trunc_sel_larger_fpext_vec(<2 x float> %a, <2 x i1> %cmp) { 256 ; CHECK-LABEL: @trunc_sel_larger_fpext_vec( 257 ; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc <2 x float> %a to <2 x half> 258 ; CHECK-NEXT: [[TMP1:%.*]] = fpext <2 x half> [[TRUNC]] to <2 x double> 259 ; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x double> [[TMP1]], <2 x double> <double 4.200000e+01, double 4.300000e+01> 260 ; CHECK-NEXT: ret <2 x double> [[EXT]] 261 ; 262 %trunc = fptrunc <2 x float> %a to <2 x half> 263 %sel = select <2 x i1> %cmp, <2 x half> %trunc, <2 x half> <half 42.0, half 43.0> 264 %ext = fpext <2 x half> %sel to <2 x double> 265 ret <2 x double> %ext 266 } 267 268 define float @trunc_sel_smaller_fpext(double %a, i1 %cmp) { 269 ; CHECK-LABEL: @trunc_sel_smaller_fpext( 270 ; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc double %a to half 271 ; CHECK-NEXT: [[TMP1:%.*]] = fpext half [[TRUNC]] to float 272 ; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, float [[TMP1]], float 4.200000e+01 273 ; CHECK-NEXT: ret float [[EXT]] 274 ; 275 %trunc = fptrunc double %a to half 276 %sel = select i1 %cmp, half %trunc, half 42.0 277 %ext = fpext half %sel to float 278 ret float %ext 279 } 280 281 define <2 x float> @trunc_sel_smaller_fpext_vec(<2 x double> %a, <2 x i1> %cmp) { 282 ; CHECK-LABEL: @trunc_sel_smaller_fpext_vec( 283 ; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc <2 x double> %a to <2 x half> 284 ; CHECK-NEXT: [[TMP1:%.*]] = fpext <2 x half> [[TRUNC]] to <2 x float> 285 ; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x float> [[TMP1]], <2 x float> <float 4.200000e+01, float 4.300000e+01> 286 ; CHECK-NEXT: ret <2 x float> [[EXT]] 287 ; 288 %trunc = fptrunc <2 x double> %a to <2 x half> 289 %sel = select <2 x i1> %cmp, <2 x half> %trunc, <2 x half> <half 42.0, half 43.0> 290 %ext = fpext <2 x half> %sel to <2 x float> 291 ret <2 x float> %ext 292 } 293 294 define float @trunc_sel_equal_fpext(float %a, i1 %cmp) { 295 ; CHECK-LABEL: @trunc_sel_equal_fpext( 296 ; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc float %a to half 297 ; CHECK-NEXT: [[TMP1:%.*]] = fpext half [[TRUNC]] to float 298 ; CHECK-NEXT: [[EXT:%.*]] = select i1 %cmp, float [[TMP1]], float 4.200000e+01 299 ; CHECK-NEXT: ret float [[EXT]] 300 ; 301 %trunc = fptrunc float %a to half 302 %sel = select i1 %cmp, half %trunc, half 42.0 303 %ext = fpext half %sel to float 304 ret float %ext 305 } 306 307 define <2 x float> @trunc_sel_equal_fpext_vec(<2 x float> %a, <2 x i1> %cmp) { 308 ; CHECK-LABEL: @trunc_sel_equal_fpext_vec( 309 ; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc <2 x float> %a to <2 x half> 310 ; CHECK-NEXT: [[TMP1:%.*]] = fpext <2 x half> [[TRUNC]] to <2 x float> 311 ; CHECK-NEXT: [[EXT:%.*]] = select <2 x i1> %cmp, <2 x float> [[TMP1]], <2 x float> <float 4.200000e+01, float 4.300000e+01> 312 ; CHECK-NEXT: ret <2 x float> [[EXT]] 313 ; 314 %trunc = fptrunc <2 x float> %a to <2 x half> 315 %sel = select <2 x i1> %cmp, <2 x half> %trunc, <2 x half> <half 42.0, half 43.0> 316 %ext = fpext <2 x half> %sel to <2 x float> 317 ret <2 x float> %ext 318 } 319 320 define i32 @test_sext1(i1 %cca, i1 %ccb) { 321 ; CHECK-LABEL: @test_sext1( 322 ; CHECK-NEXT: [[FOLD_R:%.*]] = and i1 %ccb, %cca 323 ; CHECK-NEXT: [[R:%.*]] = sext i1 [[FOLD_R]] to i32 324 ; CHECK-NEXT: ret i32 [[R]] 325 ; 326 %ccax = sext i1 %cca to i32 327 %r = select i1 %ccb, i32 %ccax, i32 0 328 ret i32 %r 329 } 330 331 define i32 @test_sext2(i1 %cca, i1 %ccb) { 332 ; CHECK-LABEL: @test_sext2( 333 ; CHECK-NEXT: [[FOLD_R:%.*]] = or i1 %ccb, %cca 334 ; CHECK-NEXT: [[R:%.*]] = sext i1 [[FOLD_R]] to i32 335 ; CHECK-NEXT: ret i32 [[R]] 336 ; 337 %ccax = sext i1 %cca to i32 338 %r = select i1 %ccb, i32 -1, i32 %ccax 339 ret i32 %r 340 } 341 342 define i32 @test_sext3(i1 %cca, i1 %ccb) { 343 ; CHECK-LABEL: @test_sext3( 344 ; CHECK-NEXT: [[NOT_CCB:%.*]] = xor i1 %ccb, true 345 ; CHECK-NEXT: [[FOLD_R:%.*]] = and i1 [[NOT_CCB]], %cca 346 ; CHECK-NEXT: [[R:%.*]] = sext i1 [[FOLD_R]] to i32 347 ; CHECK-NEXT: ret i32 [[R]] 348 ; 349 %ccax = sext i1 %cca to i32 350 %r = select i1 %ccb, i32 0, i32 %ccax 351 ret i32 %r 352 } 353 354 define i32 @test_sext4(i1 %cca, i1 %ccb) { 355 ; CHECK-LABEL: @test_sext4( 356 ; CHECK-NEXT: [[NOT_CCB:%.*]] = xor i1 %ccb, true 357 ; CHECK-NEXT: [[FOLD_R:%.*]] = or i1 [[NOT_CCB]], %cca 358 ; CHECK-NEXT: [[R:%.*]] = sext i1 [[FOLD_R]] to i32 359 ; CHECK-NEXT: ret i32 [[R]] 360 ; 361 %ccax = sext i1 %cca to i32 362 %r = select i1 %ccb, i32 %ccax, i32 -1 363 ret i32 %r 364 } 365 366 define i32 @test_zext1(i1 %cca, i1 %ccb) { 367 ; CHECK-LABEL: @test_zext1( 368 ; CHECK-NEXT: [[FOLD_R:%.*]] = and i1 %ccb, %cca 369 ; CHECK-NEXT: [[R:%.*]] = zext i1 [[FOLD_R]] to i32 370 ; CHECK-NEXT: ret i32 [[R]] 371 ; 372 %ccax = zext i1 %cca to i32 373 %r = select i1 %ccb, i32 %ccax, i32 0 374 ret i32 %r 375 } 376 377 define i32 @test_zext2(i1 %cca, i1 %ccb) { 378 ; CHECK-LABEL: @test_zext2( 379 ; CHECK-NEXT: [[FOLD_R:%.*]] = or i1 %ccb, %cca 380 ; CHECK-NEXT: [[R:%.*]] = zext i1 [[FOLD_R]] to i32 381 ; CHECK-NEXT: ret i32 [[R]] 382 ; 383 %ccax = zext i1 %cca to i32 384 %r = select i1 %ccb, i32 1, i32 %ccax 385 ret i32 %r 386 } 387 388 define i32 @test_zext3(i1 %cca, i1 %ccb) { 389 ; CHECK-LABEL: @test_zext3( 390 ; CHECK-NEXT: [[NOT_CCB:%.*]] = xor i1 %ccb, true 391 ; CHECK-NEXT: [[FOLD_R:%.*]] = and i1 [[NOT_CCB]], %cca 392 ; CHECK-NEXT: [[R:%.*]] = zext i1 [[FOLD_R]] to i32 393 ; CHECK-NEXT: ret i32 [[R]] 394 ; 395 %ccax = zext i1 %cca to i32 396 %r = select i1 %ccb, i32 0, i32 %ccax 397 ret i32 %r 398 } 399 400 define i32 @test_zext4(i1 %cca, i1 %ccb) { 401 ; CHECK-LABEL: @test_zext4( 402 ; CHECK-NEXT: [[NOT_CCB:%.*]] = xor i1 %ccb, true 403 ; CHECK-NEXT: [[FOLD_R:%.*]] = or i1 [[NOT_CCB]], %cca 404 ; CHECK-NEXT: [[R:%.*]] = zext i1 [[FOLD_R]] to i32 405 ; CHECK-NEXT: ret i32 [[R]] 406 ; 407 %ccax = zext i1 %cca to i32 408 %r = select i1 %ccb, i32 %ccax, i32 1 409 ret i32 %r 410 } 411 412 define i32 @test_negative_sext(i1 %a, i1 %cc) { 413 ; CHECK-LABEL: @test_negative_sext( 414 ; CHECK-NEXT: [[A_EXT:%.*]] = sext i1 %a to i32 415 ; CHECK-NEXT: [[R:%.*]] = select i1 %cc, i32 [[A_EXT]], i32 1 416 ; CHECK-NEXT: ret i32 [[R]] 417 ; 418 %a.ext = sext i1 %a to i32 419 %r = select i1 %cc, i32 %a.ext, i32 1 420 ret i32 %r 421 } 422 423 define i32 @test_negative_zext(i1 %a, i1 %cc) { 424 ; CHECK-LABEL: @test_negative_zext( 425 ; CHECK-NEXT: [[A_EXT:%.*]] = zext i1 %a to i32 426 ; CHECK-NEXT: [[R:%.*]] = select i1 %cc, i32 [[A_EXT]], i32 -1 427 ; CHECK-NEXT: ret i32 [[R]] 428 ; 429 %a.ext = zext i1 %a to i32 430 %r = select i1 %cc, i32 %a.ext, i32 -1 431 ret i32 %r 432 } 433 434 define i32 @test_bits_sext(i8 %a, i1 %cc) { 435 ; CHECK-LABEL: @test_bits_sext( 436 ; CHECK-NEXT: [[A_EXT:%.*]] = sext i8 %a to i32 437 ; CHECK-NEXT: [[R:%.*]] = select i1 %cc, i32 [[A_EXT]], i32 -128 438 ; CHECK-NEXT: ret i32 [[R]] 439 ; 440 %a.ext = sext i8 %a to i32 441 %r = select i1 %cc, i32 %a.ext, i32 -128 442 ret i32 %r 443 } 444 445 define i32 @test_bits_zext(i8 %a, i1 %cc) { 446 ; CHECK-LABEL: @test_bits_zext( 447 ; CHECK-NEXT: [[A_EXT:%.*]] = zext i8 %a to i32 448 ; CHECK-NEXT: [[R:%.*]] = select i1 %cc, i32 [[A_EXT]], i32 255 449 ; CHECK-NEXT: ret i32 [[R]] 450 ; 451 %a.ext = zext i8 %a to i32 452 %r = select i1 %cc, i32 %a.ext, i32 255 453 ret i32 %r 454 } 455 456 define i32 @test_op_op(i32 %a, i32 %b, i32 %c) { 457 ; CHECK-LABEL: @test_op_op( 458 ; CHECK-NEXT: [[CCA:%.*]] = icmp sgt i32 %a, 0 459 ; CHECK-NEXT: [[CCB:%.*]] = icmp sgt i32 %b, 0 460 ; CHECK-NEXT: [[CCC:%.*]] = icmp sgt i32 %c, 0 461 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[CCC]], i1 [[CCA]], i1 [[CCB]] 462 ; CHECK-NEXT: [[R:%.*]] = sext i1 [[R:%.*]].v to i32 463 ; CHECK-NEXT: ret i32 [[R]] 464 ; 465 %cca = icmp sgt i32 %a, 0 466 %ccax = sext i1 %cca to i32 467 %ccb = icmp sgt i32 %b, 0 468 %ccbx = sext i1 %ccb to i32 469 %ccc = icmp sgt i32 %c, 0 470 %r = select i1 %ccc, i32 %ccax, i32 %ccbx 471 ret i32 %r 472 } 473 474 define <2 x i32> @test_vectors_sext(<2 x i1> %cca, <2 x i1> %ccb) { 475 ; CHECK-LABEL: @test_vectors_sext( 476 ; CHECK-NEXT: [[FOLD_R:%.*]] = and <2 x i1> %ccb, %cca 477 ; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[FOLD_R]] to <2 x i32> 478 ; CHECK-NEXT: ret <2 x i32> [[R]] 479 ; 480 %ccax = sext <2 x i1> %cca to <2 x i32> 481 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 482 ret <2 x i32> %r 483 } 484 485 define <2 x i32> @test_vectors_sext_nonsplat(<2 x i1> %cca, <2 x i1> %ccb) { 486 ; CHECK-LABEL: @test_vectors_sext_nonsplat( 487 ; CHECK-NEXT: [[NARROW:%.*]] = select <2 x i1> %ccb, <2 x i1> %cca, <2 x i1> <i1 false, i1 true> 488 ; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[NARROW]] to <2 x i32> 489 ; CHECK-NEXT: ret <2 x i32> [[R]] 490 ; 491 %ccax = sext <2 x i1> %cca to <2 x i32> 492 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 -1> 493 ret <2 x i32> %r 494 } 495 496 define <2 x i32> @test_vectors_zext(<2 x i1> %cca, <2 x i1> %ccb) { 497 ; CHECK-LABEL: @test_vectors_zext( 498 ; CHECK-NEXT: [[FOLD_R:%.*]] = and <2 x i1> %ccb, %cca 499 ; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[FOLD_R]] to <2 x i32> 500 ; CHECK-NEXT: ret <2 x i32> [[R]] 501 ; 502 %ccax = zext <2 x i1> %cca to <2 x i32> 503 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 504 ret <2 x i32> %r 505 } 506 507 define <2 x i32> @test_vectors_zext_nonsplat(<2 x i1> %cca, <2 x i1> %ccb) { 508 ; CHECK-LABEL: @test_vectors_zext_nonsplat( 509 ; CHECK-NEXT: [[NARROW:%.*]] = select <2 x i1> %ccb, <2 x i1> %cca, <2 x i1> <i1 true, i1 false> 510 ; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[NARROW]] to <2 x i32> 511 ; CHECK-NEXT: ret <2 x i32> [[R]] 512 ; 513 %ccax = zext <2 x i1> %cca to <2 x i32> 514 %r = select <2 x i1> %ccb, <2 x i32> %ccax, <2 x i32> <i32 1, i32 0> 515 ret <2 x i32> %r 516 } 517 518 define <2 x i32> @scalar_select_of_vectors_sext(<2 x i1> %cca, i1 %ccb) { 519 ; CHECK-LABEL: @scalar_select_of_vectors_sext( 520 ; CHECK-NEXT: [[FOLD_R:%.*]] = select i1 %ccb, <2 x i1> %cca, <2 x i1> zeroinitializer 521 ; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[FOLD_R]] to <2 x i32> 522 ; CHECK-NEXT: ret <2 x i32> [[R]] 523 ; 524 %ccax = sext <2 x i1> %cca to <2 x i32> 525 %r = select i1 %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 526 ret <2 x i32> %r 527 } 528 529 define <2 x i32> @scalar_select_of_vectors_zext(<2 x i1> %cca, i1 %ccb) { 530 ; CHECK-LABEL: @scalar_select_of_vectors_zext( 531 ; CHECK-NEXT: [[FOLD_R:%.*]] = select i1 %ccb, <2 x i1> %cca, <2 x i1> zeroinitializer 532 ; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[FOLD_R]] to <2 x i32> 533 ; CHECK-NEXT: ret <2 x i32> [[R]] 534 ; 535 %ccax = zext <2 x i1> %cca to <2 x i32> 536 %r = select i1 %ccb, <2 x i32> %ccax, <2 x i32> <i32 0, i32 0> 537 ret <2 x i32> %r 538 } 539 540 define i32 @sext_true_val_must_be_all_ones(i1 %x) { 541 ; CHECK-LABEL: @sext_true_val_must_be_all_ones( 542 ; CHECK-NEXT: [[SEL:%.*]] = select i1 %x, i32 -1, i32 42, !prof !0 543 ; CHECK-NEXT: ret i32 [[SEL]] 544 ; 545 %ext = sext i1 %x to i32 546 %sel = select i1 %x, i32 %ext, i32 42, !prof !0 547 ret i32 %sel 548 } 549 550 define <2 x i32> @sext_true_val_must_be_all_ones_vec(<2 x i1> %x) { 551 ; CHECK-LABEL: @sext_true_val_must_be_all_ones_vec( 552 ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> %x, <2 x i32> <i32 -1, i32 -1>, <2 x i32> <i32 42, i32 12>, !prof !0 553 ; CHECK-NEXT: ret <2 x i32> [[SEL]] 554 ; 555 %ext = sext <2 x i1> %x to <2 x i32> 556 %sel = select <2 x i1> %x, <2 x i32> %ext, <2 x i32> <i32 42, i32 12>, !prof !0 557 ret <2 x i32> %sel 558 } 559 560 define i32 @zext_true_val_must_be_one(i1 %x) { 561 ; CHECK-LABEL: @zext_true_val_must_be_one( 562 ; CHECK-NEXT: [[SEL:%.*]] = select i1 %x, i32 1, i32 42, !prof !0 563 ; CHECK-NEXT: ret i32 [[SEL]] 564 ; 565 %ext = zext i1 %x to i32 566 %sel = select i1 %x, i32 %ext, i32 42, !prof !0 567 ret i32 %sel 568 } 569 570 define <2 x i32> @zext_true_val_must_be_one_vec(<2 x i1> %x) { 571 ; CHECK-LABEL: @zext_true_val_must_be_one_vec( 572 ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> %x, <2 x i32> <i32 1, i32 1>, <2 x i32> <i32 42, i32 12>, !prof !0 573 ; CHECK-NEXT: ret <2 x i32> [[SEL]] 574 ; 575 %ext = zext <2 x i1> %x to <2 x i32> 576 %sel = select <2 x i1> %x, <2 x i32> %ext, <2 x i32> <i32 42, i32 12>, !prof !0 577 ret <2 x i32> %sel 578 } 579 580 define i32 @sext_false_val_must_be_zero(i1 %x) { 581 ; CHECK-LABEL: @sext_false_val_must_be_zero( 582 ; CHECK-NEXT: [[SEL:%.*]] = select i1 %x, i32 42, i32 0, !prof !0 583 ; CHECK-NEXT: ret i32 [[SEL]] 584 ; 585 %ext = sext i1 %x to i32 586 %sel = select i1 %x, i32 42, i32 %ext, !prof !0 587 ret i32 %sel 588 } 589 590 define <2 x i32> @sext_false_val_must_be_zero_vec(<2 x i1> %x) { 591 ; CHECK-LABEL: @sext_false_val_must_be_zero_vec( 592 ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> %x, <2 x i32> <i32 42, i32 12>, <2 x i32> zeroinitializer, !prof !0 593 ; CHECK-NEXT: ret <2 x i32> [[SEL]] 594 ; 595 %ext = sext <2 x i1> %x to <2 x i32> 596 %sel = select <2 x i1> %x, <2 x i32> <i32 42, i32 12>, <2 x i32> %ext, !prof !0 597 ret <2 x i32> %sel 598 } 599 600 define i32 @zext_false_val_must_be_zero(i1 %x) { 601 ; CHECK-LABEL: @zext_false_val_must_be_zero( 602 ; CHECK-NEXT: [[SEL:%.*]] = select i1 %x, i32 42, i32 0, !prof !0 603 ; CHECK-NEXT: ret i32 [[SEL]] 604 ; 605 %ext = zext i1 %x to i32 606 %sel = select i1 %x, i32 42, i32 %ext, !prof !0 607 ret i32 %sel 608 } 609 610 define <2 x i32> @zext_false_val_must_be_zero_vec(<2 x i1> %x) { 611 ; CHECK-LABEL: @zext_false_val_must_be_zero_vec( 612 ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> %x, <2 x i32> <i32 42, i32 12>, <2 x i32> zeroinitializer, !prof !0 613 ; CHECK-NEXT: ret <2 x i32> [[SEL]] 614 ; 615 %ext = zext <2 x i1> %x to <2 x i32> 616 %sel = select <2 x i1> %x, <2 x i32> <i32 42, i32 12>, <2 x i32> %ext, !prof !0 617 ret <2 x i32> %sel 618 } 619 620 !0 = !{!"branch_weights", i32 3, i32 5} 621 622