1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2 ; RUN: llc < %s -mtriple=x86_64-apple-darwin10 | FileCheck %s --check-prefix=CHECK --check-prefix=NOAVX --check-prefix=SDAG 3 ; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -fast-isel -fast-isel-abort=1 | FileCheck %s --check-prefix=CHECK --check-prefix=NOAVX --check-prefix=FAST 4 ; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -fast-isel -fast-isel-abort=1 -mattr=avx | FileCheck %s --check-prefix=CHECK --check-prefix=FAST_AVX 5 ; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -fast-isel -fast-isel-abort=1 -mattr=avx512f | FileCheck %s --check-prefix=CHECK --check-prefix=FAST_AVX 6 7 ; Test all the cmp predicates that can feed an integer conditional move. 8 9 define i64 @select_fcmp_false_cmov(double %a, double %b, i64 %c, i64 %d) { 10 ; CHECK-LABEL: select_fcmp_false_cmov: 11 ; CHECK: ## %bb.0: 12 ; CHECK-NEXT: movq %rsi, %rax 13 ; CHECK-NEXT: retq 14 %1 = fcmp false double %a, %b 15 %2 = select i1 %1, i64 %c, i64 %d 16 ret i64 %2 17 } 18 19 define i64 @select_fcmp_oeq_cmov(double %a, double %b, i64 %c, i64 %d) { 20 ; SDAG-LABEL: select_fcmp_oeq_cmov: 21 ; SDAG: ## %bb.0: 22 ; SDAG-NEXT: ucomisd %xmm1, %xmm0 23 ; SDAG-NEXT: cmovneq %rsi, %rdi 24 ; SDAG-NEXT: cmovpq %rsi, %rdi 25 ; SDAG-NEXT: movq %rdi, %rax 26 ; SDAG-NEXT: retq 27 ; 28 ; FAST-LABEL: select_fcmp_oeq_cmov: 29 ; FAST: ## %bb.0: 30 ; FAST-NEXT: ucomisd %xmm1, %xmm0 31 ; FAST-NEXT: setnp %al 32 ; FAST-NEXT: sete %cl 33 ; FAST-NEXT: testb %al, %cl 34 ; FAST-NEXT: cmoveq %rsi, %rdi 35 ; FAST-NEXT: movq %rdi, %rax 36 ; FAST-NEXT: retq 37 ; 38 ; FAST_AVX-LABEL: select_fcmp_oeq_cmov: 39 ; FAST_AVX: ## %bb.0: 40 ; FAST_AVX-NEXT: vucomisd %xmm1, %xmm0 41 ; FAST_AVX-NEXT: setnp %al 42 ; FAST_AVX-NEXT: sete %cl 43 ; FAST_AVX-NEXT: testb %al, %cl 44 ; FAST_AVX-NEXT: cmoveq %rsi, %rdi 45 ; FAST_AVX-NEXT: movq %rdi, %rax 46 ; FAST_AVX-NEXT: retq 47 %1 = fcmp oeq double %a, %b 48 %2 = select i1 %1, i64 %c, i64 %d 49 ret i64 %2 50 } 51 52 define i64 @select_fcmp_ogt_cmov(double %a, double %b, i64 %c, i64 %d) { 53 ; NOAVX-LABEL: select_fcmp_ogt_cmov: 54 ; NOAVX: ## %bb.0: 55 ; NOAVX-NEXT: ucomisd %xmm1, %xmm0 56 ; NOAVX-NEXT: cmovbeq %rsi, %rdi 57 ; NOAVX-NEXT: movq %rdi, %rax 58 ; NOAVX-NEXT: retq 59 ; 60 ; FAST_AVX-LABEL: select_fcmp_ogt_cmov: 61 ; FAST_AVX: ## %bb.0: 62 ; FAST_AVX-NEXT: vucomisd %xmm1, %xmm0 63 ; FAST_AVX-NEXT: cmovbeq %rsi, %rdi 64 ; FAST_AVX-NEXT: movq %rdi, %rax 65 ; FAST_AVX-NEXT: retq 66 %1 = fcmp ogt double %a, %b 67 %2 = select i1 %1, i64 %c, i64 %d 68 ret i64 %2 69 } 70 71 define i64 @select_fcmp_oge_cmov(double %a, double %b, i64 %c, i64 %d) { 72 ; NOAVX-LABEL: select_fcmp_oge_cmov: 73 ; NOAVX: ## %bb.0: 74 ; NOAVX-NEXT: ucomisd %xmm1, %xmm0 75 ; NOAVX-NEXT: cmovbq %rsi, %rdi 76 ; NOAVX-NEXT: movq %rdi, %rax 77 ; NOAVX-NEXT: retq 78 ; 79 ; FAST_AVX-LABEL: select_fcmp_oge_cmov: 80 ; FAST_AVX: ## %bb.0: 81 ; FAST_AVX-NEXT: vucomisd %xmm1, %xmm0 82 ; FAST_AVX-NEXT: cmovbq %rsi, %rdi 83 ; FAST_AVX-NEXT: movq %rdi, %rax 84 ; FAST_AVX-NEXT: retq 85 %1 = fcmp oge double %a, %b 86 %2 = select i1 %1, i64 %c, i64 %d 87 ret i64 %2 88 } 89 90 define i64 @select_fcmp_olt_cmov(double %a, double %b, i64 %c, i64 %d) { 91 ; NOAVX-LABEL: select_fcmp_olt_cmov: 92 ; NOAVX: ## %bb.0: 93 ; NOAVX-NEXT: ucomisd %xmm0, %xmm1 94 ; NOAVX-NEXT: cmovbeq %rsi, %rdi 95 ; NOAVX-NEXT: movq %rdi, %rax 96 ; NOAVX-NEXT: retq 97 ; 98 ; FAST_AVX-LABEL: select_fcmp_olt_cmov: 99 ; FAST_AVX: ## %bb.0: 100 ; FAST_AVX-NEXT: vucomisd %xmm0, %xmm1 101 ; FAST_AVX-NEXT: cmovbeq %rsi, %rdi 102 ; FAST_AVX-NEXT: movq %rdi, %rax 103 ; FAST_AVX-NEXT: retq 104 %1 = fcmp olt double %a, %b 105 %2 = select i1 %1, i64 %c, i64 %d 106 ret i64 %2 107 } 108 109 define i64 @select_fcmp_ole_cmov(double %a, double %b, i64 %c, i64 %d) { 110 ; NOAVX-LABEL: select_fcmp_ole_cmov: 111 ; NOAVX: ## %bb.0: 112 ; NOAVX-NEXT: ucomisd %xmm0, %xmm1 113 ; NOAVX-NEXT: cmovbq %rsi, %rdi 114 ; NOAVX-NEXT: movq %rdi, %rax 115 ; NOAVX-NEXT: retq 116 ; 117 ; FAST_AVX-LABEL: select_fcmp_ole_cmov: 118 ; FAST_AVX: ## %bb.0: 119 ; FAST_AVX-NEXT: vucomisd %xmm0, %xmm1 120 ; FAST_AVX-NEXT: cmovbq %rsi, %rdi 121 ; FAST_AVX-NEXT: movq %rdi, %rax 122 ; FAST_AVX-NEXT: retq 123 %1 = fcmp ole double %a, %b 124 %2 = select i1 %1, i64 %c, i64 %d 125 ret i64 %2 126 } 127 128 define i64 @select_fcmp_one_cmov(double %a, double %b, i64 %c, i64 %d) { 129 ; NOAVX-LABEL: select_fcmp_one_cmov: 130 ; NOAVX: ## %bb.0: 131 ; NOAVX-NEXT: ucomisd %xmm1, %xmm0 132 ; NOAVX-NEXT: cmoveq %rsi, %rdi 133 ; NOAVX-NEXT: movq %rdi, %rax 134 ; NOAVX-NEXT: retq 135 ; 136 ; FAST_AVX-LABEL: select_fcmp_one_cmov: 137 ; FAST_AVX: ## %bb.0: 138 ; FAST_AVX-NEXT: vucomisd %xmm1, %xmm0 139 ; FAST_AVX-NEXT: cmoveq %rsi, %rdi 140 ; FAST_AVX-NEXT: movq %rdi, %rax 141 ; FAST_AVX-NEXT: retq 142 %1 = fcmp one double %a, %b 143 %2 = select i1 %1, i64 %c, i64 %d 144 ret i64 %2 145 } 146 147 define i64 @select_fcmp_ord_cmov(double %a, double %b, i64 %c, i64 %d) { 148 ; NOAVX-LABEL: select_fcmp_ord_cmov: 149 ; NOAVX: ## %bb.0: 150 ; NOAVX-NEXT: ucomisd %xmm1, %xmm0 151 ; NOAVX-NEXT: cmovpq %rsi, %rdi 152 ; NOAVX-NEXT: movq %rdi, %rax 153 ; NOAVX-NEXT: retq 154 ; 155 ; FAST_AVX-LABEL: select_fcmp_ord_cmov: 156 ; FAST_AVX: ## %bb.0: 157 ; FAST_AVX-NEXT: vucomisd %xmm1, %xmm0 158 ; FAST_AVX-NEXT: cmovpq %rsi, %rdi 159 ; FAST_AVX-NEXT: movq %rdi, %rax 160 ; FAST_AVX-NEXT: retq 161 %1 = fcmp ord double %a, %b 162 %2 = select i1 %1, i64 %c, i64 %d 163 ret i64 %2 164 } 165 166 define i64 @select_fcmp_uno_cmov(double %a, double %b, i64 %c, i64 %d) { 167 ; NOAVX-LABEL: select_fcmp_uno_cmov: 168 ; NOAVX: ## %bb.0: 169 ; NOAVX-NEXT: ucomisd %xmm1, %xmm0 170 ; NOAVX-NEXT: cmovnpq %rsi, %rdi 171 ; NOAVX-NEXT: movq %rdi, %rax 172 ; NOAVX-NEXT: retq 173 ; 174 ; FAST_AVX-LABEL: select_fcmp_uno_cmov: 175 ; FAST_AVX: ## %bb.0: 176 ; FAST_AVX-NEXT: vucomisd %xmm1, %xmm0 177 ; FAST_AVX-NEXT: cmovnpq %rsi, %rdi 178 ; FAST_AVX-NEXT: movq %rdi, %rax 179 ; FAST_AVX-NEXT: retq 180 %1 = fcmp uno double %a, %b 181 %2 = select i1 %1, i64 %c, i64 %d 182 ret i64 %2 183 } 184 185 define i64 @select_fcmp_ueq_cmov(double %a, double %b, i64 %c, i64 %d) { 186 ; NOAVX-LABEL: select_fcmp_ueq_cmov: 187 ; NOAVX: ## %bb.0: 188 ; NOAVX-NEXT: ucomisd %xmm1, %xmm0 189 ; NOAVX-NEXT: cmovneq %rsi, %rdi 190 ; NOAVX-NEXT: movq %rdi, %rax 191 ; NOAVX-NEXT: retq 192 ; 193 ; FAST_AVX-LABEL: select_fcmp_ueq_cmov: 194 ; FAST_AVX: ## %bb.0: 195 ; FAST_AVX-NEXT: vucomisd %xmm1, %xmm0 196 ; FAST_AVX-NEXT: cmovneq %rsi, %rdi 197 ; FAST_AVX-NEXT: movq %rdi, %rax 198 ; FAST_AVX-NEXT: retq 199 %1 = fcmp ueq double %a, %b 200 %2 = select i1 %1, i64 %c, i64 %d 201 ret i64 %2 202 } 203 204 define i64 @select_fcmp_ugt_cmov(double %a, double %b, i64 %c, i64 %d) { 205 ; NOAVX-LABEL: select_fcmp_ugt_cmov: 206 ; NOAVX: ## %bb.0: 207 ; NOAVX-NEXT: ucomisd %xmm0, %xmm1 208 ; NOAVX-NEXT: cmovaeq %rsi, %rdi 209 ; NOAVX-NEXT: movq %rdi, %rax 210 ; NOAVX-NEXT: retq 211 ; 212 ; FAST_AVX-LABEL: select_fcmp_ugt_cmov: 213 ; FAST_AVX: ## %bb.0: 214 ; FAST_AVX-NEXT: vucomisd %xmm0, %xmm1 215 ; FAST_AVX-NEXT: cmovaeq %rsi, %rdi 216 ; FAST_AVX-NEXT: movq %rdi, %rax 217 ; FAST_AVX-NEXT: retq 218 %1 = fcmp ugt double %a, %b 219 %2 = select i1 %1, i64 %c, i64 %d 220 ret i64 %2 221 } 222 223 define i64 @select_fcmp_uge_cmov(double %a, double %b, i64 %c, i64 %d) { 224 ; NOAVX-LABEL: select_fcmp_uge_cmov: 225 ; NOAVX: ## %bb.0: 226 ; NOAVX-NEXT: ucomisd %xmm0, %xmm1 227 ; NOAVX-NEXT: cmovaq %rsi, %rdi 228 ; NOAVX-NEXT: movq %rdi, %rax 229 ; NOAVX-NEXT: retq 230 ; 231 ; FAST_AVX-LABEL: select_fcmp_uge_cmov: 232 ; FAST_AVX: ## %bb.0: 233 ; FAST_AVX-NEXT: vucomisd %xmm0, %xmm1 234 ; FAST_AVX-NEXT: cmovaq %rsi, %rdi 235 ; FAST_AVX-NEXT: movq %rdi, %rax 236 ; FAST_AVX-NEXT: retq 237 %1 = fcmp uge double %a, %b 238 %2 = select i1 %1, i64 %c, i64 %d 239 ret i64 %2 240 } 241 242 define i64 @select_fcmp_ult_cmov(double %a, double %b, i64 %c, i64 %d) { 243 ; NOAVX-LABEL: select_fcmp_ult_cmov: 244 ; NOAVX: ## %bb.0: 245 ; NOAVX-NEXT: ucomisd %xmm1, %xmm0 246 ; NOAVX-NEXT: cmovaeq %rsi, %rdi 247 ; NOAVX-NEXT: movq %rdi, %rax 248 ; NOAVX-NEXT: retq 249 ; 250 ; FAST_AVX-LABEL: select_fcmp_ult_cmov: 251 ; FAST_AVX: ## %bb.0: 252 ; FAST_AVX-NEXT: vucomisd %xmm1, %xmm0 253 ; FAST_AVX-NEXT: cmovaeq %rsi, %rdi 254 ; FAST_AVX-NEXT: movq %rdi, %rax 255 ; FAST_AVX-NEXT: retq 256 %1 = fcmp ult double %a, %b 257 %2 = select i1 %1, i64 %c, i64 %d 258 ret i64 %2 259 } 260 261 define i64 @select_fcmp_ule_cmov(double %a, double %b, i64 %c, i64 %d) { 262 ; NOAVX-LABEL: select_fcmp_ule_cmov: 263 ; NOAVX: ## %bb.0: 264 ; NOAVX-NEXT: ucomisd %xmm1, %xmm0 265 ; NOAVX-NEXT: cmovaq %rsi, %rdi 266 ; NOAVX-NEXT: movq %rdi, %rax 267 ; NOAVX-NEXT: retq 268 ; 269 ; FAST_AVX-LABEL: select_fcmp_ule_cmov: 270 ; FAST_AVX: ## %bb.0: 271 ; FAST_AVX-NEXT: vucomisd %xmm1, %xmm0 272 ; FAST_AVX-NEXT: cmovaq %rsi, %rdi 273 ; FAST_AVX-NEXT: movq %rdi, %rax 274 ; FAST_AVX-NEXT: retq 275 %1 = fcmp ule double %a, %b 276 %2 = select i1 %1, i64 %c, i64 %d 277 ret i64 %2 278 } 279 280 define i64 @select_fcmp_une_cmov(double %a, double %b, i64 %c, i64 %d) { 281 ; SDAG-LABEL: select_fcmp_une_cmov: 282 ; SDAG: ## %bb.0: 283 ; SDAG-NEXT: ucomisd %xmm1, %xmm0 284 ; SDAG-NEXT: cmovneq %rdi, %rsi 285 ; SDAG-NEXT: cmovpq %rdi, %rsi 286 ; SDAG-NEXT: movq %rsi, %rax 287 ; SDAG-NEXT: retq 288 ; 289 ; FAST-LABEL: select_fcmp_une_cmov: 290 ; FAST: ## %bb.0: 291 ; FAST-NEXT: ucomisd %xmm1, %xmm0 292 ; FAST-NEXT: setp %al 293 ; FAST-NEXT: setne %cl 294 ; FAST-NEXT: orb %al, %cl 295 ; FAST-NEXT: cmoveq %rsi, %rdi 296 ; FAST-NEXT: movq %rdi, %rax 297 ; FAST-NEXT: retq 298 ; 299 ; FAST_AVX-LABEL: select_fcmp_une_cmov: 300 ; FAST_AVX: ## %bb.0: 301 ; FAST_AVX-NEXT: vucomisd %xmm1, %xmm0 302 ; FAST_AVX-NEXT: setp %al 303 ; FAST_AVX-NEXT: setne %cl 304 ; FAST_AVX-NEXT: orb %al, %cl 305 ; FAST_AVX-NEXT: cmoveq %rsi, %rdi 306 ; FAST_AVX-NEXT: movq %rdi, %rax 307 ; FAST_AVX-NEXT: retq 308 %1 = fcmp une double %a, %b 309 %2 = select i1 %1, i64 %c, i64 %d 310 ret i64 %2 311 } 312 313 define i64 @select_fcmp_true_cmov(double %a, double %b, i64 %c, i64 %d) { 314 ; CHECK-LABEL: select_fcmp_true_cmov: 315 ; CHECK: ## %bb.0: 316 ; CHECK-NEXT: movq %rdi, %rax 317 ; CHECK-NEXT: retq 318 %1 = fcmp true double %a, %b 319 %2 = select i1 %1, i64 %c, i64 %d 320 ret i64 %2 321 } 322 323 define i64 @select_icmp_eq_cmov(i64 %a, i64 %b, i64 %c, i64 %d) { 324 ; CHECK-LABEL: select_icmp_eq_cmov: 325 ; CHECK: ## %bb.0: 326 ; CHECK-NEXT: cmpq %rsi, %rdi 327 ; CHECK-NEXT: cmovneq %rcx, %rdx 328 ; CHECK-NEXT: movq %rdx, %rax 329 ; CHECK-NEXT: retq 330 %1 = icmp eq i64 %a, %b 331 %2 = select i1 %1, i64 %c, i64 %d 332 ret i64 %2 333 } 334 335 define i64 @select_icmp_ne_cmov(i64 %a, i64 %b, i64 %c, i64 %d) { 336 ; CHECK-LABEL: select_icmp_ne_cmov: 337 ; CHECK: ## %bb.0: 338 ; CHECK-NEXT: cmpq %rsi, %rdi 339 ; CHECK-NEXT: cmoveq %rcx, %rdx 340 ; CHECK-NEXT: movq %rdx, %rax 341 ; CHECK-NEXT: retq 342 %1 = icmp ne i64 %a, %b 343 %2 = select i1 %1, i64 %c, i64 %d 344 ret i64 %2 345 } 346 347 define i64 @select_icmp_ugt_cmov(i64 %a, i64 %b, i64 %c, i64 %d) { 348 ; CHECK-LABEL: select_icmp_ugt_cmov: 349 ; CHECK: ## %bb.0: 350 ; CHECK-NEXT: cmpq %rsi, %rdi 351 ; CHECK-NEXT: cmovbeq %rcx, %rdx 352 ; CHECK-NEXT: movq %rdx, %rax 353 ; CHECK-NEXT: retq 354 %1 = icmp ugt i64 %a, %b 355 %2 = select i1 %1, i64 %c, i64 %d 356 ret i64 %2 357 } 358 359 360 define i64 @select_icmp_uge_cmov(i64 %a, i64 %b, i64 %c, i64 %d) { 361 ; CHECK-LABEL: select_icmp_uge_cmov: 362 ; CHECK: ## %bb.0: 363 ; CHECK-NEXT: cmpq %rsi, %rdi 364 ; CHECK-NEXT: cmovbq %rcx, %rdx 365 ; CHECK-NEXT: movq %rdx, %rax 366 ; CHECK-NEXT: retq 367 %1 = icmp uge i64 %a, %b 368 %2 = select i1 %1, i64 %c, i64 %d 369 ret i64 %2 370 } 371 372 define i64 @select_icmp_ult_cmov(i64 %a, i64 %b, i64 %c, i64 %d) { 373 ; CHECK-LABEL: select_icmp_ult_cmov: 374 ; CHECK: ## %bb.0: 375 ; CHECK-NEXT: cmpq %rsi, %rdi 376 ; CHECK-NEXT: cmovaeq %rcx, %rdx 377 ; CHECK-NEXT: movq %rdx, %rax 378 ; CHECK-NEXT: retq 379 %1 = icmp ult i64 %a, %b 380 %2 = select i1 %1, i64 %c, i64 %d 381 ret i64 %2 382 } 383 384 define i64 @select_icmp_ule_cmov(i64 %a, i64 %b, i64 %c, i64 %d) { 385 ; CHECK-LABEL: select_icmp_ule_cmov: 386 ; CHECK: ## %bb.0: 387 ; CHECK-NEXT: cmpq %rsi, %rdi 388 ; CHECK-NEXT: cmovaq %rcx, %rdx 389 ; CHECK-NEXT: movq %rdx, %rax 390 ; CHECK-NEXT: retq 391 %1 = icmp ule i64 %a, %b 392 %2 = select i1 %1, i64 %c, i64 %d 393 ret i64 %2 394 } 395 396 define i64 @select_icmp_sgt_cmov(i64 %a, i64 %b, i64 %c, i64 %d) { 397 ; CHECK-LABEL: select_icmp_sgt_cmov: 398 ; CHECK: ## %bb.0: 399 ; CHECK-NEXT: cmpq %rsi, %rdi 400 ; CHECK-NEXT: cmovleq %rcx, %rdx 401 ; CHECK-NEXT: movq %rdx, %rax 402 ; CHECK-NEXT: retq 403 %1 = icmp sgt i64 %a, %b 404 %2 = select i1 %1, i64 %c, i64 %d 405 ret i64 %2 406 } 407 408 define i64 @select_icmp_sge_cmov(i64 %a, i64 %b, i64 %c, i64 %d) { 409 ; CHECK-LABEL: select_icmp_sge_cmov: 410 ; CHECK: ## %bb.0: 411 ; CHECK-NEXT: cmpq %rsi, %rdi 412 ; CHECK-NEXT: cmovlq %rcx, %rdx 413 ; CHECK-NEXT: movq %rdx, %rax 414 ; CHECK-NEXT: retq 415 %1 = icmp sge i64 %a, %b 416 %2 = select i1 %1, i64 %c, i64 %d 417 ret i64 %2 418 } 419 420 define i64 @select_icmp_slt_cmov(i64 %a, i64 %b, i64 %c, i64 %d) { 421 ; CHECK-LABEL: select_icmp_slt_cmov: 422 ; CHECK: ## %bb.0: 423 ; CHECK-NEXT: cmpq %rsi, %rdi 424 ; CHECK-NEXT: cmovgeq %rcx, %rdx 425 ; CHECK-NEXT: movq %rdx, %rax 426 ; CHECK-NEXT: retq 427 %1 = icmp slt i64 %a, %b 428 %2 = select i1 %1, i64 %c, i64 %d 429 ret i64 %2 430 } 431 432 define i64 @select_icmp_sle_cmov(i64 %a, i64 %b, i64 %c, i64 %d) { 433 ; CHECK-LABEL: select_icmp_sle_cmov: 434 ; CHECK: ## %bb.0: 435 ; CHECK-NEXT: cmpq %rsi, %rdi 436 ; CHECK-NEXT: cmovgq %rcx, %rdx 437 ; CHECK-NEXT: movq %rdx, %rax 438 ; CHECK-NEXT: retq 439 %1 = icmp sle i64 %a, %b 440 %2 = select i1 %1, i64 %c, i64 %d 441 ret i64 %2 442 } 443 444