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