1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=sse4.2 | FileCheck %s --check-prefix=ALL --check-prefix=STRICT 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=sse4.2 -enable-no-signed-zeros-fp-math -enable-no-nans-fp-math | FileCheck %s --check-prefix=ALL --check-prefix=RELAX --check-prefix=UNSAFE 4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=sse4.2 -enable-no-nans-fp-math | FileCheck %s --check-prefix=ALL --check-prefix=RELAX --check-prefix=FINITE 5 6; Some of these patterns can be matched as SSE min or max. Some of 7; them can be matched provided that the operands are swapped. 8; Some of them can't be matched at all and require a comparison 9; and a conditional branch. 10 11; The naming convention is {,x_,y_}{o,u}{gt,lt,ge,le}{,_inverse} 12; _x: use 0.0 instead of %y 13; _y: use -0.0 instead of %y 14; _inverse : swap the arms of the select. 15 16define double @ogt(double %x, double %y) { 17; ALL-LABEL: ogt: 18; ALL: # %bb.0: 19; ALL-NEXT: maxsd %xmm1, %xmm0 20; ALL-NEXT: retq 21 %c = fcmp ogt double %x, %y 22 %d = select i1 %c, double %x, double %y 23 ret double %d 24} 25 26define double @olt(double %x, double %y) { 27; ALL-LABEL: olt: 28; ALL: # %bb.0: 29; ALL-NEXT: minsd %xmm1, %xmm0 30; ALL-NEXT: retq 31 %c = fcmp olt double %x, %y 32 %d = select i1 %c, double %x, double %y 33 ret double %d 34} 35 36define double @ogt_inverse(double %x, double %y) { 37; STRICT-LABEL: ogt_inverse: 38; STRICT: # %bb.0: 39; STRICT-NEXT: minsd %xmm0, %xmm1 40; STRICT-NEXT: movapd %xmm1, %xmm0 41; STRICT-NEXT: retq 42; 43; UNSAFE-LABEL: ogt_inverse: 44; UNSAFE: # %bb.0: 45; UNSAFE-NEXT: minsd %xmm1, %xmm0 46; UNSAFE-NEXT: retq 47; 48; FINITE-LABEL: ogt_inverse: 49; FINITE: # %bb.0: 50; FINITE-NEXT: minsd %xmm0, %xmm1 51; FINITE-NEXT: movapd %xmm1, %xmm0 52; FINITE-NEXT: retq 53 %c = fcmp ogt double %x, %y 54 %d = select i1 %c, double %y, double %x 55 ret double %d 56} 57 58define double @olt_inverse(double %x, double %y) { 59; STRICT-LABEL: olt_inverse: 60; STRICT: # %bb.0: 61; STRICT-NEXT: maxsd %xmm0, %xmm1 62; STRICT-NEXT: movapd %xmm1, %xmm0 63; STRICT-NEXT: retq 64; 65; UNSAFE-LABEL: olt_inverse: 66; UNSAFE: # %bb.0: 67; UNSAFE-NEXT: maxsd %xmm1, %xmm0 68; UNSAFE-NEXT: retq 69; 70; FINITE-LABEL: olt_inverse: 71; FINITE: # %bb.0: 72; FINITE-NEXT: maxsd %xmm0, %xmm1 73; FINITE-NEXT: movapd %xmm1, %xmm0 74; FINITE-NEXT: retq 75 %c = fcmp olt double %x, %y 76 %d = select i1 %c, double %y, double %x 77 ret double %d 78} 79 80define double @oge(double %x, double %y) { 81; STRICT-LABEL: oge: 82; STRICT: # %bb.0: 83; STRICT-NEXT: movapd %xmm1, %xmm2 84; STRICT-NEXT: cmplesd %xmm0, %xmm2 85; STRICT-NEXT: andpd %xmm2, %xmm0 86; STRICT-NEXT: andnpd %xmm1, %xmm2 87; STRICT-NEXT: orpd %xmm2, %xmm0 88; STRICT-NEXT: retq 89; 90; RELAX-LABEL: oge: 91; RELAX: # %bb.0: 92; RELAX-NEXT: maxsd %xmm1, %xmm0 93; RELAX-NEXT: retq 94 %c = fcmp oge double %x, %y 95 %d = select i1 %c, double %x, double %y 96 ret double %d 97} 98 99define double @ole(double %x, double %y) { 100; STRICT-LABEL: ole: 101; STRICT: # %bb.0: 102; STRICT-NEXT: movapd %xmm0, %xmm2 103; STRICT-NEXT: cmplesd %xmm1, %xmm2 104; STRICT-NEXT: andpd %xmm2, %xmm0 105; STRICT-NEXT: andnpd %xmm1, %xmm2 106; STRICT-NEXT: orpd %xmm2, %xmm0 107; STRICT-NEXT: retq 108; 109; RELAX-LABEL: ole: 110; RELAX: # %bb.0: 111; RELAX-NEXT: minsd %xmm1, %xmm0 112; RELAX-NEXT: retq 113 %c = fcmp ole double %x, %y 114 %d = select i1 %c, double %x, double %y 115 ret double %d 116} 117 118define double @oge_inverse(double %x, double %y) { 119; STRICT-LABEL: oge_inverse: 120; STRICT: # %bb.0: 121; STRICT-NEXT: movapd %xmm1, %xmm2 122; STRICT-NEXT: cmplesd %xmm0, %xmm2 123; STRICT-NEXT: andpd %xmm2, %xmm1 124; STRICT-NEXT: andnpd %xmm0, %xmm2 125; STRICT-NEXT: orpd %xmm1, %xmm2 126; STRICT-NEXT: movapd %xmm2, %xmm0 127; STRICT-NEXT: retq 128; 129; UNSAFE-LABEL: oge_inverse: 130; UNSAFE: # %bb.0: 131; UNSAFE-NEXT: minsd %xmm1, %xmm0 132; UNSAFE-NEXT: retq 133; 134; FINITE-LABEL: oge_inverse: 135; FINITE: # %bb.0: 136; FINITE-NEXT: minsd %xmm0, %xmm1 137; FINITE-NEXT: movapd %xmm1, %xmm0 138; FINITE-NEXT: retq 139 %c = fcmp oge double %x, %y 140 %d = select i1 %c, double %y, double %x 141 ret double %d 142} 143 144define double @ole_inverse(double %x, double %y) { 145; STRICT-LABEL: ole_inverse: 146; STRICT: # %bb.0: 147; STRICT-NEXT: movapd %xmm0, %xmm2 148; STRICT-NEXT: cmplesd %xmm1, %xmm2 149; STRICT-NEXT: andpd %xmm2, %xmm1 150; STRICT-NEXT: andnpd %xmm0, %xmm2 151; STRICT-NEXT: orpd %xmm1, %xmm2 152; STRICT-NEXT: movapd %xmm2, %xmm0 153; STRICT-NEXT: retq 154; 155; UNSAFE-LABEL: ole_inverse: 156; UNSAFE: # %bb.0: 157; UNSAFE-NEXT: maxsd %xmm1, %xmm0 158; UNSAFE-NEXT: retq 159; 160; FINITE-LABEL: ole_inverse: 161; FINITE: # %bb.0: 162; FINITE-NEXT: maxsd %xmm0, %xmm1 163; FINITE-NEXT: movapd %xmm1, %xmm0 164; FINITE-NEXT: retq 165 %c = fcmp ole double %x, %y 166 %d = select i1 %c, double %y, double %x 167 ret double %d 168} 169 170define double @ogt_x(double %x) { 171; ALL-LABEL: ogt_x: 172; ALL: # %bb.0: 173; ALL-NEXT: xorpd %xmm1, %xmm1 174; ALL-NEXT: maxsd %xmm1, %xmm0 175; ALL-NEXT: retq 176 %c = fcmp ogt double %x, 0.000000e+00 177 %d = select i1 %c, double %x, double 0.000000e+00 178 ret double %d 179} 180 181define double @olt_x(double %x) { 182; ALL-LABEL: olt_x: 183; ALL: # %bb.0: 184; ALL-NEXT: xorpd %xmm1, %xmm1 185; ALL-NEXT: minsd %xmm1, %xmm0 186; ALL-NEXT: retq 187 %c = fcmp olt double %x, 0.000000e+00 188 %d = select i1 %c, double %x, double 0.000000e+00 189 ret double %d 190} 191 192define double @ogt_inverse_x(double %x) { 193; STRICT-LABEL: ogt_inverse_x: 194; STRICT: # %bb.0: 195; STRICT-NEXT: xorpd %xmm1, %xmm1 196; STRICT-NEXT: minsd %xmm0, %xmm1 197; STRICT-NEXT: movapd %xmm1, %xmm0 198; STRICT-NEXT: retq 199; 200; UNSAFE-LABEL: ogt_inverse_x: 201; UNSAFE: # %bb.0: 202; UNSAFE-NEXT: xorpd %xmm1, %xmm1 203; UNSAFE-NEXT: minsd %xmm1, %xmm0 204; UNSAFE-NEXT: retq 205; 206; FINITE-LABEL: ogt_inverse_x: 207; FINITE: # %bb.0: 208; FINITE-NEXT: xorpd %xmm1, %xmm1 209; FINITE-NEXT: minsd %xmm0, %xmm1 210; FINITE-NEXT: movapd %xmm1, %xmm0 211; FINITE-NEXT: retq 212 %c = fcmp ogt double %x, 0.000000e+00 213 %d = select i1 %c, double 0.000000e+00, double %x 214 ret double %d 215} 216 217define double @olt_inverse_x(double %x) { 218; STRICT-LABEL: olt_inverse_x: 219; STRICT: # %bb.0: 220; STRICT-NEXT: xorpd %xmm1, %xmm1 221; STRICT-NEXT: maxsd %xmm0, %xmm1 222; STRICT-NEXT: movapd %xmm1, %xmm0 223; STRICT-NEXT: retq 224; 225; UNSAFE-LABEL: olt_inverse_x: 226; UNSAFE: # %bb.0: 227; UNSAFE-NEXT: xorpd %xmm1, %xmm1 228; UNSAFE-NEXT: maxsd %xmm1, %xmm0 229; UNSAFE-NEXT: retq 230; 231; FINITE-LABEL: olt_inverse_x: 232; FINITE: # %bb.0: 233; FINITE-NEXT: xorpd %xmm1, %xmm1 234; FINITE-NEXT: maxsd %xmm0, %xmm1 235; FINITE-NEXT: movapd %xmm1, %xmm0 236; FINITE-NEXT: retq 237 %c = fcmp olt double %x, 0.000000e+00 238 %d = select i1 %c, double 0.000000e+00, double %x 239 ret double %d 240} 241 242define double @oge_x(double %x) { 243; STRICT-LABEL: oge_x: 244; STRICT: # %bb.0: 245; STRICT-NEXT: xorpd %xmm1, %xmm1 246; STRICT-NEXT: cmplesd %xmm0, %xmm1 247; STRICT-NEXT: andpd %xmm1, %xmm0 248; STRICT-NEXT: retq 249; 250; RELAX-LABEL: oge_x: 251; RELAX: # %bb.0: 252; RELAX-NEXT: xorpd %xmm1, %xmm1 253; RELAX-NEXT: maxsd %xmm1, %xmm0 254; RELAX-NEXT: retq 255 %c = fcmp oge double %x, 0.000000e+00 256 %d = select i1 %c, double %x, double 0.000000e+00 257 ret double %d 258} 259 260define double @ole_x(double %x) { 261; STRICT-LABEL: ole_x: 262; STRICT: # %bb.0: 263; STRICT-NEXT: xorpd %xmm1, %xmm1 264; STRICT-NEXT: movapd %xmm0, %xmm2 265; STRICT-NEXT: cmplesd %xmm1, %xmm2 266; STRICT-NEXT: andpd %xmm2, %xmm0 267; STRICT-NEXT: retq 268; 269; RELAX-LABEL: ole_x: 270; RELAX: # %bb.0: 271; RELAX-NEXT: xorpd %xmm1, %xmm1 272; RELAX-NEXT: minsd %xmm1, %xmm0 273; RELAX-NEXT: retq 274 %c = fcmp ole double %x, 0.000000e+00 275 %d = select i1 %c, double %x, double 0.000000e+00 276 ret double %d 277} 278 279define double @oge_inverse_x(double %x) { 280; STRICT-LABEL: oge_inverse_x: 281; STRICT: # %bb.0: 282; STRICT-NEXT: xorpd %xmm1, %xmm1 283; STRICT-NEXT: cmplesd %xmm0, %xmm1 284; STRICT-NEXT: andnpd %xmm0, %xmm1 285; STRICT-NEXT: movapd %xmm1, %xmm0 286; STRICT-NEXT: retq 287; 288; UNSAFE-LABEL: oge_inverse_x: 289; UNSAFE: # %bb.0: 290; UNSAFE-NEXT: xorpd %xmm1, %xmm1 291; UNSAFE-NEXT: minsd %xmm1, %xmm0 292; UNSAFE-NEXT: retq 293; 294; FINITE-LABEL: oge_inverse_x: 295; FINITE: # %bb.0: 296; FINITE-NEXT: xorpd %xmm1, %xmm1 297; FINITE-NEXT: minsd %xmm0, %xmm1 298; FINITE-NEXT: movapd %xmm1, %xmm0 299; FINITE-NEXT: retq 300 %c = fcmp oge double %x, 0.000000e+00 301 %d = select i1 %c, double 0.000000e+00, double %x 302 ret double %d 303} 304 305define double @ole_inverse_x(double %x) { 306; STRICT-LABEL: ole_inverse_x: 307; STRICT: # %bb.0: 308; STRICT-NEXT: xorpd %xmm2, %xmm2 309; STRICT-NEXT: movapd %xmm0, %xmm1 310; STRICT-NEXT: cmplesd %xmm2, %xmm1 311; STRICT-NEXT: andnpd %xmm0, %xmm1 312; STRICT-NEXT: movapd %xmm1, %xmm0 313; STRICT-NEXT: retq 314; 315; UNSAFE-LABEL: ole_inverse_x: 316; UNSAFE: # %bb.0: 317; UNSAFE-NEXT: xorpd %xmm1, %xmm1 318; UNSAFE-NEXT: maxsd %xmm1, %xmm0 319; UNSAFE-NEXT: retq 320; 321; FINITE-LABEL: ole_inverse_x: 322; FINITE: # %bb.0: 323; FINITE-NEXT: xorpd %xmm1, %xmm1 324; FINITE-NEXT: maxsd %xmm0, %xmm1 325; FINITE-NEXT: movapd %xmm1, %xmm0 326; FINITE-NEXT: retq 327 %c = fcmp ole double %x, 0.000000e+00 328 %d = select i1 %c, double 0.000000e+00, double %x 329 ret double %d 330} 331 332define double @ugt(double %x, double %y) { 333; STRICT-LABEL: ugt: 334; STRICT: # %bb.0: 335; STRICT-NEXT: movapd %xmm0, %xmm2 336; STRICT-NEXT: cmpnlesd %xmm1, %xmm2 337; STRICT-NEXT: andpd %xmm2, %xmm0 338; STRICT-NEXT: andnpd %xmm1, %xmm2 339; STRICT-NEXT: orpd %xmm2, %xmm0 340; STRICT-NEXT: retq 341; 342; RELAX-LABEL: ugt: 343; RELAX: # %bb.0: 344; RELAX-NEXT: maxsd %xmm1, %xmm0 345; RELAX-NEXT: retq 346 %c = fcmp ugt double %x, %y 347 %d = select i1 %c, double %x, double %y 348 ret double %d 349} 350 351define double @ult(double %x, double %y) { 352; STRICT-LABEL: ult: 353; STRICT: # %bb.0: 354; STRICT-NEXT: movapd %xmm1, %xmm2 355; STRICT-NEXT: cmpnlesd %xmm0, %xmm2 356; STRICT-NEXT: andpd %xmm2, %xmm0 357; STRICT-NEXT: andnpd %xmm1, %xmm2 358; STRICT-NEXT: orpd %xmm2, %xmm0 359; STRICT-NEXT: retq 360; 361; RELAX-LABEL: ult: 362; RELAX: # %bb.0: 363; RELAX-NEXT: minsd %xmm1, %xmm0 364; RELAX-NEXT: retq 365 %c = fcmp ult double %x, %y 366 %d = select i1 %c, double %x, double %y 367 ret double %d 368} 369 370define double @ugt_inverse(double %x, double %y) { 371; STRICT-LABEL: ugt_inverse: 372; STRICT: # %bb.0: 373; STRICT-NEXT: movapd %xmm0, %xmm2 374; STRICT-NEXT: cmpnlesd %xmm1, %xmm2 375; STRICT-NEXT: andpd %xmm2, %xmm1 376; STRICT-NEXT: andnpd %xmm0, %xmm2 377; STRICT-NEXT: orpd %xmm1, %xmm2 378; STRICT-NEXT: movapd %xmm2, %xmm0 379; STRICT-NEXT: retq 380; 381; UNSAFE-LABEL: ugt_inverse: 382; UNSAFE: # %bb.0: 383; UNSAFE-NEXT: minsd %xmm1, %xmm0 384; UNSAFE-NEXT: retq 385; 386; FINITE-LABEL: ugt_inverse: 387; FINITE: # %bb.0: 388; FINITE-NEXT: minsd %xmm0, %xmm1 389; FINITE-NEXT: movapd %xmm1, %xmm0 390; FINITE-NEXT: retq 391 %c = fcmp ugt double %x, %y 392 %d = select i1 %c, double %y, double %x 393 ret double %d 394} 395 396define double @ult_inverse(double %x, double %y) { 397; STRICT-LABEL: ult_inverse: 398; STRICT: # %bb.0: 399; STRICT-NEXT: movapd %xmm1, %xmm2 400; STRICT-NEXT: cmpnlesd %xmm0, %xmm2 401; STRICT-NEXT: andpd %xmm2, %xmm1 402; STRICT-NEXT: andnpd %xmm0, %xmm2 403; STRICT-NEXT: orpd %xmm1, %xmm2 404; STRICT-NEXT: movapd %xmm2, %xmm0 405; STRICT-NEXT: retq 406; 407; UNSAFE-LABEL: ult_inverse: 408; UNSAFE: # %bb.0: 409; UNSAFE-NEXT: maxsd %xmm1, %xmm0 410; UNSAFE-NEXT: retq 411; 412; FINITE-LABEL: ult_inverse: 413; FINITE: # %bb.0: 414; FINITE-NEXT: maxsd %xmm0, %xmm1 415; FINITE-NEXT: movapd %xmm1, %xmm0 416; FINITE-NEXT: retq 417 %c = fcmp ult double %x, %y 418 %d = select i1 %c, double %y, double %x 419 ret double %d 420} 421 422define double @uge(double %x, double %y) { 423; STRICT-LABEL: uge: 424; STRICT: # %bb.0: 425; STRICT-NEXT: maxsd %xmm0, %xmm1 426; STRICT-NEXT: movapd %xmm1, %xmm0 427; STRICT-NEXT: retq 428; 429; RELAX-LABEL: uge: 430; RELAX: # %bb.0: 431; RELAX-NEXT: maxsd %xmm1, %xmm0 432; RELAX-NEXT: retq 433 %c = fcmp uge double %x, %y 434 %d = select i1 %c, double %x, double %y 435 ret double %d 436} 437 438define double @ule(double %x, double %y) { 439; STRICT-LABEL: ule: 440; STRICT: # %bb.0: 441; STRICT-NEXT: minsd %xmm0, %xmm1 442; STRICT-NEXT: movapd %xmm1, %xmm0 443; STRICT-NEXT: retq 444; 445; RELAX-LABEL: ule: 446; RELAX: # %bb.0: 447; RELAX-NEXT: minsd %xmm1, %xmm0 448; RELAX-NEXT: retq 449 %c = fcmp ule double %x, %y 450 %d = select i1 %c, double %x, double %y 451 ret double %d 452} 453 454define double @uge_inverse(double %x, double %y) { 455; STRICT-LABEL: uge_inverse: 456; STRICT: # %bb.0: 457; STRICT-NEXT: minsd %xmm1, %xmm0 458; STRICT-NEXT: retq 459; 460; UNSAFE-LABEL: uge_inverse: 461; UNSAFE: # %bb.0: 462; UNSAFE-NEXT: minsd %xmm1, %xmm0 463; UNSAFE-NEXT: retq 464; 465; FINITE-LABEL: uge_inverse: 466; FINITE: # %bb.0: 467; FINITE-NEXT: minsd %xmm0, %xmm1 468; FINITE-NEXT: movapd %xmm1, %xmm0 469; FINITE-NEXT: retq 470 %c = fcmp uge double %x, %y 471 %d = select i1 %c, double %y, double %x 472 ret double %d 473} 474 475define double @ule_inverse(double %x, double %y) { 476; STRICT-LABEL: ule_inverse: 477; STRICT: # %bb.0: 478; STRICT-NEXT: maxsd %xmm1, %xmm0 479; STRICT-NEXT: retq 480; 481; UNSAFE-LABEL: ule_inverse: 482; UNSAFE: # %bb.0: 483; UNSAFE-NEXT: maxsd %xmm1, %xmm0 484; UNSAFE-NEXT: retq 485; 486; FINITE-LABEL: ule_inverse: 487; FINITE: # %bb.0: 488; FINITE-NEXT: maxsd %xmm0, %xmm1 489; FINITE-NEXT: movapd %xmm1, %xmm0 490; FINITE-NEXT: retq 491 %c = fcmp ule double %x, %y 492 %d = select i1 %c, double %y, double %x 493 ret double %d 494} 495 496define double @ugt_x(double %x) { 497; STRICT-LABEL: ugt_x: 498; STRICT: # %bb.0: 499; STRICT-NEXT: xorpd %xmm1, %xmm1 500; STRICT-NEXT: movapd %xmm0, %xmm2 501; STRICT-NEXT: cmpnlesd %xmm1, %xmm2 502; STRICT-NEXT: andpd %xmm2, %xmm0 503; STRICT-NEXT: retq 504; 505; RELAX-LABEL: ugt_x: 506; RELAX: # %bb.0: 507; RELAX-NEXT: xorpd %xmm1, %xmm1 508; RELAX-NEXT: maxsd %xmm1, %xmm0 509; RELAX-NEXT: retq 510 %c = fcmp ugt double %x, 0.000000e+00 511 %d = select i1 %c, double %x, double 0.000000e+00 512 ret double %d 513} 514 515define double @ult_x(double %x) { 516; STRICT-LABEL: ult_x: 517; STRICT: # %bb.0: 518; STRICT-NEXT: xorpd %xmm1, %xmm1 519; STRICT-NEXT: cmpnlesd %xmm0, %xmm1 520; STRICT-NEXT: andpd %xmm1, %xmm0 521; STRICT-NEXT: retq 522; 523; RELAX-LABEL: ult_x: 524; RELAX: # %bb.0: 525; RELAX-NEXT: xorpd %xmm1, %xmm1 526; RELAX-NEXT: minsd %xmm1, %xmm0 527; RELAX-NEXT: retq 528 %c = fcmp ult double %x, 0.000000e+00 529 %d = select i1 %c, double %x, double 0.000000e+00 530 ret double %d 531} 532 533define double @ugt_inverse_x(double %x) { 534; STRICT-LABEL: ugt_inverse_x: 535; STRICT: # %bb.0: 536; STRICT-NEXT: xorpd %xmm2, %xmm2 537; STRICT-NEXT: movapd %xmm0, %xmm1 538; STRICT-NEXT: cmpnlesd %xmm2, %xmm1 539; STRICT-NEXT: andnpd %xmm0, %xmm1 540; STRICT-NEXT: movapd %xmm1, %xmm0 541; STRICT-NEXT: retq 542; 543; UNSAFE-LABEL: ugt_inverse_x: 544; UNSAFE: # %bb.0: 545; UNSAFE-NEXT: xorpd %xmm1, %xmm1 546; UNSAFE-NEXT: minsd %xmm1, %xmm0 547; UNSAFE-NEXT: retq 548; 549; FINITE-LABEL: ugt_inverse_x: 550; FINITE: # %bb.0: 551; FINITE-NEXT: xorpd %xmm1, %xmm1 552; FINITE-NEXT: minsd %xmm0, %xmm1 553; FINITE-NEXT: movapd %xmm1, %xmm0 554; FINITE-NEXT: retq 555 %c = fcmp ugt double %x, 0.000000e+00 556 %d = select i1 %c, double 0.000000e+00, double %x 557 ret double %d 558} 559 560define double @ult_inverse_x(double %x) { 561; STRICT-LABEL: ult_inverse_x: 562; STRICT: # %bb.0: 563; STRICT-NEXT: xorpd %xmm1, %xmm1 564; STRICT-NEXT: cmpnlesd %xmm0, %xmm1 565; STRICT-NEXT: andnpd %xmm0, %xmm1 566; STRICT-NEXT: movapd %xmm1, %xmm0 567; STRICT-NEXT: retq 568; 569; UNSAFE-LABEL: ult_inverse_x: 570; UNSAFE: # %bb.0: 571; UNSAFE-NEXT: xorpd %xmm1, %xmm1 572; UNSAFE-NEXT: maxsd %xmm1, %xmm0 573; UNSAFE-NEXT: retq 574; 575; FINITE-LABEL: ult_inverse_x: 576; FINITE: # %bb.0: 577; FINITE-NEXT: xorpd %xmm1, %xmm1 578; FINITE-NEXT: maxsd %xmm0, %xmm1 579; FINITE-NEXT: movapd %xmm1, %xmm0 580; FINITE-NEXT: retq 581 %c = fcmp ult double %x, 0.000000e+00 582 %d = select i1 %c, double 0.000000e+00, double %x 583 ret double %d 584} 585 586define double @uge_x(double %x) { 587; STRICT-LABEL: uge_x: 588; STRICT: # %bb.0: 589; STRICT-NEXT: xorpd %xmm1, %xmm1 590; STRICT-NEXT: maxsd %xmm0, %xmm1 591; STRICT-NEXT: movapd %xmm1, %xmm0 592; STRICT-NEXT: retq 593; 594; RELAX-LABEL: uge_x: 595; RELAX: # %bb.0: 596; RELAX-NEXT: xorpd %xmm1, %xmm1 597; RELAX-NEXT: maxsd %xmm1, %xmm0 598; RELAX-NEXT: retq 599 %c = fcmp uge double %x, 0.000000e+00 600 %d = select i1 %c, double %x, double 0.000000e+00 601 ret double %d 602} 603 604define double @ule_x(double %x) { 605; STRICT-LABEL: ule_x: 606; STRICT: # %bb.0: 607; STRICT-NEXT: xorpd %xmm1, %xmm1 608; STRICT-NEXT: minsd %xmm0, %xmm1 609; STRICT-NEXT: movapd %xmm1, %xmm0 610; STRICT-NEXT: retq 611; 612; RELAX-LABEL: ule_x: 613; RELAX: # %bb.0: 614; RELAX-NEXT: xorpd %xmm1, %xmm1 615; RELAX-NEXT: minsd %xmm1, %xmm0 616; RELAX-NEXT: retq 617 %c = fcmp ule double %x, 0.000000e+00 618 %d = select i1 %c, double %x, double 0.000000e+00 619 ret double %d 620} 621 622define double @uge_inverse_x(double %x) { 623; STRICT-LABEL: uge_inverse_x: 624; STRICT: # %bb.0: 625; STRICT-NEXT: xorpd %xmm1, %xmm1 626; STRICT-NEXT: minsd %xmm1, %xmm0 627; STRICT-NEXT: retq 628; 629; UNSAFE-LABEL: uge_inverse_x: 630; UNSAFE: # %bb.0: 631; UNSAFE-NEXT: xorpd %xmm1, %xmm1 632; UNSAFE-NEXT: minsd %xmm1, %xmm0 633; UNSAFE-NEXT: retq 634; 635; FINITE-LABEL: uge_inverse_x: 636; FINITE: # %bb.0: 637; FINITE-NEXT: xorpd %xmm1, %xmm1 638; FINITE-NEXT: minsd %xmm0, %xmm1 639; FINITE-NEXT: movapd %xmm1, %xmm0 640; FINITE-NEXT: retq 641 %c = fcmp uge double %x, 0.000000e+00 642 %d = select i1 %c, double 0.000000e+00, double %x 643 ret double %d 644} 645 646define double @ule_inverse_x(double %x) { 647; STRICT-LABEL: ule_inverse_x: 648; STRICT: # %bb.0: 649; STRICT-NEXT: xorpd %xmm1, %xmm1 650; STRICT-NEXT: maxsd %xmm1, %xmm0 651; STRICT-NEXT: retq 652; 653; UNSAFE-LABEL: ule_inverse_x: 654; UNSAFE: # %bb.0: 655; UNSAFE-NEXT: xorpd %xmm1, %xmm1 656; UNSAFE-NEXT: maxsd %xmm1, %xmm0 657; UNSAFE-NEXT: retq 658; 659; FINITE-LABEL: ule_inverse_x: 660; FINITE: # %bb.0: 661; FINITE-NEXT: xorpd %xmm1, %xmm1 662; FINITE-NEXT: maxsd %xmm0, %xmm1 663; FINITE-NEXT: movapd %xmm1, %xmm0 664; FINITE-NEXT: retq 665 %c = fcmp ule double %x, 0.000000e+00 666 %d = select i1 %c, double 0.000000e+00, double %x 667 ret double %d 668} 669 670define double @ogt_y(double %x) { 671; ALL-LABEL: ogt_y: 672; ALL: # %bb.0: 673; ALL-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 674; ALL-NEXT: retq 675 %c = fcmp ogt double %x, -0.000000e+00 676 %d = select i1 %c, double %x, double -0.000000e+00 677 ret double %d 678} 679 680define double @olt_y(double %x) { 681; ALL-LABEL: olt_y: 682; ALL: # %bb.0: 683; ALL-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 684; ALL-NEXT: retq 685 %c = fcmp olt double %x, -0.000000e+00 686 %d = select i1 %c, double %x, double -0.000000e+00 687 ret double %d 688} 689 690define double @ogt_inverse_y(double %x) { 691; STRICT-LABEL: ogt_inverse_y: 692; STRICT: # %bb.0: 693; STRICT-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 694; STRICT-NEXT: minsd %xmm0, %xmm1 695; STRICT-NEXT: movapd %xmm1, %xmm0 696; STRICT-NEXT: retq 697; 698; UNSAFE-LABEL: ogt_inverse_y: 699; UNSAFE: # %bb.0: 700; UNSAFE-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 701; UNSAFE-NEXT: retq 702; 703; FINITE-LABEL: ogt_inverse_y: 704; FINITE: # %bb.0: 705; FINITE-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 706; FINITE-NEXT: minsd %xmm0, %xmm1 707; FINITE-NEXT: movapd %xmm1, %xmm0 708; FINITE-NEXT: retq 709 %c = fcmp ogt double %x, -0.000000e+00 710 %d = select i1 %c, double -0.000000e+00, double %x 711 ret double %d 712} 713 714define double @olt_inverse_y(double %x) { 715; STRICT-LABEL: olt_inverse_y: 716; STRICT: # %bb.0: 717; STRICT-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 718; STRICT-NEXT: maxsd %xmm0, %xmm1 719; STRICT-NEXT: movapd %xmm1, %xmm0 720; STRICT-NEXT: retq 721; 722; UNSAFE-LABEL: olt_inverse_y: 723; UNSAFE: # %bb.0: 724; UNSAFE-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 725; UNSAFE-NEXT: retq 726; 727; FINITE-LABEL: olt_inverse_y: 728; FINITE: # %bb.0: 729; FINITE-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 730; FINITE-NEXT: maxsd %xmm0, %xmm1 731; FINITE-NEXT: movapd %xmm1, %xmm0 732; FINITE-NEXT: retq 733 %c = fcmp olt double %x, -0.000000e+00 734 %d = select i1 %c, double -0.000000e+00, double %x 735 ret double %d 736} 737 738define double @oge_y(double %x) { 739; STRICT-LABEL: oge_y: 740; STRICT: # %bb.0: 741; STRICT-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 742; STRICT-NEXT: movapd %xmm1, %xmm2 743; STRICT-NEXT: cmplesd %xmm0, %xmm2 744; STRICT-NEXT: andpd %xmm2, %xmm0 745; STRICT-NEXT: andnpd %xmm1, %xmm2 746; STRICT-NEXT: orpd %xmm2, %xmm0 747; STRICT-NEXT: retq 748; 749; RELAX-LABEL: oge_y: 750; RELAX: # %bb.0: 751; RELAX-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 752; RELAX-NEXT: retq 753 %c = fcmp oge double %x, -0.000000e+00 754 %d = select i1 %c, double %x, double -0.000000e+00 755 ret double %d 756} 757 758define double @ole_y(double %x) { 759; STRICT-LABEL: ole_y: 760; STRICT: # %bb.0: 761; STRICT-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 762; STRICT-NEXT: movapd %xmm0, %xmm2 763; STRICT-NEXT: cmplesd %xmm1, %xmm2 764; STRICT-NEXT: andpd %xmm2, %xmm0 765; STRICT-NEXT: andnpd %xmm1, %xmm2 766; STRICT-NEXT: orpd %xmm2, %xmm0 767; STRICT-NEXT: retq 768; 769; RELAX-LABEL: ole_y: 770; RELAX: # %bb.0: 771; RELAX-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 772; RELAX-NEXT: retq 773 %c = fcmp ole double %x, -0.000000e+00 774 %d = select i1 %c, double %x, double -0.000000e+00 775 ret double %d 776} 777 778define double @oge_inverse_y(double %x) { 779; STRICT-LABEL: oge_inverse_y: 780; STRICT: # %bb.0: 781; STRICT-NEXT: movsd {{.*#+}} xmm2 = [-0.0E+0,0.0E+0] 782; STRICT-NEXT: movapd %xmm2, %xmm1 783; STRICT-NEXT: cmplesd %xmm0, %xmm1 784; STRICT-NEXT: andpd %xmm1, %xmm2 785; STRICT-NEXT: andnpd %xmm0, %xmm1 786; STRICT-NEXT: orpd %xmm2, %xmm1 787; STRICT-NEXT: movapd %xmm1, %xmm0 788; STRICT-NEXT: retq 789; 790; UNSAFE-LABEL: oge_inverse_y: 791; UNSAFE: # %bb.0: 792; UNSAFE-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 793; UNSAFE-NEXT: retq 794; 795; FINITE-LABEL: oge_inverse_y: 796; FINITE: # %bb.0: 797; FINITE-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 798; FINITE-NEXT: minsd %xmm0, %xmm1 799; FINITE-NEXT: movapd %xmm1, %xmm0 800; FINITE-NEXT: retq 801 %c = fcmp oge double %x, -0.000000e+00 802 %d = select i1 %c, double -0.000000e+00, double %x 803 ret double %d 804} 805 806define double @ole_inverse_y(double %x) { 807; STRICT-LABEL: ole_inverse_y: 808; STRICT: # %bb.0: 809; STRICT-NEXT: movsd {{.*#+}} xmm2 = [-0.0E+0,0.0E+0] 810; STRICT-NEXT: movapd %xmm0, %xmm1 811; STRICT-NEXT: cmplesd %xmm2, %xmm1 812; STRICT-NEXT: andpd %xmm1, %xmm2 813; STRICT-NEXT: andnpd %xmm0, %xmm1 814; STRICT-NEXT: orpd %xmm2, %xmm1 815; STRICT-NEXT: movapd %xmm1, %xmm0 816; STRICT-NEXT: retq 817; 818; UNSAFE-LABEL: ole_inverse_y: 819; UNSAFE: # %bb.0: 820; UNSAFE-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 821; UNSAFE-NEXT: retq 822; 823; FINITE-LABEL: ole_inverse_y: 824; FINITE: # %bb.0: 825; FINITE-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 826; FINITE-NEXT: maxsd %xmm0, %xmm1 827; FINITE-NEXT: movapd %xmm1, %xmm0 828; FINITE-NEXT: retq 829 %c = fcmp ole double %x, -0.000000e+00 830 %d = select i1 %c, double -0.000000e+00, double %x 831 ret double %d 832} 833 834define double @ugt_y(double %x) { 835; STRICT-LABEL: ugt_y: 836; STRICT: # %bb.0: 837; STRICT-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 838; STRICT-NEXT: movapd %xmm0, %xmm2 839; STRICT-NEXT: cmpnlesd %xmm1, %xmm2 840; STRICT-NEXT: andpd %xmm2, %xmm0 841; STRICT-NEXT: andnpd %xmm1, %xmm2 842; STRICT-NEXT: orpd %xmm2, %xmm0 843; STRICT-NEXT: retq 844; 845; RELAX-LABEL: ugt_y: 846; RELAX: # %bb.0: 847; RELAX-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 848; RELAX-NEXT: retq 849 %c = fcmp ugt double %x, -0.000000e+00 850 %d = select i1 %c, double %x, double -0.000000e+00 851 ret double %d 852} 853 854define double @ult_y(double %x) { 855; STRICT-LABEL: ult_y: 856; STRICT: # %bb.0: 857; STRICT-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 858; STRICT-NEXT: movapd %xmm1, %xmm2 859; STRICT-NEXT: cmpnlesd %xmm0, %xmm2 860; STRICT-NEXT: andpd %xmm2, %xmm0 861; STRICT-NEXT: andnpd %xmm1, %xmm2 862; STRICT-NEXT: orpd %xmm2, %xmm0 863; STRICT-NEXT: retq 864; 865; RELAX-LABEL: ult_y: 866; RELAX: # %bb.0: 867; RELAX-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 868; RELAX-NEXT: retq 869 %c = fcmp ult double %x, -0.000000e+00 870 %d = select i1 %c, double %x, double -0.000000e+00 871 ret double %d 872} 873 874define double @ugt_inverse_y(double %x) { 875; STRICT-LABEL: ugt_inverse_y: 876; STRICT: # %bb.0: 877; STRICT-NEXT: movsd {{.*#+}} xmm2 = [-0.0E+0,0.0E+0] 878; STRICT-NEXT: movapd %xmm0, %xmm1 879; STRICT-NEXT: cmpnlesd %xmm2, %xmm1 880; STRICT-NEXT: andpd %xmm1, %xmm2 881; STRICT-NEXT: andnpd %xmm0, %xmm1 882; STRICT-NEXT: orpd %xmm2, %xmm1 883; STRICT-NEXT: movapd %xmm1, %xmm0 884; STRICT-NEXT: retq 885; 886; UNSAFE-LABEL: ugt_inverse_y: 887; UNSAFE: # %bb.0: 888; UNSAFE-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 889; UNSAFE-NEXT: retq 890; 891; FINITE-LABEL: ugt_inverse_y: 892; FINITE: # %bb.0: 893; FINITE-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 894; FINITE-NEXT: minsd %xmm0, %xmm1 895; FINITE-NEXT: movapd %xmm1, %xmm0 896; FINITE-NEXT: retq 897 %c = fcmp ugt double %x, -0.000000e+00 898 %d = select i1 %c, double -0.000000e+00, double %x 899 ret double %d 900} 901 902define double @ult_inverse_y(double %x) { 903; STRICT-LABEL: ult_inverse_y: 904; STRICT: # %bb.0: 905; STRICT-NEXT: movsd {{.*#+}} xmm2 = [-0.0E+0,0.0E+0] 906; STRICT-NEXT: movapd %xmm2, %xmm1 907; STRICT-NEXT: cmpnlesd %xmm0, %xmm1 908; STRICT-NEXT: andpd %xmm1, %xmm2 909; STRICT-NEXT: andnpd %xmm0, %xmm1 910; STRICT-NEXT: orpd %xmm2, %xmm1 911; STRICT-NEXT: movapd %xmm1, %xmm0 912; STRICT-NEXT: retq 913; 914; UNSAFE-LABEL: ult_inverse_y: 915; UNSAFE: # %bb.0: 916; UNSAFE-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 917; UNSAFE-NEXT: retq 918; 919; FINITE-LABEL: ult_inverse_y: 920; FINITE: # %bb.0: 921; FINITE-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 922; FINITE-NEXT: maxsd %xmm0, %xmm1 923; FINITE-NEXT: movapd %xmm1, %xmm0 924; FINITE-NEXT: retq 925 %c = fcmp ult double %x, -0.000000e+00 926 %d = select i1 %c, double -0.000000e+00, double %x 927 ret double %d 928} 929 930define double @uge_y(double %x) { 931; STRICT-LABEL: uge_y: 932; STRICT: # %bb.0: 933; STRICT-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 934; STRICT-NEXT: maxsd %xmm0, %xmm1 935; STRICT-NEXT: movapd %xmm1, %xmm0 936; STRICT-NEXT: retq 937; 938; RELAX-LABEL: uge_y: 939; RELAX: # %bb.0: 940; RELAX-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 941; RELAX-NEXT: retq 942 %c = fcmp uge double %x, -0.000000e+00 943 %d = select i1 %c, double %x, double -0.000000e+00 944 ret double %d 945} 946 947define double @ule_y(double %x) { 948; STRICT-LABEL: ule_y: 949; STRICT: # %bb.0: 950; STRICT-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 951; STRICT-NEXT: minsd %xmm0, %xmm1 952; STRICT-NEXT: movapd %xmm1, %xmm0 953; STRICT-NEXT: retq 954; 955; RELAX-LABEL: ule_y: 956; RELAX: # %bb.0: 957; RELAX-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 958; RELAX-NEXT: retq 959 %c = fcmp ule double %x, -0.000000e+00 960 %d = select i1 %c, double %x, double -0.000000e+00 961 ret double %d 962} 963 964define double @uge_inverse_y(double %x) { 965; STRICT-LABEL: uge_inverse_y: 966; STRICT: # %bb.0: 967; STRICT-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 968; STRICT-NEXT: retq 969; 970; UNSAFE-LABEL: uge_inverse_y: 971; UNSAFE: # %bb.0: 972; UNSAFE-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 973; UNSAFE-NEXT: retq 974; 975; FINITE-LABEL: uge_inverse_y: 976; FINITE: # %bb.0: 977; FINITE-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 978; FINITE-NEXT: minsd %xmm0, %xmm1 979; FINITE-NEXT: movapd %xmm1, %xmm0 980; FINITE-NEXT: retq 981 %c = fcmp uge double %x, -0.000000e+00 982 %d = select i1 %c, double -0.000000e+00, double %x 983 ret double %d 984} 985 986define double @ule_inverse_y(double %x) { 987; STRICT-LABEL: ule_inverse_y: 988; STRICT: # %bb.0: 989; STRICT-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 990; STRICT-NEXT: retq 991; 992; UNSAFE-LABEL: ule_inverse_y: 993; UNSAFE: # %bb.0: 994; UNSAFE-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 995; UNSAFE-NEXT: retq 996; 997; FINITE-LABEL: ule_inverse_y: 998; FINITE: # %bb.0: 999; FINITE-NEXT: movsd {{.*#+}} xmm1 = [-0.0E+0,0.0E+0] 1000; FINITE-NEXT: maxsd %xmm0, %xmm1 1001; FINITE-NEXT: movapd %xmm1, %xmm0 1002; FINITE-NEXT: retq 1003 %c = fcmp ule double %x, -0.000000e+00 1004 %d = select i1 %c, double -0.000000e+00, double %x 1005 ret double %d 1006} 1007 1008; Test a few more misc. cases. 1009 1010define double @clampTo3k_a(double %x) { 1011; STRICT-LABEL: clampTo3k_a: 1012; STRICT: # %bb.0: 1013; STRICT-NEXT: movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0] 1014; STRICT-NEXT: minsd %xmm0, %xmm1 1015; STRICT-NEXT: movapd %xmm1, %xmm0 1016; STRICT-NEXT: retq 1017; 1018; UNSAFE-LABEL: clampTo3k_a: 1019; UNSAFE: # %bb.0: 1020; UNSAFE-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 1021; UNSAFE-NEXT: retq 1022; 1023; FINITE-LABEL: clampTo3k_a: 1024; FINITE: # %bb.0: 1025; FINITE-NEXT: movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0] 1026; FINITE-NEXT: minsd %xmm0, %xmm1 1027; FINITE-NEXT: movapd %xmm1, %xmm0 1028; FINITE-NEXT: retq 1029 %t0 = fcmp ogt double %x, 3.000000e+03 1030 %y = select i1 %t0, double 3.000000e+03, double %x 1031 ret double %y 1032} 1033 1034define double @clampTo3k_b(double %x) { 1035; STRICT-LABEL: clampTo3k_b: 1036; STRICT: # %bb.0: 1037; STRICT-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 1038; STRICT-NEXT: retq 1039; 1040; UNSAFE-LABEL: clampTo3k_b: 1041; UNSAFE: # %bb.0: 1042; UNSAFE-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 1043; UNSAFE-NEXT: retq 1044; 1045; FINITE-LABEL: clampTo3k_b: 1046; FINITE: # %bb.0: 1047; FINITE-NEXT: movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0] 1048; FINITE-NEXT: minsd %xmm0, %xmm1 1049; FINITE-NEXT: movapd %xmm1, %xmm0 1050; FINITE-NEXT: retq 1051 %t0 = fcmp uge double %x, 3.000000e+03 1052 %y = select i1 %t0, double 3.000000e+03, double %x 1053 ret double %y 1054} 1055 1056define double @clampTo3k_c(double %x) { 1057; STRICT-LABEL: clampTo3k_c: 1058; STRICT: # %bb.0: 1059; STRICT-NEXT: movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0] 1060; STRICT-NEXT: maxsd %xmm0, %xmm1 1061; STRICT-NEXT: movapd %xmm1, %xmm0 1062; STRICT-NEXT: retq 1063; 1064; UNSAFE-LABEL: clampTo3k_c: 1065; UNSAFE: # %bb.0: 1066; UNSAFE-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 1067; UNSAFE-NEXT: retq 1068; 1069; FINITE-LABEL: clampTo3k_c: 1070; FINITE: # %bb.0: 1071; FINITE-NEXT: movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0] 1072; FINITE-NEXT: maxsd %xmm0, %xmm1 1073; FINITE-NEXT: movapd %xmm1, %xmm0 1074; FINITE-NEXT: retq 1075 %t0 = fcmp olt double %x, 3.000000e+03 1076 %y = select i1 %t0, double 3.000000e+03, double %x 1077 ret double %y 1078} 1079 1080define double @clampTo3k_d(double %x) { 1081; STRICT-LABEL: clampTo3k_d: 1082; STRICT: # %bb.0: 1083; STRICT-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 1084; STRICT-NEXT: retq 1085; 1086; UNSAFE-LABEL: clampTo3k_d: 1087; UNSAFE: # %bb.0: 1088; UNSAFE-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 1089; UNSAFE-NEXT: retq 1090; 1091; FINITE-LABEL: clampTo3k_d: 1092; FINITE: # %bb.0: 1093; FINITE-NEXT: movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0] 1094; FINITE-NEXT: maxsd %xmm0, %xmm1 1095; FINITE-NEXT: movapd %xmm1, %xmm0 1096; FINITE-NEXT: retq 1097 %t0 = fcmp ule double %x, 3.000000e+03 1098 %y = select i1 %t0, double 3.000000e+03, double %x 1099 ret double %y 1100} 1101 1102define double @clampTo3k_e(double %x) { 1103; STRICT-LABEL: clampTo3k_e: 1104; STRICT: # %bb.0: 1105; STRICT-NEXT: movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0] 1106; STRICT-NEXT: maxsd %xmm0, %xmm1 1107; STRICT-NEXT: movapd %xmm1, %xmm0 1108; STRICT-NEXT: retq 1109; 1110; UNSAFE-LABEL: clampTo3k_e: 1111; UNSAFE: # %bb.0: 1112; UNSAFE-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 1113; UNSAFE-NEXT: retq 1114; 1115; FINITE-LABEL: clampTo3k_e: 1116; FINITE: # %bb.0: 1117; FINITE-NEXT: movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0] 1118; FINITE-NEXT: maxsd %xmm0, %xmm1 1119; FINITE-NEXT: movapd %xmm1, %xmm0 1120; FINITE-NEXT: retq 1121 %t0 = fcmp olt double %x, 3.000000e+03 1122 %y = select i1 %t0, double 3.000000e+03, double %x 1123 ret double %y 1124} 1125 1126define double @clampTo3k_f(double %x) { 1127; STRICT-LABEL: clampTo3k_f: 1128; STRICT: # %bb.0: 1129; STRICT-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 1130; STRICT-NEXT: retq 1131; 1132; UNSAFE-LABEL: clampTo3k_f: 1133; UNSAFE: # %bb.0: 1134; UNSAFE-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 1135; UNSAFE-NEXT: retq 1136; 1137; FINITE-LABEL: clampTo3k_f: 1138; FINITE: # %bb.0: 1139; FINITE-NEXT: movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0] 1140; FINITE-NEXT: maxsd %xmm0, %xmm1 1141; FINITE-NEXT: movapd %xmm1, %xmm0 1142; FINITE-NEXT: retq 1143 %t0 = fcmp ule double %x, 3.000000e+03 1144 %y = select i1 %t0, double 3.000000e+03, double %x 1145 ret double %y 1146} 1147 1148define double @clampTo3k_g(double %x) { 1149; STRICT-LABEL: clampTo3k_g: 1150; STRICT: # %bb.0: 1151; STRICT-NEXT: movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0] 1152; STRICT-NEXT: minsd %xmm0, %xmm1 1153; STRICT-NEXT: movapd %xmm1, %xmm0 1154; STRICT-NEXT: retq 1155; 1156; UNSAFE-LABEL: clampTo3k_g: 1157; UNSAFE: # %bb.0: 1158; UNSAFE-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 1159; UNSAFE-NEXT: retq 1160; 1161; FINITE-LABEL: clampTo3k_g: 1162; FINITE: # %bb.0: 1163; FINITE-NEXT: movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0] 1164; FINITE-NEXT: minsd %xmm0, %xmm1 1165; FINITE-NEXT: movapd %xmm1, %xmm0 1166; FINITE-NEXT: retq 1167 %t0 = fcmp ogt double %x, 3.000000e+03 1168 %y = select i1 %t0, double 3.000000e+03, double %x 1169 ret double %y 1170} 1171 1172define double @clampTo3k_h(double %x) { 1173; STRICT-LABEL: clampTo3k_h: 1174; STRICT: # %bb.0: 1175; STRICT-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 1176; STRICT-NEXT: retq 1177; 1178; UNSAFE-LABEL: clampTo3k_h: 1179; UNSAFE: # %bb.0: 1180; UNSAFE-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 1181; UNSAFE-NEXT: retq 1182; 1183; FINITE-LABEL: clampTo3k_h: 1184; FINITE: # %bb.0: 1185; FINITE-NEXT: movsd {{.*#+}} xmm1 = [3.0E+3,0.0E+0] 1186; FINITE-NEXT: minsd %xmm0, %xmm1 1187; FINITE-NEXT: movapd %xmm1, %xmm0 1188; FINITE-NEXT: retq 1189 %t0 = fcmp uge double %x, 3.000000e+03 1190 %y = select i1 %t0, double 3.000000e+03, double %x 1191 ret double %y 1192} 1193 1194define <2 x double> @test_maxpd(<2 x double> %x, <2 x double> %y) { 1195; STRICT-LABEL: test_maxpd: 1196; STRICT: # %bb.0: 1197; STRICT-NEXT: movapd %xmm0, %xmm2 1198; STRICT-NEXT: movapd %xmm1, %xmm0 1199; STRICT-NEXT: cmplepd %xmm2, %xmm0 1200; STRICT-NEXT: blendvpd %xmm0, %xmm2, %xmm1 1201; STRICT-NEXT: movapd %xmm1, %xmm0 1202; STRICT-NEXT: retq 1203; 1204; RELAX-LABEL: test_maxpd: 1205; RELAX: # %bb.0: 1206; RELAX-NEXT: maxpd %xmm1, %xmm0 1207; RELAX-NEXT: retq 1208 %max_is_x = fcmp oge <2 x double> %x, %y 1209 %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y 1210 ret <2 x double> %max 1211} 1212 1213define <2 x double> @test_minpd(<2 x double> %x, <2 x double> %y) { 1214; STRICT-LABEL: test_minpd: 1215; STRICT: # %bb.0: 1216; STRICT-NEXT: movapd %xmm0, %xmm2 1217; STRICT-NEXT: cmplepd %xmm1, %xmm0 1218; STRICT-NEXT: blendvpd %xmm0, %xmm2, %xmm1 1219; STRICT-NEXT: movapd %xmm1, %xmm0 1220; STRICT-NEXT: retq 1221; 1222; RELAX-LABEL: test_minpd: 1223; RELAX: # %bb.0: 1224; RELAX-NEXT: minpd %xmm1, %xmm0 1225; RELAX-NEXT: retq 1226 %min_is_x = fcmp ole <2 x double> %x, %y 1227 %min = select <2 x i1> %min_is_x, <2 x double> %x, <2 x double> %y 1228 ret <2 x double> %min 1229} 1230 1231define <4 x float> @test_maxps(<4 x float> %x, <4 x float> %y) { 1232; STRICT-LABEL: test_maxps: 1233; STRICT: # %bb.0: 1234; STRICT-NEXT: movaps %xmm0, %xmm2 1235; STRICT-NEXT: movaps %xmm1, %xmm0 1236; STRICT-NEXT: cmpleps %xmm2, %xmm0 1237; STRICT-NEXT: blendvps %xmm0, %xmm2, %xmm1 1238; STRICT-NEXT: movaps %xmm1, %xmm0 1239; STRICT-NEXT: retq 1240; 1241; RELAX-LABEL: test_maxps: 1242; RELAX: # %bb.0: 1243; RELAX-NEXT: maxps %xmm1, %xmm0 1244; RELAX-NEXT: retq 1245 %max_is_x = fcmp oge <4 x float> %x, %y 1246 %max = select <4 x i1> %max_is_x, <4 x float> %x, <4 x float> %y 1247 ret <4 x float> %max 1248} 1249 1250define <4 x float> @test_minps(<4 x float> %x, <4 x float> %y) { 1251; STRICT-LABEL: test_minps: 1252; STRICT: # %bb.0: 1253; STRICT-NEXT: movaps %xmm0, %xmm2 1254; STRICT-NEXT: cmpleps %xmm1, %xmm0 1255; STRICT-NEXT: blendvps %xmm0, %xmm2, %xmm1 1256; STRICT-NEXT: movaps %xmm1, %xmm0 1257; STRICT-NEXT: retq 1258; 1259; RELAX-LABEL: test_minps: 1260; RELAX: # %bb.0: 1261; RELAX-NEXT: minps %xmm1, %xmm0 1262; RELAX-NEXT: retq 1263 %min_is_x = fcmp ole <4 x float> %x, %y 1264 %min = select <4 x i1> %min_is_x, <4 x float> %x, <4 x float> %y 1265 ret <4 x float> %min 1266} 1267 1268define <2 x float> @test_maxps_illegal_v2f32(<2 x float> %x, <2 x float> %y) { 1269; STRICT-LABEL: test_maxps_illegal_v2f32: 1270; STRICT: # %bb.0: 1271; STRICT-NEXT: movaps %xmm0, %xmm2 1272; STRICT-NEXT: movaps %xmm1, %xmm0 1273; STRICT-NEXT: cmpleps %xmm2, %xmm0 1274; STRICT-NEXT: blendvps %xmm0, %xmm2, %xmm1 1275; STRICT-NEXT: movaps %xmm1, %xmm0 1276; STRICT-NEXT: retq 1277; 1278; RELAX-LABEL: test_maxps_illegal_v2f32: 1279; RELAX: # %bb.0: 1280; RELAX-NEXT: maxps %xmm1, %xmm0 1281; RELAX-NEXT: retq 1282 %max_is_x = fcmp oge <2 x float> %x, %y 1283 %max = select <2 x i1> %max_is_x, <2 x float> %x, <2 x float> %y 1284 ret <2 x float> %max 1285} 1286 1287define <2 x float> @test_minps_illegal_v2f32(<2 x float> %x, <2 x float> %y) { 1288; STRICT-LABEL: test_minps_illegal_v2f32: 1289; STRICT: # %bb.0: 1290; STRICT-NEXT: movaps %xmm0, %xmm2 1291; STRICT-NEXT: cmpleps %xmm1, %xmm0 1292; STRICT-NEXT: blendvps %xmm0, %xmm2, %xmm1 1293; STRICT-NEXT: movaps %xmm1, %xmm0 1294; STRICT-NEXT: retq 1295; 1296; RELAX-LABEL: test_minps_illegal_v2f32: 1297; RELAX: # %bb.0: 1298; RELAX-NEXT: minps %xmm1, %xmm0 1299; RELAX-NEXT: retq 1300 %min_is_x = fcmp ole <2 x float> %x, %y 1301 %min = select <2 x i1> %min_is_x, <2 x float> %x, <2 x float> %y 1302 ret <2 x float> %min 1303} 1304 1305define <3 x float> @test_maxps_illegal_v3f32(<3 x float> %x, <3 x float> %y) { 1306; STRICT-LABEL: test_maxps_illegal_v3f32: 1307; STRICT: # %bb.0: 1308; STRICT-NEXT: movaps %xmm0, %xmm2 1309; STRICT-NEXT: movaps %xmm1, %xmm0 1310; STRICT-NEXT: cmpleps %xmm2, %xmm0 1311; STRICT-NEXT: blendvps %xmm0, %xmm2, %xmm1 1312; STRICT-NEXT: movaps %xmm1, %xmm0 1313; STRICT-NEXT: retq 1314; 1315; RELAX-LABEL: test_maxps_illegal_v3f32: 1316; RELAX: # %bb.0: 1317; RELAX-NEXT: maxps %xmm1, %xmm0 1318; RELAX-NEXT: retq 1319 %max_is_x = fcmp oge <3 x float> %x, %y 1320 %max = select <3 x i1> %max_is_x, <3 x float> %x, <3 x float> %y 1321 ret <3 x float> %max 1322} 1323 1324define <3 x float> @test_minps_illegal_v3f32(<3 x float> %x, <3 x float> %y) { 1325; STRICT-LABEL: test_minps_illegal_v3f32: 1326; STRICT: # %bb.0: 1327; STRICT-NEXT: movaps %xmm0, %xmm2 1328; STRICT-NEXT: cmpleps %xmm1, %xmm0 1329; STRICT-NEXT: blendvps %xmm0, %xmm2, %xmm1 1330; STRICT-NEXT: movaps %xmm1, %xmm0 1331; STRICT-NEXT: retq 1332; 1333; RELAX-LABEL: test_minps_illegal_v3f32: 1334; RELAX: # %bb.0: 1335; RELAX-NEXT: minps %xmm1, %xmm0 1336; RELAX-NEXT: retq 1337 %min_is_x = fcmp ole <3 x float> %x, %y 1338 %min = select <3 x i1> %min_is_x, <3 x float> %x, <3 x float> %y 1339 ret <3 x float> %min 1340} 1341 1342; OSS-Fuzz #13838 1343; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13838 1344define float @ossfuzz13838(float %x) { 1345; ALL-LABEL: ossfuzz13838: 1346; ALL: # %bb.0: # %bb 1347; ALL-NEXT: movss {{.*#+}} xmm0 = [2.55E+2,0.0E+0,0.0E+0,0.0E+0] 1348; ALL-NEXT: retq 1349bb: 1350 %cmp2 = fcmp fast olt float %x, 2.550000e+02 1351 %B1 = urem i1 %cmp2, %cmp2 1352 %min = select i1 %B1, float %x, float 2.550000e+02 1353 %B = frem float %min, 0x47EFFFFFE0000000 1354 %cmp1 = fcmp fast olt float %B, 1.000000e+00 1355 %r = select i1 %cmp1, float 1.000000e+00, float %min 1356 ret float %r 1357} 1358