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