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