1 ; RUN: llc < %s -march=x86-64 -asm-verbose=false -join-physregs -promote-elements | FileCheck %s 2 ; RUN: llc < %s -march=x86-64 -asm-verbose=false -join-physregs -enable-unsafe-fp-math -enable-no-nans-fp-math -promote-elements | FileCheck -check-prefix=UNSAFE %s 3 ; RUN: llc < %s -march=x86-64 -asm-verbose=false -join-physregs -enable-no-nans-fp-math -promote-elements | FileCheck -check-prefix=FINITE %s 4 5 ; Some of these patterns can be matched as SSE min or max. Some of 6 ; then can be matched provided that the operands are swapped. 7 ; Some of them can't be matched at all and require a comparison 8 ; and a conditional branch. 9 10 ; The naming convention is {,x_,y_}{o,u}{gt,lt,ge,le}{,_inverse} 11 ; x_ : use 0.0 instead of %y 12 ; y_ : use -0.0 instead of %y 13 ; _inverse : swap the arms of the select. 14 15 ; Some of these tests depend on -join-physregs commuting instructions to 16 ; eliminate copies. 17 18 ; CHECK: ogt: 19 ; CHECK-NEXT: maxsd %xmm1, %xmm0 20 ; CHECK-NEXT: ret 21 ; UNSAFE: ogt: 22 ; UNSAFE-NEXT: maxsd %xmm1, %xmm0 23 ; UNSAFE-NEXT: ret 24 ; FINITE: ogt: 25 ; FINITE-NEXT: maxsd %xmm1, %xmm0 26 ; FINITE-NEXT: ret 27 define double @ogt(double %x, double %y) nounwind { 28 %c = fcmp ogt double %x, %y 29 %d = select i1 %c, double %x, double %y 30 ret double %d 31 } 32 33 ; CHECK: olt: 34 ; CHECK-NEXT: minsd %xmm1, %xmm0 35 ; CHECK-NEXT: ret 36 ; UNSAFE: olt: 37 ; UNSAFE-NEXT: minsd %xmm1, %xmm0 38 ; UNSAFE-NEXT: ret 39 ; FINITE: olt: 40 ; FINITE-NEXT: minsd %xmm1, %xmm0 41 ; FINITE-NEXT: ret 42 define double @olt(double %x, double %y) nounwind { 43 %c = fcmp olt double %x, %y 44 %d = select i1 %c, double %x, double %y 45 ret double %d 46 } 47 48 ; CHECK: ogt_inverse: 49 ; CHECK-NEXT: minsd %xmm0, %xmm1 50 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 51 ; CHECK-NEXT: ret 52 ; UNSAFE: ogt_inverse: 53 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 54 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 55 ; UNSAFE-NEXT: ret 56 ; FINITE: ogt_inverse: 57 ; FINITE-NEXT: minsd %xmm0, %xmm1 58 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 59 ; FINITE-NEXT: ret 60 define double @ogt_inverse(double %x, double %y) nounwind { 61 %c = fcmp ogt double %x, %y 62 %d = select i1 %c, double %y, double %x 63 ret double %d 64 } 65 66 ; CHECK: olt_inverse: 67 ; CHECK-NEXT: maxsd %xmm0, %xmm1 68 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 69 ; CHECK-NEXT: ret 70 ; UNSAFE: olt_inverse: 71 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 72 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 73 ; UNSAFE-NEXT: ret 74 ; FINITE: olt_inverse: 75 ; FINITE-NEXT: maxsd %xmm0, %xmm1 76 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 77 ; FINITE-NEXT: ret 78 define double @olt_inverse(double %x, double %y) nounwind { 79 %c = fcmp olt double %x, %y 80 %d = select i1 %c, double %y, double %x 81 ret double %d 82 } 83 84 ; CHECK: oge: 85 ; CHECK-NEXT: ucomisd %xmm1, %xmm0 86 ; UNSAFE: oge: 87 ; UNSAFE-NEXT: maxsd %xmm1, %xmm0 88 ; UNSAFE-NEXT: ret 89 ; FINITE: oge: 90 ; FINITE-NEXT: maxsd %xmm1, %xmm0 91 ; FINITE-NEXT: ret 92 define double @oge(double %x, double %y) nounwind { 93 %c = fcmp oge double %x, %y 94 %d = select i1 %c, double %x, double %y 95 ret double %d 96 } 97 98 ; CHECK: ole: 99 ; CHECK-NEXT: ucomisd %xmm0, %xmm1 100 ; UNSAFE: ole: 101 ; UNSAFE-NEXT: minsd %xmm1, %xmm0 102 ; FINITE: ole: 103 ; FINITE-NEXT: minsd %xmm1, %xmm0 104 define double @ole(double %x, double %y) nounwind { 105 %c = fcmp ole double %x, %y 106 %d = select i1 %c, double %x, double %y 107 ret double %d 108 } 109 110 ; CHECK: oge_inverse: 111 ; CHECK-NEXT: ucomisd %xmm1, %xmm0 112 ; UNSAFE: oge_inverse: 113 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 114 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 115 ; UNSAFE-NEXT: ret 116 ; FINITE: oge_inverse: 117 ; FINITE-NEXT: minsd %xmm0, %xmm1 118 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 119 ; FINITE-NEXT: ret 120 define double @oge_inverse(double %x, double %y) nounwind { 121 %c = fcmp oge double %x, %y 122 %d = select i1 %c, double %y, double %x 123 ret double %d 124 } 125 126 ; CHECK: ole_inverse: 127 ; CHECK-NEXT: ucomisd %xmm0, %xmm1 128 ; UNSAFE: ole_inverse: 129 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 130 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 131 ; UNSAFE-NEXT: ret 132 ; FINITE: ole_inverse: 133 ; FINITE-NEXT: maxsd %xmm0, %xmm1 134 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 135 ; FINITE-NEXT: ret 136 define double @ole_inverse(double %x, double %y) nounwind { 137 %c = fcmp ole double %x, %y 138 %d = select i1 %c, double %y, double %x 139 ret double %d 140 } 141 142 ; CHECK: x_ogt: 143 ; CHECK-NEXT: pxor %xmm1, %xmm1 144 ; CHECK-NEXT: maxsd %xmm1, %xmm0 145 ; CHECK-NEXT: ret 146 ; UNSAFE: x_ogt: 147 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 148 ; UNSAFE-NEXT: maxsd %xmm1, %xmm0 149 ; UNSAFE-NEXT: ret 150 ; FINITE: x_ogt: 151 ; FINITE-NEXT: pxor %xmm1, %xmm1 152 ; FINITE-NEXT: maxsd %xmm1, %xmm0 153 ; FINITE-NEXT: ret 154 define double @x_ogt(double %x) nounwind { 155 %c = fcmp ogt double %x, 0.000000e+00 156 %d = select i1 %c, double %x, double 0.000000e+00 157 ret double %d 158 } 159 160 ; CHECK: x_olt: 161 ; CHECK-NEXT: pxor %xmm1, %xmm1 162 ; CHECK-NEXT: minsd %xmm1, %xmm0 163 ; CHECK-NEXT: ret 164 ; UNSAFE: x_olt: 165 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 166 ; UNSAFE-NEXT: minsd %xmm1, %xmm0 167 ; UNSAFE-NEXT: ret 168 ; FINITE: x_olt: 169 ; FINITE-NEXT: pxor %xmm1, %xmm1 170 ; FINITE-NEXT: minsd %xmm1, %xmm0 171 ; FINITE-NEXT: ret 172 define double @x_olt(double %x) nounwind { 173 %c = fcmp olt double %x, 0.000000e+00 174 %d = select i1 %c, double %x, double 0.000000e+00 175 ret double %d 176 } 177 178 ; CHECK: x_ogt_inverse: 179 ; CHECK-NEXT: pxor %xmm1, %xmm1 180 ; CHECK-NEXT: minsd %xmm0, %xmm1 181 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 182 ; CHECK-NEXT: ret 183 ; UNSAFE: x_ogt_inverse: 184 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 185 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 186 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 187 ; UNSAFE-NEXT: ret 188 ; FINITE: x_ogt_inverse: 189 ; FINITE-NEXT: pxor %xmm1, %xmm1 190 ; FINITE-NEXT: minsd %xmm0, %xmm1 191 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 192 ; FINITE-NEXT: ret 193 define double @x_ogt_inverse(double %x) nounwind { 194 %c = fcmp ogt double %x, 0.000000e+00 195 %d = select i1 %c, double 0.000000e+00, double %x 196 ret double %d 197 } 198 199 ; CHECK: x_olt_inverse: 200 ; CHECK-NEXT: pxor %xmm1, %xmm1 201 ; CHECK-NEXT: maxsd %xmm0, %xmm1 202 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 203 ; CHECK-NEXT: ret 204 ; UNSAFE: x_olt_inverse: 205 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 206 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 207 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 208 ; UNSAFE-NEXT: ret 209 ; FINITE: x_olt_inverse: 210 ; FINITE-NEXT: pxor %xmm1, %xmm1 211 ; FINITE-NEXT: maxsd %xmm0, %xmm1 212 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 213 ; FINITE-NEXT: ret 214 define double @x_olt_inverse(double %x) nounwind { 215 %c = fcmp olt double %x, 0.000000e+00 216 %d = select i1 %c, double 0.000000e+00, double %x 217 ret double %d 218 } 219 220 ; CHECK: x_oge: 221 ; CHECK: ucomisd %xmm1, %xmm0 222 ; UNSAFE: x_oge: 223 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 224 ; UNSAFE-NEXT: maxsd %xmm1, %xmm0 225 ; UNSAFE-NEXT: ret 226 ; FINITE: x_oge: 227 ; FINITE-NEXT: pxor %xmm1, %xmm1 228 ; FINITE-NEXT: maxsd %xmm1, %xmm0 229 ; FINITE-NEXT: ret 230 define double @x_oge(double %x) nounwind { 231 %c = fcmp oge double %x, 0.000000e+00 232 %d = select i1 %c, double %x, double 0.000000e+00 233 ret double %d 234 } 235 236 ; CHECK: x_ole: 237 ; CHECK: ucomisd %xmm0, %xmm1 238 ; UNSAFE: x_ole: 239 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 240 ; UNSAFE-NEXT: minsd %xmm1, %xmm0 241 ; UNSAFE-NEXT: ret 242 ; FINITE: x_ole: 243 ; FINITE-NEXT: pxor %xmm1, %xmm1 244 ; FINITE-NEXT: minsd %xmm1, %xmm0 245 ; FINITE-NEXT: ret 246 define double @x_ole(double %x) nounwind { 247 %c = fcmp ole double %x, 0.000000e+00 248 %d = select i1 %c, double %x, double 0.000000e+00 249 ret double %d 250 } 251 252 ; CHECK: x_oge_inverse: 253 ; CHECK: ucomisd %xmm1, %xmm0 254 ; UNSAFE: x_oge_inverse: 255 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 256 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 257 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 258 ; UNSAFE-NEXT: ret 259 ; FINITE: x_oge_inverse: 260 ; FINITE-NEXT: pxor %xmm1, %xmm1 261 ; FINITE-NEXT: minsd %xmm0, %xmm1 262 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 263 ; FINITE-NEXT: ret 264 define double @x_oge_inverse(double %x) nounwind { 265 %c = fcmp oge double %x, 0.000000e+00 266 %d = select i1 %c, double 0.000000e+00, double %x 267 ret double %d 268 } 269 270 ; CHECK: x_ole_inverse: 271 ; CHECK: ucomisd %xmm0, %xmm1 272 ; UNSAFE: x_ole_inverse: 273 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 274 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 275 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 276 ; UNSAFE-NEXT: ret 277 ; FINITE: x_ole_inverse: 278 ; FINITE-NEXT: pxor %xmm1, %xmm1 279 ; FINITE-NEXT: maxsd %xmm0, %xmm1 280 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 281 ; FINITE-NEXT: ret 282 define double @x_ole_inverse(double %x) nounwind { 283 %c = fcmp ole double %x, 0.000000e+00 284 %d = select i1 %c, double 0.000000e+00, double %x 285 ret double %d 286 } 287 288 ; CHECK: ugt: 289 ; CHECK: ucomisd %xmm0, %xmm1 290 ; UNSAFE: ugt: 291 ; UNSAFE-NEXT: maxsd %xmm1, %xmm0 292 ; UNSAFE-NEXT: ret 293 ; FINITE: ugt: 294 ; FINITE-NEXT: maxsd %xmm1, %xmm0 295 ; FINITE-NEXT: ret 296 define double @ugt(double %x, double %y) nounwind { 297 %c = fcmp ugt double %x, %y 298 %d = select i1 %c, double %x, double %y 299 ret double %d 300 } 301 302 ; CHECK: ult: 303 ; CHECK: ucomisd %xmm1, %xmm0 304 ; UNSAFE: ult: 305 ; UNSAFE-NEXT: minsd %xmm1, %xmm0 306 ; UNSAFE-NEXT: ret 307 ; FINITE: ult: 308 ; FINITE-NEXT: minsd %xmm1, %xmm0 309 ; FINITE-NEXT: ret 310 define double @ult(double %x, double %y) nounwind { 311 %c = fcmp ult double %x, %y 312 %d = select i1 %c, double %x, double %y 313 ret double %d 314 } 315 316 ; CHECK: ugt_inverse: 317 ; CHECK: ucomisd %xmm0, %xmm1 318 ; UNSAFE: ugt_inverse: 319 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 320 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 321 ; UNSAFE-NEXT: ret 322 ; FINITE: ugt_inverse: 323 ; FINITE-NEXT: minsd %xmm0, %xmm1 324 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 325 ; FINITE-NEXT: ret 326 define double @ugt_inverse(double %x, double %y) nounwind { 327 %c = fcmp ugt double %x, %y 328 %d = select i1 %c, double %y, double %x 329 ret double %d 330 } 331 332 ; CHECK: ult_inverse: 333 ; CHECK: ucomisd %xmm1, %xmm0 334 ; UNSAFE: ult_inverse: 335 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 336 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 337 ; UNSAFE-NEXT: ret 338 ; FINITE: ult_inverse: 339 ; FINITE-NEXT: maxsd %xmm0, %xmm1 340 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 341 ; FINITE-NEXT: ret 342 define double @ult_inverse(double %x, double %y) nounwind { 343 %c = fcmp ult double %x, %y 344 %d = select i1 %c, double %y, double %x 345 ret double %d 346 } 347 348 ; CHECK: uge: 349 ; CHECK-NEXT: maxsd %xmm0, %xmm1 350 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 351 ; CHECK-NEXT: ret 352 ; UNSAFE: uge: 353 ; UNSAFE-NEXT: maxsd %xmm1, %xmm0 354 ; UNSAFE-NEXT: ret 355 ; FINITE: uge: 356 ; FINITE-NEXT: maxsd %xmm1, %xmm0 357 ; FINITE-NEXT: ret 358 define double @uge(double %x, double %y) nounwind { 359 %c = fcmp uge double %x, %y 360 %d = select i1 %c, double %x, double %y 361 ret double %d 362 } 363 364 ; CHECK: ule: 365 ; CHECK-NEXT: minsd %xmm0, %xmm1 366 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 367 ; CHECK-NEXT: ret 368 ; UNSAFE: ule: 369 ; UNSAFE-NEXT: minsd %xmm1, %xmm0 370 ; UNSAFE-NEXT: ret 371 ; FINITE: ule: 372 ; FINITE-NEXT: minsd %xmm1, %xmm0 373 ; FINITE-NEXT: ret 374 define double @ule(double %x, double %y) nounwind { 375 %c = fcmp ule double %x, %y 376 %d = select i1 %c, double %x, double %y 377 ret double %d 378 } 379 380 ; CHECK: uge_inverse: 381 ; CHECK-NEXT: minsd %xmm1, %xmm0 382 ; CHECK-NEXT: ret 383 ; UNSAFE: uge_inverse: 384 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 385 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 386 ; UNSAFE-NEXT: ret 387 ; FINITE: uge_inverse: 388 ; FINITE-NEXT: minsd %xmm0, %xmm1 389 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 390 ; FINITE-NEXT: ret 391 define double @uge_inverse(double %x, double %y) nounwind { 392 %c = fcmp uge double %x, %y 393 %d = select i1 %c, double %y, double %x 394 ret double %d 395 } 396 397 ; CHECK: ule_inverse: 398 ; CHECK-NEXT: maxsd %xmm1, %xmm0 399 ; CHECK-NEXT: ret 400 ; UNSAFE: ule_inverse: 401 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 402 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 403 ; UNSAFE-NEXT: ret 404 ; FINITE: ule_inverse: 405 ; FINITE-NEXT: maxsd %xmm0, %xmm1 406 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 407 ; FINITE-NEXT: ret 408 define double @ule_inverse(double %x, double %y) nounwind { 409 %c = fcmp ule double %x, %y 410 %d = select i1 %c, double %y, double %x 411 ret double %d 412 } 413 414 ; CHECK: x_ugt: 415 ; CHECK: ucomisd %xmm0, %xmm1 416 ; UNSAFE: x_ugt: 417 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 418 ; UNSAFE-NEXT: maxsd %xmm1, %xmm0 419 ; UNSAFE-NEXT: ret 420 ; FINITE: x_ugt: 421 ; FINITE-NEXT: pxor %xmm1, %xmm1 422 ; FINITE-NEXT: maxsd %xmm1, %xmm0 423 ; FINITE-NEXT: ret 424 define double @x_ugt(double %x) nounwind { 425 %c = fcmp ugt double %x, 0.000000e+00 426 %d = select i1 %c, double %x, double 0.000000e+00 427 ret double %d 428 } 429 430 ; CHECK: x_ult: 431 ; CHECK: ucomisd %xmm1, %xmm0 432 ; UNSAFE: x_ult: 433 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 434 ; UNSAFE-NEXT: minsd %xmm1, %xmm0 435 ; UNSAFE-NEXT: ret 436 ; FINITE: x_ult: 437 ; FINITE-NEXT: pxor %xmm1, %xmm1 438 ; FINITE-NEXT: minsd %xmm1, %xmm0 439 ; FINITE-NEXT: ret 440 define double @x_ult(double %x) nounwind { 441 %c = fcmp ult double %x, 0.000000e+00 442 %d = select i1 %c, double %x, double 0.000000e+00 443 ret double %d 444 } 445 446 ; CHECK: x_ugt_inverse: 447 ; CHECK: ucomisd %xmm0, %xmm1 448 ; UNSAFE: x_ugt_inverse: 449 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 450 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 451 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 452 ; UNSAFE-NEXT: ret 453 ; FINITE: x_ugt_inverse: 454 ; FINITE-NEXT: pxor %xmm1, %xmm1 455 ; FINITE-NEXT: minsd %xmm0, %xmm1 456 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 457 ; FINITE-NEXT: ret 458 define double @x_ugt_inverse(double %x) nounwind { 459 %c = fcmp ugt double %x, 0.000000e+00 460 %d = select i1 %c, double 0.000000e+00, double %x 461 ret double %d 462 } 463 464 ; CHECK: x_ult_inverse: 465 ; CHECK: ucomisd %xmm1, %xmm0 466 ; UNSAFE: x_ult_inverse: 467 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 468 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 469 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 470 ; UNSAFE-NEXT: ret 471 ; FINITE: x_ult_inverse: 472 ; FINITE-NEXT: pxor %xmm1, %xmm1 473 ; FINITE-NEXT: maxsd %xmm0, %xmm1 474 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 475 ; FINITE-NEXT: ret 476 define double @x_ult_inverse(double %x) nounwind { 477 %c = fcmp ult double %x, 0.000000e+00 478 %d = select i1 %c, double 0.000000e+00, double %x 479 ret double %d 480 } 481 482 ; CHECK: x_uge: 483 ; CHECK-NEXT: pxor %xmm1, %xmm1 484 ; CHECK-NEXT: maxsd %xmm0, %xmm1 485 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 486 ; CHECK-NEXT: ret 487 ; UNSAFE: x_uge: 488 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 489 ; UNSAFE-NEXT: maxsd %xmm1, %xmm0 490 ; UNSAFE-NEXT: ret 491 ; FINITE: x_uge: 492 ; FINITE-NEXT: pxor %xmm1, %xmm1 493 ; FINITE-NEXT: maxsd %xmm1, %xmm0 494 ; FINITE-NEXT: ret 495 define double @x_uge(double %x) nounwind { 496 %c = fcmp uge double %x, 0.000000e+00 497 %d = select i1 %c, double %x, double 0.000000e+00 498 ret double %d 499 } 500 501 ; CHECK: x_ule: 502 ; CHECK-NEXT: pxor %xmm1, %xmm1 503 ; CHECK-NEXT: minsd %xmm0, %xmm1 504 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 505 ; CHECK-NEXT: ret 506 ; UNSAFE: x_ule: 507 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 508 ; UNSAFE-NEXT: minsd %xmm1, %xmm0 509 ; UNSAFE-NEXT: ret 510 ; FINITE: x_ule: 511 ; FINITE-NEXT: pxor %xmm1, %xmm1 512 ; FINITE-NEXT: minsd %xmm1, %xmm0 513 ; FINITE-NEXT: ret 514 define double @x_ule(double %x) nounwind { 515 %c = fcmp ule double %x, 0.000000e+00 516 %d = select i1 %c, double %x, double 0.000000e+00 517 ret double %d 518 } 519 520 ; CHECK: x_uge_inverse: 521 ; CHECK-NEXT: pxor %xmm1, %xmm1 522 ; CHECK-NEXT: minsd %xmm1, %xmm0 523 ; CHECK-NEXT: ret 524 ; UNSAFE: x_uge_inverse: 525 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 526 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 527 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 528 ; UNSAFE-NEXT: ret 529 ; FINITE: x_uge_inverse: 530 ; FINITE-NEXT: pxor %xmm1, %xmm1 531 ; FINITE-NEXT: minsd %xmm0, %xmm1 532 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 533 ; FINITE-NEXT: ret 534 define double @x_uge_inverse(double %x) nounwind { 535 %c = fcmp uge double %x, 0.000000e+00 536 %d = select i1 %c, double 0.000000e+00, double %x 537 ret double %d 538 } 539 540 ; CHECK: x_ule_inverse: 541 ; CHECK-NEXT: pxor %xmm1, %xmm1 542 ; CHECK-NEXT: maxsd %xmm1, %xmm0 543 ; CHECK-NEXT: ret 544 ; UNSAFE: x_ule_inverse: 545 ; UNSAFE-NEXT: pxor %xmm1, %xmm1 546 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 547 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 548 ; UNSAFE-NEXT: ret 549 ; FINITE: x_ule_inverse: 550 ; FINITE-NEXT: pxor %xmm1, %xmm1 551 ; FINITE-NEXT: maxsd %xmm0, %xmm1 552 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 553 ; FINITE-NEXT: ret 554 define double @x_ule_inverse(double %x) nounwind { 555 %c = fcmp ule double %x, 0.000000e+00 556 %d = select i1 %c, double 0.000000e+00, double %x 557 ret double %d 558 } 559 560 ; CHECK: y_ogt: 561 ; CHECK-NEXT: maxsd {{[^,]*}}, %xmm0 562 ; CHECK-NEXT: ret 563 ; UNSAFE: y_ogt: 564 ; UNSAFE-NEXT: maxsd {{[^,]*}}, %xmm0 565 ; UNSAFE-NEXT: ret 566 ; FINITE: y_ogt: 567 ; FINITE-NEXT: maxsd {{[^,]*}}, %xmm0 568 ; FINITE-NEXT: ret 569 define double @y_ogt(double %x) nounwind { 570 %c = fcmp ogt double %x, -0.000000e+00 571 %d = select i1 %c, double %x, double -0.000000e+00 572 ret double %d 573 } 574 575 ; CHECK: y_olt: 576 ; CHECK-NEXT: minsd {{[^,]*}}, %xmm0 577 ; CHECK-NEXT: ret 578 ; UNSAFE: y_olt: 579 ; UNSAFE-NEXT: minsd {{[^,]*}}, %xmm0 580 ; UNSAFE-NEXT: ret 581 ; FINITE: y_olt: 582 ; FINITE-NEXT: minsd {{[^,]*}}, %xmm0 583 ; FINITE-NEXT: ret 584 define double @y_olt(double %x) nounwind { 585 %c = fcmp olt double %x, -0.000000e+00 586 %d = select i1 %c, double %x, double -0.000000e+00 587 ret double %d 588 } 589 590 ; CHECK: y_ogt_inverse: 591 ; CHECK-NEXT: movsd {{[^,]*}}, %xmm1 592 ; CHECK-NEXT: minsd %xmm0, %xmm1 593 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 594 ; CHECK-NEXT: ret 595 ; UNSAFE: y_ogt_inverse: 596 ; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1 597 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 598 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 599 ; UNSAFE-NEXT: ret 600 ; FINITE: y_ogt_inverse: 601 ; FINITE-NEXT: movsd {{[^,]*}}, %xmm1 602 ; FINITE-NEXT: minsd %xmm0, %xmm1 603 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 604 ; FINITE-NEXT: ret 605 define double @y_ogt_inverse(double %x) nounwind { 606 %c = fcmp ogt double %x, -0.000000e+00 607 %d = select i1 %c, double -0.000000e+00, double %x 608 ret double %d 609 } 610 611 ; CHECK: y_olt_inverse: 612 ; CHECK-NEXT: movsd {{[^,]*}}, %xmm1 613 ; CHECK-NEXT: maxsd %xmm0, %xmm1 614 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 615 ; CHECK-NEXT: ret 616 ; UNSAFE: y_olt_inverse: 617 ; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1 618 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 619 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 620 ; UNSAFE-NEXT: ret 621 ; FINITE: y_olt_inverse: 622 ; FINITE-NEXT: movsd {{[^,]*}}, %xmm1 623 ; FINITE-NEXT: maxsd %xmm0, %xmm1 624 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 625 ; FINITE-NEXT: ret 626 define double @y_olt_inverse(double %x) nounwind { 627 %c = fcmp olt double %x, -0.000000e+00 628 %d = select i1 %c, double -0.000000e+00, double %x 629 ret double %d 630 } 631 632 ; CHECK: y_oge: 633 ; CHECK: ucomisd %xmm1, %xmm0 634 ; UNSAFE: y_oge: 635 ; UNSAFE-NEXT: maxsd {{[^,]*}}, %xmm0 636 ; UNSAFE-NEXT: ret 637 ; FINITE: y_oge: 638 ; FINITE-NEXT: maxsd {{[^,]*}}, %xmm0 639 ; FINITE-NEXT: ret 640 define double @y_oge(double %x) nounwind { 641 %c = fcmp oge double %x, -0.000000e+00 642 %d = select i1 %c, double %x, double -0.000000e+00 643 ret double %d 644 } 645 646 ; CHECK: y_ole: 647 ; CHECK: ucomisd %xmm0, %xmm1 648 ; UNSAFE: y_ole: 649 ; UNSAFE-NEXT: minsd {{[^,]*}}, %xmm0 650 ; UNSAFE-NEXT: ret 651 ; FINITE: y_ole: 652 ; FINITE-NEXT: minsd {{[^,]*}}, %xmm0 653 ; FINITE-NEXT: ret 654 define double @y_ole(double %x) nounwind { 655 %c = fcmp ole double %x, -0.000000e+00 656 %d = select i1 %c, double %x, double -0.000000e+00 657 ret double %d 658 } 659 660 ; CHECK: y_oge_inverse: 661 ; CHECK: ucomisd %xmm1, %xmm0 662 ; UNSAFE: y_oge_inverse: 663 ; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1 664 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 665 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 666 ; UNSAFE-NEXT: ret 667 ; FINITE: y_oge_inverse: 668 ; FINITE-NEXT: movsd {{[^,]*}}, %xmm1 669 ; FINITE-NEXT: minsd %xmm0, %xmm1 670 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 671 ; FINITE-NEXT: ret 672 define double @y_oge_inverse(double %x) nounwind { 673 %c = fcmp oge double %x, -0.000000e+00 674 %d = select i1 %c, double -0.000000e+00, double %x 675 ret double %d 676 } 677 678 ; CHECK: y_ole_inverse: 679 ; CHECK: ucomisd %xmm0, %xmm1 680 ; UNSAFE: y_ole_inverse: 681 ; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1 682 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 683 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 684 ; UNSAFE-NEXT: ret 685 ; FINITE: y_ole_inverse: 686 ; FINITE-NEXT: movsd {{[^,]*}}, %xmm1 687 ; FINITE-NEXT: maxsd %xmm0, %xmm1 688 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 689 ; FINITE-NEXT: ret 690 define double @y_ole_inverse(double %x) nounwind { 691 %c = fcmp ole double %x, -0.000000e+00 692 %d = select i1 %c, double -0.000000e+00, double %x 693 ret double %d 694 } 695 696 ; CHECK: y_ugt: 697 ; CHECK: ucomisd %xmm0, %xmm1 698 ; UNSAFE: y_ugt: 699 ; UNSAFE-NEXT: maxsd {{[^,]*}}, %xmm0 700 ; UNSAFE-NEXT: ret 701 ; FINITE: y_ugt: 702 ; FINITE-NEXT: maxsd {{[^,]*}}, %xmm0 703 ; FINITE-NEXT: ret 704 define double @y_ugt(double %x) nounwind { 705 %c = fcmp ugt double %x, -0.000000e+00 706 %d = select i1 %c, double %x, double -0.000000e+00 707 ret double %d 708 } 709 710 ; CHECK: y_ult: 711 ; CHECK: ucomisd %xmm1, %xmm0 712 ; UNSAFE: y_ult: 713 ; UNSAFE-NEXT: minsd {{[^,]*}}, %xmm0 714 ; UNSAFE-NEXT: ret 715 ; FINITE: y_ult: 716 ; FINITE-NEXT: minsd {{[^,]*}}, %xmm0 717 ; FINITE-NEXT: ret 718 define double @y_ult(double %x) nounwind { 719 %c = fcmp ult double %x, -0.000000e+00 720 %d = select i1 %c, double %x, double -0.000000e+00 721 ret double %d 722 } 723 724 ; CHECK: y_ugt_inverse: 725 ; CHECK: ucomisd %xmm0, %xmm1 726 ; UNSAFE: y_ugt_inverse: 727 ; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1 728 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 729 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 730 ; UNSAFE-NEXT: ret 731 ; FINITE: y_ugt_inverse: 732 ; FINITE-NEXT: movsd {{[^,]*}}, %xmm1 733 ; FINITE-NEXT: minsd %xmm0, %xmm1 734 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 735 ; FINITE-NEXT: ret 736 define double @y_ugt_inverse(double %x) nounwind { 737 %c = fcmp ugt double %x, -0.000000e+00 738 %d = select i1 %c, double -0.000000e+00, double %x 739 ret double %d 740 } 741 742 ; CHECK: y_ult_inverse: 743 ; CHECK: ucomisd %xmm1, %xmm0 744 ; UNSAFE: y_ult_inverse: 745 ; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1 746 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 747 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 748 ; UNSAFE-NEXT: ret 749 ; FINITE: y_ult_inverse: 750 ; FINITE-NEXT: movsd {{[^,]*}}, %xmm1 751 ; FINITE-NEXT: maxsd %xmm0, %xmm1 752 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 753 ; FINITE-NEXT: ret 754 define double @y_ult_inverse(double %x) nounwind { 755 %c = fcmp ult double %x, -0.000000e+00 756 %d = select i1 %c, double -0.000000e+00, double %x 757 ret double %d 758 } 759 760 ; CHECK: y_uge: 761 ; CHECK-NEXT: movsd {{[^,]*}}, %xmm1 762 ; CHECK-NEXT: maxsd %xmm0, %xmm1 763 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 764 ; CHECK-NEXT: ret 765 ; UNSAFE: y_uge: 766 ; UNSAFE-NEXT: maxsd {{[^,]*}}, %xmm0 767 ; UNSAFE-NEXT: ret 768 ; FINITE: y_uge: 769 ; FINITE-NEXT: maxsd {{[^,]*}}, %xmm0 770 ; FINITE-NEXT: ret 771 define double @y_uge(double %x) nounwind { 772 %c = fcmp uge double %x, -0.000000e+00 773 %d = select i1 %c, double %x, double -0.000000e+00 774 ret double %d 775 } 776 777 ; CHECK: y_ule: 778 ; CHECK-NEXT: movsd {{[^,]*}}, %xmm1 779 ; CHECK-NEXT: minsd %xmm0, %xmm1 780 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 781 ; CHECK-NEXT: ret 782 ; UNSAFE: y_ule: 783 ; UNSAFE-NEXT: minsd {{[^,]*}}, %xmm0 784 ; UNSAFE-NEXT: ret 785 ; FINITE: y_ule: 786 ; FINITE-NEXT: minsd {{[^,]*}}, %xmm0 787 ; FINITE-NEXT: ret 788 define double @y_ule(double %x) nounwind { 789 %c = fcmp ule double %x, -0.000000e+00 790 %d = select i1 %c, double %x, double -0.000000e+00 791 ret double %d 792 } 793 794 ; CHECK: y_uge_inverse: 795 ; CHECK-NEXT: minsd {{[^,]*}}, %xmm0 796 ; CHECK-NEXT: ret 797 ; UNSAFE: y_uge_inverse: 798 ; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1 799 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 800 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 801 ; UNSAFE-NEXT: ret 802 ; FINITE: y_uge_inverse: 803 ; FINITE-NEXT: movsd {{[^,]*}}, %xmm1 804 ; FINITE-NEXT: minsd %xmm0, %xmm1 805 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 806 ; FINITE-NEXT: ret 807 define double @y_uge_inverse(double %x) nounwind { 808 %c = fcmp uge double %x, -0.000000e+00 809 %d = select i1 %c, double -0.000000e+00, double %x 810 ret double %d 811 } 812 813 ; CHECK: y_ule_inverse: 814 ; CHECK-NEXT: maxsd {{[^,]*}}, %xmm0 815 ; CHECK-NEXT: ret 816 ; UNSAFE: y_ule_inverse: 817 ; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1 818 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 819 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 820 ; UNSAFE-NEXT: ret 821 ; FINITE: y_ule_inverse: 822 ; FINITE-NEXT: movsd {{[^,]*}}, %xmm1 823 ; FINITE-NEXT: maxsd %xmm0, %xmm1 824 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 825 ; FINITE-NEXT: ret 826 define double @y_ule_inverse(double %x) nounwind { 827 %c = fcmp ule double %x, -0.000000e+00 828 %d = select i1 %c, double -0.000000e+00, double %x 829 ret double %d 830 } 831 ; Test a few more misc. cases. 832 833 ; CHECK: clampTo3k_a: 834 ; CHECK: minsd 835 ; UNSAFE: clampTo3k_a: 836 ; UNSAFE: minsd 837 ; FINITE: clampTo3k_a: 838 ; FINITE: minsd 839 define double @clampTo3k_a(double %x) nounwind readnone { 840 entry: 841 %0 = fcmp ogt double %x, 3.000000e+03 ; <i1> [#uses=1] 842 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1] 843 ret double %x_addr.0 844 } 845 846 ; CHECK: clampTo3k_b: 847 ; CHECK: minsd 848 ; UNSAFE: clampTo3k_b: 849 ; UNSAFE: minsd 850 ; FINITE: clampTo3k_b: 851 ; FINITE: minsd 852 define double @clampTo3k_b(double %x) nounwind readnone { 853 entry: 854 %0 = fcmp uge double %x, 3.000000e+03 ; <i1> [#uses=1] 855 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1] 856 ret double %x_addr.0 857 } 858 859 ; CHECK: clampTo3k_c: 860 ; CHECK: maxsd 861 ; UNSAFE: clampTo3k_c: 862 ; UNSAFE: maxsd 863 ; FINITE: clampTo3k_c: 864 ; FINITE: maxsd 865 define double @clampTo3k_c(double %x) nounwind readnone { 866 entry: 867 %0 = fcmp olt double %x, 3.000000e+03 ; <i1> [#uses=1] 868 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1] 869 ret double %x_addr.0 870 } 871 872 ; CHECK: clampTo3k_d: 873 ; CHECK: maxsd 874 ; UNSAFE: clampTo3k_d: 875 ; UNSAFE: maxsd 876 ; FINITE: clampTo3k_d: 877 ; FINITE: maxsd 878 define double @clampTo3k_d(double %x) nounwind readnone { 879 entry: 880 %0 = fcmp ule double %x, 3.000000e+03 ; <i1> [#uses=1] 881 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1] 882 ret double %x_addr.0 883 } 884 885 ; CHECK: clampTo3k_e: 886 ; CHECK: maxsd 887 ; UNSAFE: clampTo3k_e: 888 ; UNSAFE: maxsd 889 ; FINITE: clampTo3k_e: 890 ; FINITE: maxsd 891 define double @clampTo3k_e(double %x) nounwind readnone { 892 entry: 893 %0 = fcmp olt double %x, 3.000000e+03 ; <i1> [#uses=1] 894 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1] 895 ret double %x_addr.0 896 } 897 898 ; CHECK: clampTo3k_f: 899 ; CHECK: maxsd 900 ; UNSAFE: clampTo3k_f: 901 ; UNSAFE: maxsd 902 ; FINITE: clampTo3k_f: 903 ; FINITE: maxsd 904 define double @clampTo3k_f(double %x) nounwind readnone { 905 entry: 906 %0 = fcmp ule double %x, 3.000000e+03 ; <i1> [#uses=1] 907 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1] 908 ret double %x_addr.0 909 } 910 911 ; CHECK: clampTo3k_g: 912 ; CHECK: minsd 913 ; UNSAFE: clampTo3k_g: 914 ; UNSAFE: minsd 915 ; FINITE: clampTo3k_g: 916 ; FINITE: minsd 917 define double @clampTo3k_g(double %x) nounwind readnone { 918 entry: 919 %0 = fcmp ogt double %x, 3.000000e+03 ; <i1> [#uses=1] 920 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1] 921 ret double %x_addr.0 922 } 923 924 ; CHECK: clampTo3k_h: 925 ; CHECK: minsd 926 ; UNSAFE: clampTo3k_h: 927 ; UNSAFE: minsd 928 ; FINITE: clampTo3k_h: 929 ; FINITE: minsd 930 define double @clampTo3k_h(double %x) nounwind readnone { 931 entry: 932 %0 = fcmp uge double %x, 3.000000e+03 ; <i1> [#uses=1] 933 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1] 934 ret double %x_addr.0 935 } 936 937 ; UNSAFE: maxpd: 938 ; UNSAFE: maxpd 939 define <2 x double> @maxpd(<2 x double> %x, <2 x double> %y) { 940 %max_is_x = fcmp oge <2 x double> %x, %y 941 %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y 942 ret <2 x double> %max 943 } 944 945 ; UNSAFE: minpd: 946 ; UNSAFE: minpd 947 define <2 x double> @minpd(<2 x double> %x, <2 x double> %y) { 948 %min_is_x = fcmp ole <2 x double> %x, %y 949 %min = select <2 x i1> %min_is_x, <2 x double> %x, <2 x double> %y 950 ret <2 x double> %min 951 } 952 953 ; UNSAFE: maxps: 954 ; UNSAFE: maxps 955 define <4 x float> @maxps(<4 x float> %x, <4 x float> %y) { 956 %max_is_x = fcmp oge <4 x float> %x, %y 957 %max = select <4 x i1> %max_is_x, <4 x float> %x, <4 x float> %y 958 ret <4 x float> %max 959 } 960 961 ; UNSAFE: minps: 962 ; UNSAFE: minps 963 define <4 x float> @minps(<4 x float> %x, <4 x float> %y) { 964 %min_is_x = fcmp ole <4 x float> %x, %y 965 %min = select <4 x i1> %min_is_x, <4 x float> %x, <4 x float> %y 966 ret <4 x float> %min 967 } 968