1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s 3 4; i32 saturate 5 6define i32 @stest_f64i32(double %x) nounwind { 7; CHECK-LABEL: stest_f64i32: 8; CHECK: # %bb.0: # %entry 9; CHECK-NEXT: xorl %eax, %eax 10; CHECK-NEXT: ucomisd %xmm0, %xmm0 11; CHECK-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 12; CHECK-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 13; CHECK-NEXT: cvttsd2si %xmm0, %ecx 14; CHECK-NEXT: cmovnpl %ecx, %eax 15; CHECK-NEXT: retq 16entry: 17 %conv = fptosi double %x to i64 18 %0 = icmp slt i64 %conv, 2147483647 19 %spec.store.select = select i1 %0, i64 %conv, i64 2147483647 20 %1 = icmp sgt i64 %spec.store.select, -2147483648 21 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 -2147483648 22 %conv6 = trunc i64 %spec.store.select7 to i32 23 ret i32 %conv6 24} 25 26define i32 @utest_f64i32(double %x) nounwind { 27; CHECK-LABEL: utest_f64i32: 28; CHECK: # %bb.0: # %entry 29; CHECK-NEXT: cvttsd2si %xmm0, %rax 30; CHECK-NEXT: movq %rax, %rcx 31; CHECK-NEXT: sarq $63, %rcx 32; CHECK-NEXT: subsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 33; CHECK-NEXT: cvttsd2si %xmm0, %rdx 34; CHECK-NEXT: andq %rcx, %rdx 35; CHECK-NEXT: orq %rax, %rdx 36; CHECK-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF 37; CHECK-NEXT: cmpq %rax, %rdx 38; CHECK-NEXT: movl $-1, %eax 39; CHECK-NEXT: cmovbl %edx, %eax 40; CHECK-NEXT: retq 41entry: 42 %conv = fptoui double %x to i64 43 %0 = icmp ult i64 %conv, 4294967295 44 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 45 %conv6 = trunc i64 %spec.store.select to i32 46 ret i32 %conv6 47} 48 49define i32 @ustest_f64i32(double %x) nounwind { 50; CHECK-LABEL: ustest_f64i32: 51; CHECK: # %bb.0: # %entry 52; CHECK-NEXT: cvttsd2si %xmm0, %rcx 53; CHECK-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF 54; CHECK-NEXT: cmpq %rax, %rcx 55; CHECK-NEXT: cmovlq %rcx, %rax 56; CHECK-NEXT: xorl %ecx, %ecx 57; CHECK-NEXT: testq %rax, %rax 58; CHECK-NEXT: cmovlel %ecx, %eax 59; CHECK-NEXT: # kill: def $eax killed $eax killed $rax 60; CHECK-NEXT: retq 61entry: 62 %conv = fptosi double %x to i64 63 %0 = icmp slt i64 %conv, 4294967295 64 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 65 %1 = icmp sgt i64 %spec.store.select, 0 66 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 0 67 %conv6 = trunc i64 %spec.store.select7 to i32 68 ret i32 %conv6 69} 70 71define i32 @stest_f32i32(float %x) nounwind { 72; CHECK-LABEL: stest_f32i32: 73; CHECK: # %bb.0: # %entry 74; CHECK-NEXT: cvttss2si %xmm0, %eax 75; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 76; CHECK-NEXT: movl $2147483647, %ecx # imm = 0x7FFFFFFF 77; CHECK-NEXT: cmovbel %eax, %ecx 78; CHECK-NEXT: xorl %eax, %eax 79; CHECK-NEXT: ucomiss %xmm0, %xmm0 80; CHECK-NEXT: cmovnpl %ecx, %eax 81; CHECK-NEXT: retq 82entry: 83 %conv = fptosi float %x to i64 84 %0 = icmp slt i64 %conv, 2147483647 85 %spec.store.select = select i1 %0, i64 %conv, i64 2147483647 86 %1 = icmp sgt i64 %spec.store.select, -2147483648 87 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 -2147483648 88 %conv6 = trunc i64 %spec.store.select7 to i32 89 ret i32 %conv6 90} 91 92define i32 @utest_f32i32(float %x) nounwind { 93; CHECK-LABEL: utest_f32i32: 94; CHECK: # %bb.0: # %entry 95; CHECK-NEXT: cvttss2si %xmm0, %rax 96; CHECK-NEXT: movq %rax, %rcx 97; CHECK-NEXT: sarq $63, %rcx 98; CHECK-NEXT: subss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 99; CHECK-NEXT: cvttss2si %xmm0, %rdx 100; CHECK-NEXT: andq %rcx, %rdx 101; CHECK-NEXT: orq %rax, %rdx 102; CHECK-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF 103; CHECK-NEXT: cmpq %rax, %rdx 104; CHECK-NEXT: movl $-1, %eax 105; CHECK-NEXT: cmovbl %edx, %eax 106; CHECK-NEXT: retq 107entry: 108 %conv = fptoui float %x to i64 109 %0 = icmp ult i64 %conv, 4294967295 110 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 111 %conv6 = trunc i64 %spec.store.select to i32 112 ret i32 %conv6 113} 114 115define i32 @ustest_f32i32(float %x) nounwind { 116; CHECK-LABEL: ustest_f32i32: 117; CHECK: # %bb.0: # %entry 118; CHECK-NEXT: cvttss2si %xmm0, %rcx 119; CHECK-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF 120; CHECK-NEXT: cmpq %rax, %rcx 121; CHECK-NEXT: cmovlq %rcx, %rax 122; CHECK-NEXT: xorl %ecx, %ecx 123; CHECK-NEXT: testq %rax, %rax 124; CHECK-NEXT: cmovlel %ecx, %eax 125; CHECK-NEXT: # kill: def $eax killed $eax killed $rax 126; CHECK-NEXT: retq 127entry: 128 %conv = fptosi float %x to i64 129 %0 = icmp slt i64 %conv, 4294967295 130 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 131 %1 = icmp sgt i64 %spec.store.select, 0 132 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 0 133 %conv6 = trunc i64 %spec.store.select7 to i32 134 ret i32 %conv6 135} 136 137define i32 @stest_f16i32(half %x) nounwind { 138; CHECK-LABEL: stest_f16i32: 139; CHECK: # %bb.0: # %entry 140; CHECK-NEXT: pushq %rax 141; CHECK-NEXT: callq __extendhfsf2@PLT 142; CHECK-NEXT: cvttss2si %xmm0, %eax 143; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 144; CHECK-NEXT: movl $-2147483648, %ecx # imm = 0x80000000 145; CHECK-NEXT: cmovael %eax, %ecx 146; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 147; CHECK-NEXT: movl $2147483647, %edx # imm = 0x7FFFFFFF 148; CHECK-NEXT: cmovbel %ecx, %edx 149; CHECK-NEXT: xorl %eax, %eax 150; CHECK-NEXT: ucomiss %xmm0, %xmm0 151; CHECK-NEXT: cmovnpl %edx, %eax 152; CHECK-NEXT: popq %rcx 153; CHECK-NEXT: retq 154entry: 155 %conv = fptosi half %x to i64 156 %0 = icmp slt i64 %conv, 2147483647 157 %spec.store.select = select i1 %0, i64 %conv, i64 2147483647 158 %1 = icmp sgt i64 %spec.store.select, -2147483648 159 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 -2147483648 160 %conv6 = trunc i64 %spec.store.select7 to i32 161 ret i32 %conv6 162} 163 164define i32 @utesth_f16i32(half %x) nounwind { 165; CHECK-LABEL: utesth_f16i32: 166; CHECK: # %bb.0: # %entry 167; CHECK-NEXT: pushq %rax 168; CHECK-NEXT: callq __extendhfsf2@PLT 169; CHECK-NEXT: cvttss2si %xmm0, %rax 170; CHECK-NEXT: movq %rax, %rcx 171; CHECK-NEXT: sarq $63, %rcx 172; CHECK-NEXT: subss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 173; CHECK-NEXT: cvttss2si %xmm0, %rdx 174; CHECK-NEXT: andq %rcx, %rdx 175; CHECK-NEXT: orq %rax, %rdx 176; CHECK-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF 177; CHECK-NEXT: cmpq %rax, %rdx 178; CHECK-NEXT: movl $-1, %eax 179; CHECK-NEXT: cmovbl %edx, %eax 180; CHECK-NEXT: popq %rcx 181; CHECK-NEXT: retq 182entry: 183 %conv = fptoui half %x to i64 184 %0 = icmp ult i64 %conv, 4294967295 185 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 186 %conv6 = trunc i64 %spec.store.select to i32 187 ret i32 %conv6 188} 189 190define i32 @ustest_f16i32(half %x) nounwind { 191; CHECK-LABEL: ustest_f16i32: 192; CHECK: # %bb.0: # %entry 193; CHECK-NEXT: pushq %rax 194; CHECK-NEXT: callq __extendhfsf2@PLT 195; CHECK-NEXT: cvttss2si %xmm0, %rcx 196; CHECK-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF 197; CHECK-NEXT: cmpq %rax, %rcx 198; CHECK-NEXT: cmovlq %rcx, %rax 199; CHECK-NEXT: xorl %ecx, %ecx 200; CHECK-NEXT: testq %rax, %rax 201; CHECK-NEXT: cmovlel %ecx, %eax 202; CHECK-NEXT: # kill: def $eax killed $eax killed $rax 203; CHECK-NEXT: popq %rcx 204; CHECK-NEXT: retq 205entry: 206 %conv = fptosi half %x to i64 207 %0 = icmp slt i64 %conv, 4294967295 208 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 209 %1 = icmp sgt i64 %spec.store.select, 0 210 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 0 211 %conv6 = trunc i64 %spec.store.select7 to i32 212 ret i32 %conv6 213} 214 215; i16 saturate 216 217define i16 @stest_f64i16(double %x) nounwind { 218; CHECK-LABEL: stest_f64i16: 219; CHECK: # %bb.0: # %entry 220; CHECK-NEXT: movsd {{.*#+}} xmm1 = [-3.2768E+4,0.0E+0] 221; CHECK-NEXT: maxsd %xmm0, %xmm1 222; CHECK-NEXT: movsd {{.*#+}} xmm0 = [3.2767E+4,0.0E+0] 223; CHECK-NEXT: minsd %xmm1, %xmm0 224; CHECK-NEXT: cvttsd2si %xmm0, %eax 225; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 226; CHECK-NEXT: retq 227entry: 228 %conv = fptosi double %x to i32 229 %0 = icmp slt i32 %conv, 32767 230 %spec.store.select = select i1 %0, i32 %conv, i32 32767 231 %1 = icmp sgt i32 %spec.store.select, -32768 232 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 -32768 233 %conv6 = trunc i32 %spec.store.select7 to i16 234 ret i16 %conv6 235} 236 237define i16 @utest_f64i16(double %x) nounwind { 238; CHECK-LABEL: utest_f64i16: 239; CHECK: # %bb.0: # %entry 240; CHECK-NEXT: cvttsd2si %xmm0, %rcx 241; CHECK-NEXT: cmpl $65535, %ecx # imm = 0xFFFF 242; CHECK-NEXT: movl $65535, %eax # imm = 0xFFFF 243; CHECK-NEXT: cmovbl %ecx, %eax 244; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 245; CHECK-NEXT: retq 246entry: 247 %conv = fptoui double %x to i32 248 %0 = icmp ult i32 %conv, 65535 249 %spec.store.select = select i1 %0, i32 %conv, i32 65535 250 %conv6 = trunc i32 %spec.store.select to i16 251 ret i16 %conv6 252} 253 254define i16 @ustest_f64i16(double %x) nounwind { 255; CHECK-LABEL: ustest_f64i16: 256; CHECK: # %bb.0: # %entry 257; CHECK-NEXT: cvttsd2si %xmm0, %eax 258; CHECK-NEXT: cmpl $65535, %eax # imm = 0xFFFF 259; CHECK-NEXT: movl $65535, %ecx # imm = 0xFFFF 260; CHECK-NEXT: cmovll %eax, %ecx 261; CHECK-NEXT: xorl %eax, %eax 262; CHECK-NEXT: testl %ecx, %ecx 263; CHECK-NEXT: cmovgl %ecx, %eax 264; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 265; CHECK-NEXT: retq 266entry: 267 %conv = fptosi double %x to i32 268 %0 = icmp slt i32 %conv, 65535 269 %spec.store.select = select i1 %0, i32 %conv, i32 65535 270 %1 = icmp sgt i32 %spec.store.select, 0 271 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 0 272 %conv6 = trunc i32 %spec.store.select7 to i16 273 ret i16 %conv6 274} 275 276define i16 @stest_f32i16(float %x) nounwind { 277; CHECK-LABEL: stest_f32i16: 278; CHECK: # %bb.0: # %entry 279; CHECK-NEXT: movss {{.*#+}} xmm1 = [-3.2768E+4,0.0E+0,0.0E+0,0.0E+0] 280; CHECK-NEXT: maxss %xmm0, %xmm1 281; CHECK-NEXT: movss {{.*#+}} xmm0 = [3.2767E+4,0.0E+0,0.0E+0,0.0E+0] 282; CHECK-NEXT: minss %xmm1, %xmm0 283; CHECK-NEXT: cvttss2si %xmm0, %eax 284; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 285; CHECK-NEXT: retq 286entry: 287 %conv = fptosi float %x to i32 288 %0 = icmp slt i32 %conv, 32767 289 %spec.store.select = select i1 %0, i32 %conv, i32 32767 290 %1 = icmp sgt i32 %spec.store.select, -32768 291 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 -32768 292 %conv6 = trunc i32 %spec.store.select7 to i16 293 ret i16 %conv6 294} 295 296define i16 @utest_f32i16(float %x) nounwind { 297; CHECK-LABEL: utest_f32i16: 298; CHECK: # %bb.0: # %entry 299; CHECK-NEXT: cvttss2si %xmm0, %rcx 300; CHECK-NEXT: cmpl $65535, %ecx # imm = 0xFFFF 301; CHECK-NEXT: movl $65535, %eax # imm = 0xFFFF 302; CHECK-NEXT: cmovbl %ecx, %eax 303; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 304; CHECK-NEXT: retq 305entry: 306 %conv = fptoui float %x to i32 307 %0 = icmp ult i32 %conv, 65535 308 %spec.store.select = select i1 %0, i32 %conv, i32 65535 309 %conv6 = trunc i32 %spec.store.select to i16 310 ret i16 %conv6 311} 312 313define i16 @ustest_f32i16(float %x) nounwind { 314; CHECK-LABEL: ustest_f32i16: 315; CHECK: # %bb.0: # %entry 316; CHECK-NEXT: cvttss2si %xmm0, %eax 317; CHECK-NEXT: cmpl $65535, %eax # imm = 0xFFFF 318; CHECK-NEXT: movl $65535, %ecx # imm = 0xFFFF 319; CHECK-NEXT: cmovll %eax, %ecx 320; CHECK-NEXT: xorl %eax, %eax 321; CHECK-NEXT: testl %ecx, %ecx 322; CHECK-NEXT: cmovgl %ecx, %eax 323; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 324; CHECK-NEXT: retq 325entry: 326 %conv = fptosi float %x to i32 327 %0 = icmp slt i32 %conv, 65535 328 %spec.store.select = select i1 %0, i32 %conv, i32 65535 329 %1 = icmp sgt i32 %spec.store.select, 0 330 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 0 331 %conv6 = trunc i32 %spec.store.select7 to i16 332 ret i16 %conv6 333} 334 335define i16 @stest_f16i16(half %x) nounwind { 336; CHECK-LABEL: stest_f16i16: 337; CHECK: # %bb.0: # %entry 338; CHECK-NEXT: pushq %rax 339; CHECK-NEXT: callq __extendhfsf2@PLT 340; CHECK-NEXT: cvttss2si %xmm0, %eax 341; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 342; CHECK-NEXT: movl $32768, %ecx # imm = 0x8000 343; CHECK-NEXT: cmovael %eax, %ecx 344; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 345; CHECK-NEXT: movl $32767, %edx # imm = 0x7FFF 346; CHECK-NEXT: cmovbel %ecx, %edx 347; CHECK-NEXT: xorl %eax, %eax 348; CHECK-NEXT: ucomiss %xmm0, %xmm0 349; CHECK-NEXT: cmovnpl %edx, %eax 350; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 351; CHECK-NEXT: popq %rcx 352; CHECK-NEXT: retq 353entry: 354 %conv = fptosi half %x to i32 355 %0 = icmp slt i32 %conv, 32767 356 %spec.store.select = select i1 %0, i32 %conv, i32 32767 357 %1 = icmp sgt i32 %spec.store.select, -32768 358 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 -32768 359 %conv6 = trunc i32 %spec.store.select7 to i16 360 ret i16 %conv6 361} 362 363define i16 @utesth_f16i16(half %x) nounwind { 364; CHECK-LABEL: utesth_f16i16: 365; CHECK: # %bb.0: # %entry 366; CHECK-NEXT: pushq %rax 367; CHECK-NEXT: callq __extendhfsf2@PLT 368; CHECK-NEXT: cvttss2si %xmm0, %rcx 369; CHECK-NEXT: cmpl $65535, %ecx # imm = 0xFFFF 370; CHECK-NEXT: movl $65535, %eax # imm = 0xFFFF 371; CHECK-NEXT: cmovbl %ecx, %eax 372; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 373; CHECK-NEXT: popq %rcx 374; CHECK-NEXT: retq 375entry: 376 %conv = fptoui half %x to i32 377 %0 = icmp ult i32 %conv, 65535 378 %spec.store.select = select i1 %0, i32 %conv, i32 65535 379 %conv6 = trunc i32 %spec.store.select to i16 380 ret i16 %conv6 381} 382 383define i16 @ustest_f16i16(half %x) nounwind { 384; CHECK-LABEL: ustest_f16i16: 385; CHECK: # %bb.0: # %entry 386; CHECK-NEXT: pushq %rax 387; CHECK-NEXT: callq __extendhfsf2@PLT 388; CHECK-NEXT: cvttss2si %xmm0, %eax 389; CHECK-NEXT: cmpl $65535, %eax # imm = 0xFFFF 390; CHECK-NEXT: movl $65535, %ecx # imm = 0xFFFF 391; CHECK-NEXT: cmovll %eax, %ecx 392; CHECK-NEXT: xorl %eax, %eax 393; CHECK-NEXT: testl %ecx, %ecx 394; CHECK-NEXT: cmovgl %ecx, %eax 395; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 396; CHECK-NEXT: popq %rcx 397; CHECK-NEXT: retq 398entry: 399 %conv = fptosi half %x to i32 400 %0 = icmp slt i32 %conv, 65535 401 %spec.store.select = select i1 %0, i32 %conv, i32 65535 402 %1 = icmp sgt i32 %spec.store.select, 0 403 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 0 404 %conv6 = trunc i32 %spec.store.select7 to i16 405 ret i16 %conv6 406} 407 408; i64 saturate 409 410define i64 @stest_f64i64(double %x) nounwind { 411; CHECK-LABEL: stest_f64i64: 412; CHECK: # %bb.0: # %entry 413; CHECK-NEXT: cvttsd2si %xmm0, %rax 414; CHECK-NEXT: ucomisd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 415; CHECK-NEXT: movabsq $9223372036854775807, %rcx # imm = 0x7FFFFFFFFFFFFFFF 416; CHECK-NEXT: cmovbeq %rax, %rcx 417; CHECK-NEXT: xorl %eax, %eax 418; CHECK-NEXT: ucomisd %xmm0, %xmm0 419; CHECK-NEXT: cmovnpq %rcx, %rax 420; CHECK-NEXT: retq 421entry: 422 %conv = fptosi double %x to i128 423 %0 = icmp slt i128 %conv, 9223372036854775807 424 %spec.store.select = select i1 %0, i128 %conv, i128 9223372036854775807 425 %1 = icmp sgt i128 %spec.store.select, -9223372036854775808 426 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 -9223372036854775808 427 %conv6 = trunc i128 %spec.store.select7 to i64 428 ret i64 %conv6 429} 430 431define i64 @utest_f64i64(double %x) nounwind { 432; CHECK-LABEL: utest_f64i64: 433; CHECK: # %bb.0: # %entry 434; CHECK-NEXT: pushq %rax 435; CHECK-NEXT: callq __fixunsdfti@PLT 436; CHECK-NEXT: xorl %ecx, %ecx 437; CHECK-NEXT: testq %rdx, %rdx 438; CHECK-NEXT: cmovneq %rcx, %rax 439; CHECK-NEXT: popq %rcx 440; CHECK-NEXT: retq 441entry: 442 %conv = fptoui double %x to i128 443 %0 = icmp ult i128 %conv, 18446744073709551616 444 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 445 %conv6 = trunc i128 %spec.store.select to i64 446 ret i64 %conv6 447} 448 449define i64 @ustest_f64i64(double %x) nounwind { 450; CHECK-LABEL: ustest_f64i64: 451; CHECK: # %bb.0: # %entry 452; CHECK-NEXT: pushq %rax 453; CHECK-NEXT: callq __fixdfti@PLT 454; CHECK-NEXT: xorl %ecx, %ecx 455; CHECK-NEXT: testq %rdx, %rdx 456; CHECK-NEXT: movl $1, %esi 457; CHECK-NEXT: cmovleq %rdx, %rsi 458; CHECK-NEXT: cmovgq %rcx, %rax 459; CHECK-NEXT: movq %rax, %rdx 460; CHECK-NEXT: negq %rdx 461; CHECK-NEXT: movl $0, %edx 462; CHECK-NEXT: sbbq %rsi, %rdx 463; CHECK-NEXT: cmovgeq %rcx, %rax 464; CHECK-NEXT: popq %rcx 465; CHECK-NEXT: retq 466entry: 467 %conv = fptosi double %x to i128 468 %0 = icmp slt i128 %conv, 18446744073709551616 469 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 470 %1 = icmp sgt i128 %spec.store.select, 0 471 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 0 472 %conv6 = trunc i128 %spec.store.select7 to i64 473 ret i64 %conv6 474} 475 476define i64 @stest_f32i64(float %x) nounwind { 477; CHECK-LABEL: stest_f32i64: 478; CHECK: # %bb.0: # %entry 479; CHECK-NEXT: cvttss2si %xmm0, %rax 480; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 481; CHECK-NEXT: movabsq $9223372036854775807, %rcx # imm = 0x7FFFFFFFFFFFFFFF 482; CHECK-NEXT: cmovbeq %rax, %rcx 483; CHECK-NEXT: xorl %eax, %eax 484; CHECK-NEXT: ucomiss %xmm0, %xmm0 485; CHECK-NEXT: cmovnpq %rcx, %rax 486; CHECK-NEXT: retq 487entry: 488 %conv = fptosi float %x to i128 489 %0 = icmp slt i128 %conv, 9223372036854775807 490 %spec.store.select = select i1 %0, i128 %conv, i128 9223372036854775807 491 %1 = icmp sgt i128 %spec.store.select, -9223372036854775808 492 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 -9223372036854775808 493 %conv6 = trunc i128 %spec.store.select7 to i64 494 ret i64 %conv6 495} 496 497define i64 @utest_f32i64(float %x) nounwind { 498; CHECK-LABEL: utest_f32i64: 499; CHECK: # %bb.0: # %entry 500; CHECK-NEXT: pushq %rax 501; CHECK-NEXT: callq __fixunssfti@PLT 502; CHECK-NEXT: xorl %ecx, %ecx 503; CHECK-NEXT: testq %rdx, %rdx 504; CHECK-NEXT: cmovneq %rcx, %rax 505; CHECK-NEXT: popq %rcx 506; CHECK-NEXT: retq 507entry: 508 %conv = fptoui float %x to i128 509 %0 = icmp ult i128 %conv, 18446744073709551616 510 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 511 %conv6 = trunc i128 %spec.store.select to i64 512 ret i64 %conv6 513} 514 515define i64 @ustest_f32i64(float %x) nounwind { 516; CHECK-LABEL: ustest_f32i64: 517; CHECK: # %bb.0: # %entry 518; CHECK-NEXT: pushq %rax 519; CHECK-NEXT: callq __fixsfti@PLT 520; CHECK-NEXT: xorl %ecx, %ecx 521; CHECK-NEXT: testq %rdx, %rdx 522; CHECK-NEXT: movl $1, %esi 523; CHECK-NEXT: cmovleq %rdx, %rsi 524; CHECK-NEXT: cmovgq %rcx, %rax 525; CHECK-NEXT: movq %rax, %rdx 526; CHECK-NEXT: negq %rdx 527; CHECK-NEXT: movl $0, %edx 528; CHECK-NEXT: sbbq %rsi, %rdx 529; CHECK-NEXT: cmovgeq %rcx, %rax 530; CHECK-NEXT: popq %rcx 531; CHECK-NEXT: retq 532entry: 533 %conv = fptosi float %x to i128 534 %0 = icmp slt i128 %conv, 18446744073709551616 535 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 536 %1 = icmp sgt i128 %spec.store.select, 0 537 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 0 538 %conv6 = trunc i128 %spec.store.select7 to i64 539 ret i64 %conv6 540} 541 542define i64 @stest_f16i64(half %x) nounwind { 543; CHECK-LABEL: stest_f16i64: 544; CHECK: # %bb.0: # %entry 545; CHECK-NEXT: pushq %rax 546; CHECK-NEXT: callq __extendhfsf2@PLT 547; CHECK-NEXT: cvttss2si %xmm0, %rax 548; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 549; CHECK-NEXT: movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000 550; CHECK-NEXT: cmovaeq %rax, %rcx 551; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 552; CHECK-NEXT: movabsq $9223372036854775807, %rdx # imm = 0x7FFFFFFFFFFFFFFF 553; CHECK-NEXT: cmovbeq %rcx, %rdx 554; CHECK-NEXT: xorl %eax, %eax 555; CHECK-NEXT: ucomiss %xmm0, %xmm0 556; CHECK-NEXT: cmovnpq %rdx, %rax 557; CHECK-NEXT: popq %rcx 558; CHECK-NEXT: retq 559entry: 560 %conv = fptosi half %x to i128 561 %0 = icmp slt i128 %conv, 9223372036854775807 562 %spec.store.select = select i1 %0, i128 %conv, i128 9223372036854775807 563 %1 = icmp sgt i128 %spec.store.select, -9223372036854775808 564 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 -9223372036854775808 565 %conv6 = trunc i128 %spec.store.select7 to i64 566 ret i64 %conv6 567} 568 569define i64 @utesth_f16i64(half %x) nounwind { 570; CHECK-LABEL: utesth_f16i64: 571; CHECK: # %bb.0: # %entry 572; CHECK-NEXT: pushq %rax 573; CHECK-NEXT: callq __fixunshfti@PLT 574; CHECK-NEXT: xorl %ecx, %ecx 575; CHECK-NEXT: testq %rdx, %rdx 576; CHECK-NEXT: cmovneq %rcx, %rax 577; CHECK-NEXT: popq %rcx 578; CHECK-NEXT: retq 579entry: 580 %conv = fptoui half %x to i128 581 %0 = icmp ult i128 %conv, 18446744073709551616 582 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 583 %conv6 = trunc i128 %spec.store.select to i64 584 ret i64 %conv6 585} 586 587define i64 @ustest_f16i64(half %x) nounwind { 588; CHECK-LABEL: ustest_f16i64: 589; CHECK: # %bb.0: # %entry 590; CHECK-NEXT: pushq %rax 591; CHECK-NEXT: callq __fixhfti@PLT 592; CHECK-NEXT: xorl %ecx, %ecx 593; CHECK-NEXT: testq %rdx, %rdx 594; CHECK-NEXT: movl $1, %esi 595; CHECK-NEXT: cmovleq %rdx, %rsi 596; CHECK-NEXT: cmovgq %rcx, %rax 597; CHECK-NEXT: movq %rax, %rdx 598; CHECK-NEXT: negq %rdx 599; CHECK-NEXT: movl $0, %edx 600; CHECK-NEXT: sbbq %rsi, %rdx 601; CHECK-NEXT: cmovgeq %rcx, %rax 602; CHECK-NEXT: popq %rcx 603; CHECK-NEXT: retq 604entry: 605 %conv = fptosi half %x to i128 606 %0 = icmp slt i128 %conv, 18446744073709551616 607 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 608 %1 = icmp sgt i128 %spec.store.select, 0 609 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 0 610 %conv6 = trunc i128 %spec.store.select7 to i64 611 ret i64 %conv6 612} 613 614 615 616 617; i32 saturate 618 619define i32 @stest_f64i32_mm(double %x) nounwind { 620; CHECK-LABEL: stest_f64i32_mm: 621; CHECK: # %bb.0: # %entry 622; CHECK-NEXT: xorl %eax, %eax 623; CHECK-NEXT: ucomisd %xmm0, %xmm0 624; CHECK-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 625; CHECK-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 626; CHECK-NEXT: cvttsd2si %xmm0, %ecx 627; CHECK-NEXT: cmovnpl %ecx, %eax 628; CHECK-NEXT: retq 629entry: 630 %conv = fptosi double %x to i64 631 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) 632 %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648) 633 %conv6 = trunc i64 %spec.store.select7 to i32 634 ret i32 %conv6 635} 636 637define i32 @utest_f64i32_mm(double %x) nounwind { 638; CHECK-LABEL: utest_f64i32_mm: 639; CHECK: # %bb.0: # %entry 640; CHECK-NEXT: cvttsd2si %xmm0, %rcx 641; CHECK-NEXT: movq %rcx, %rdx 642; CHECK-NEXT: sarq $63, %rdx 643; CHECK-NEXT: subsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 644; CHECK-NEXT: cvttsd2si %xmm0, %rax 645; CHECK-NEXT: andq %rdx, %rax 646; CHECK-NEXT: orq %rcx, %rax 647; CHECK-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF 648; CHECK-NEXT: cmpq %rcx, %rax 649; CHECK-NEXT: cmovaeq %rcx, %rax 650; CHECK-NEXT: # kill: def $eax killed $eax killed $rax 651; CHECK-NEXT: retq 652entry: 653 %conv = fptoui double %x to i64 654 %spec.store.select = call i64 @llvm.umin.i64(i64 %conv, i64 4294967295) 655 %conv6 = trunc i64 %spec.store.select to i32 656 ret i32 %conv6 657} 658 659define i32 @ustest_f64i32_mm(double %x) nounwind { 660; CHECK-LABEL: ustest_f64i32_mm: 661; CHECK: # %bb.0: # %entry 662; CHECK-NEXT: cvttsd2si %xmm0, %rax 663; CHECK-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF 664; CHECK-NEXT: cmpq %rcx, %rax 665; CHECK-NEXT: cmovlq %rax, %rcx 666; CHECK-NEXT: xorl %eax, %eax 667; CHECK-NEXT: testq %rcx, %rcx 668; CHECK-NEXT: cmovgq %rcx, %rax 669; CHECK-NEXT: # kill: def $eax killed $eax killed $rax 670; CHECK-NEXT: retq 671entry: 672 %conv = fptosi double %x to i64 673 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 4294967295) 674 %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 0) 675 %conv6 = trunc i64 %spec.store.select7 to i32 676 ret i32 %conv6 677} 678 679define i32 @stest_f32i32_mm(float %x) nounwind { 680; CHECK-LABEL: stest_f32i32_mm: 681; CHECK: # %bb.0: # %entry 682; CHECK-NEXT: cvttss2si %xmm0, %eax 683; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 684; CHECK-NEXT: movl $2147483647, %ecx # imm = 0x7FFFFFFF 685; CHECK-NEXT: cmovbel %eax, %ecx 686; CHECK-NEXT: xorl %eax, %eax 687; CHECK-NEXT: ucomiss %xmm0, %xmm0 688; CHECK-NEXT: cmovnpl %ecx, %eax 689; CHECK-NEXT: retq 690entry: 691 %conv = fptosi float %x to i64 692 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) 693 %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648) 694 %conv6 = trunc i64 %spec.store.select7 to i32 695 ret i32 %conv6 696} 697 698define i32 @utest_f32i32_mm(float %x) nounwind { 699; CHECK-LABEL: utest_f32i32_mm: 700; CHECK: # %bb.0: # %entry 701; CHECK-NEXT: cvttss2si %xmm0, %rcx 702; CHECK-NEXT: movq %rcx, %rdx 703; CHECK-NEXT: sarq $63, %rdx 704; CHECK-NEXT: subss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 705; CHECK-NEXT: cvttss2si %xmm0, %rax 706; CHECK-NEXT: andq %rdx, %rax 707; CHECK-NEXT: orq %rcx, %rax 708; CHECK-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF 709; CHECK-NEXT: cmpq %rcx, %rax 710; CHECK-NEXT: cmovaeq %rcx, %rax 711; CHECK-NEXT: # kill: def $eax killed $eax killed $rax 712; CHECK-NEXT: retq 713entry: 714 %conv = fptoui float %x to i64 715 %spec.store.select = call i64 @llvm.umin.i64(i64 %conv, i64 4294967295) 716 %conv6 = trunc i64 %spec.store.select to i32 717 ret i32 %conv6 718} 719 720define i32 @ustest_f32i32_mm(float %x) nounwind { 721; CHECK-LABEL: ustest_f32i32_mm: 722; CHECK: # %bb.0: # %entry 723; CHECK-NEXT: cvttss2si %xmm0, %rax 724; CHECK-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF 725; CHECK-NEXT: cmpq %rcx, %rax 726; CHECK-NEXT: cmovlq %rax, %rcx 727; CHECK-NEXT: xorl %eax, %eax 728; CHECK-NEXT: testq %rcx, %rcx 729; CHECK-NEXT: cmovgq %rcx, %rax 730; CHECK-NEXT: # kill: def $eax killed $eax killed $rax 731; CHECK-NEXT: retq 732entry: 733 %conv = fptosi float %x to i64 734 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 4294967295) 735 %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 0) 736 %conv6 = trunc i64 %spec.store.select7 to i32 737 ret i32 %conv6 738} 739 740define i32 @stest_f16i32_mm(half %x) nounwind { 741; CHECK-LABEL: stest_f16i32_mm: 742; CHECK: # %bb.0: # %entry 743; CHECK-NEXT: pushq %rax 744; CHECK-NEXT: callq __extendhfsf2@PLT 745; CHECK-NEXT: cvttss2si %xmm0, %eax 746; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 747; CHECK-NEXT: movl $-2147483648, %ecx # imm = 0x80000000 748; CHECK-NEXT: cmovael %eax, %ecx 749; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 750; CHECK-NEXT: movl $2147483647, %edx # imm = 0x7FFFFFFF 751; CHECK-NEXT: cmovbel %ecx, %edx 752; CHECK-NEXT: xorl %eax, %eax 753; CHECK-NEXT: ucomiss %xmm0, %xmm0 754; CHECK-NEXT: cmovnpl %edx, %eax 755; CHECK-NEXT: popq %rcx 756; CHECK-NEXT: retq 757entry: 758 %conv = fptosi half %x to i64 759 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) 760 %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648) 761 %conv6 = trunc i64 %spec.store.select7 to i32 762 ret i32 %conv6 763} 764 765define i32 @utesth_f16i32_mm(half %x) nounwind { 766; CHECK-LABEL: utesth_f16i32_mm: 767; CHECK: # %bb.0: # %entry 768; CHECK-NEXT: pushq %rax 769; CHECK-NEXT: callq __extendhfsf2@PLT 770; CHECK-NEXT: cvttss2si %xmm0, %rcx 771; CHECK-NEXT: movq %rcx, %rdx 772; CHECK-NEXT: sarq $63, %rdx 773; CHECK-NEXT: subss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 774; CHECK-NEXT: cvttss2si %xmm0, %rax 775; CHECK-NEXT: andq %rdx, %rax 776; CHECK-NEXT: orq %rcx, %rax 777; CHECK-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF 778; CHECK-NEXT: cmpq %rcx, %rax 779; CHECK-NEXT: cmovaeq %rcx, %rax 780; CHECK-NEXT: # kill: def $eax killed $eax killed $rax 781; CHECK-NEXT: popq %rcx 782; CHECK-NEXT: retq 783entry: 784 %conv = fptoui half %x to i64 785 %spec.store.select = call i64 @llvm.umin.i64(i64 %conv, i64 4294967295) 786 %conv6 = trunc i64 %spec.store.select to i32 787 ret i32 %conv6 788} 789 790define i32 @ustest_f16i32_mm(half %x) nounwind { 791; CHECK-LABEL: ustest_f16i32_mm: 792; CHECK: # %bb.0: # %entry 793; CHECK-NEXT: pushq %rax 794; CHECK-NEXT: callq __extendhfsf2@PLT 795; CHECK-NEXT: cvttss2si %xmm0, %rax 796; CHECK-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF 797; CHECK-NEXT: cmpq %rcx, %rax 798; CHECK-NEXT: cmovlq %rax, %rcx 799; CHECK-NEXT: xorl %eax, %eax 800; CHECK-NEXT: testq %rcx, %rcx 801; CHECK-NEXT: cmovgq %rcx, %rax 802; CHECK-NEXT: # kill: def $eax killed $eax killed $rax 803; CHECK-NEXT: popq %rcx 804; CHECK-NEXT: retq 805entry: 806 %conv = fptosi half %x to i64 807 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 4294967295) 808 %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 0) 809 %conv6 = trunc i64 %spec.store.select7 to i32 810 ret i32 %conv6 811} 812 813; i16 saturate 814 815define i16 @stest_f64i16_mm(double %x) nounwind { 816; CHECK-LABEL: stest_f64i16_mm: 817; CHECK: # %bb.0: # %entry 818; CHECK-NEXT: movsd {{.*#+}} xmm1 = [-3.2768E+4,0.0E+0] 819; CHECK-NEXT: maxsd %xmm0, %xmm1 820; CHECK-NEXT: movsd {{.*#+}} xmm0 = [3.2767E+4,0.0E+0] 821; CHECK-NEXT: minsd %xmm1, %xmm0 822; CHECK-NEXT: cvttsd2si %xmm0, %eax 823; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 824; CHECK-NEXT: retq 825entry: 826 %conv = fptosi double %x to i32 827 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 32767) 828 %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768) 829 %conv6 = trunc i32 %spec.store.select7 to i16 830 ret i16 %conv6 831} 832 833define i16 @utest_f64i16_mm(double %x) nounwind { 834; CHECK-LABEL: utest_f64i16_mm: 835; CHECK: # %bb.0: # %entry 836; CHECK-NEXT: cvttsd2si %xmm0, %rcx 837; CHECK-NEXT: cmpl $65535, %ecx # imm = 0xFFFF 838; CHECK-NEXT: movl $65535, %eax # imm = 0xFFFF 839; CHECK-NEXT: cmovbl %ecx, %eax 840; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 841; CHECK-NEXT: retq 842entry: 843 %conv = fptoui double %x to i32 844 %spec.store.select = call i32 @llvm.umin.i32(i32 %conv, i32 65535) 845 %conv6 = trunc i32 %spec.store.select to i16 846 ret i16 %conv6 847} 848 849define i16 @ustest_f64i16_mm(double %x) nounwind { 850; CHECK-LABEL: ustest_f64i16_mm: 851; CHECK: # %bb.0: # %entry 852; CHECK-NEXT: cvttsd2si %xmm0, %eax 853; CHECK-NEXT: cmpl $65535, %eax # imm = 0xFFFF 854; CHECK-NEXT: movl $65535, %ecx # imm = 0xFFFF 855; CHECK-NEXT: cmovll %eax, %ecx 856; CHECK-NEXT: xorl %eax, %eax 857; CHECK-NEXT: testl %ecx, %ecx 858; CHECK-NEXT: cmovgl %ecx, %eax 859; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 860; CHECK-NEXT: retq 861entry: 862 %conv = fptosi double %x to i32 863 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 65535) 864 %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 0) 865 %conv6 = trunc i32 %spec.store.select7 to i16 866 ret i16 %conv6 867} 868 869define i16 @stest_f32i16_mm(float %x) nounwind { 870; CHECK-LABEL: stest_f32i16_mm: 871; CHECK: # %bb.0: # %entry 872; CHECK-NEXT: movss {{.*#+}} xmm1 = [-3.2768E+4,0.0E+0,0.0E+0,0.0E+0] 873; CHECK-NEXT: maxss %xmm0, %xmm1 874; CHECK-NEXT: movss {{.*#+}} xmm0 = [3.2767E+4,0.0E+0,0.0E+0,0.0E+0] 875; CHECK-NEXT: minss %xmm1, %xmm0 876; CHECK-NEXT: cvttss2si %xmm0, %eax 877; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 878; CHECK-NEXT: retq 879entry: 880 %conv = fptosi float %x to i32 881 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 32767) 882 %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768) 883 %conv6 = trunc i32 %spec.store.select7 to i16 884 ret i16 %conv6 885} 886 887define i16 @utest_f32i16_mm(float %x) nounwind { 888; CHECK-LABEL: utest_f32i16_mm: 889; CHECK: # %bb.0: # %entry 890; CHECK-NEXT: cvttss2si %xmm0, %rcx 891; CHECK-NEXT: cmpl $65535, %ecx # imm = 0xFFFF 892; CHECK-NEXT: movl $65535, %eax # imm = 0xFFFF 893; CHECK-NEXT: cmovbl %ecx, %eax 894; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 895; CHECK-NEXT: retq 896entry: 897 %conv = fptoui float %x to i32 898 %spec.store.select = call i32 @llvm.umin.i32(i32 %conv, i32 65535) 899 %conv6 = trunc i32 %spec.store.select to i16 900 ret i16 %conv6 901} 902 903define i16 @ustest_f32i16_mm(float %x) nounwind { 904; CHECK-LABEL: ustest_f32i16_mm: 905; CHECK: # %bb.0: # %entry 906; CHECK-NEXT: cvttss2si %xmm0, %eax 907; CHECK-NEXT: cmpl $65535, %eax # imm = 0xFFFF 908; CHECK-NEXT: movl $65535, %ecx # imm = 0xFFFF 909; CHECK-NEXT: cmovll %eax, %ecx 910; CHECK-NEXT: xorl %eax, %eax 911; CHECK-NEXT: testl %ecx, %ecx 912; CHECK-NEXT: cmovgl %ecx, %eax 913; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 914; CHECK-NEXT: retq 915entry: 916 %conv = fptosi float %x to i32 917 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 65535) 918 %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 0) 919 %conv6 = trunc i32 %spec.store.select7 to i16 920 ret i16 %conv6 921} 922 923define i16 @stest_f16i16_mm(half %x) nounwind { 924; CHECK-LABEL: stest_f16i16_mm: 925; CHECK: # %bb.0: # %entry 926; CHECK-NEXT: pushq %rax 927; CHECK-NEXT: callq __extendhfsf2@PLT 928; CHECK-NEXT: cvttss2si %xmm0, %eax 929; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 930; CHECK-NEXT: movl $32768, %ecx # imm = 0x8000 931; CHECK-NEXT: cmovael %eax, %ecx 932; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 933; CHECK-NEXT: movl $32767, %edx # imm = 0x7FFF 934; CHECK-NEXT: cmovbel %ecx, %edx 935; CHECK-NEXT: xorl %eax, %eax 936; CHECK-NEXT: ucomiss %xmm0, %xmm0 937; CHECK-NEXT: cmovnpl %edx, %eax 938; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 939; CHECK-NEXT: popq %rcx 940; CHECK-NEXT: retq 941entry: 942 %conv = fptosi half %x to i32 943 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 32767) 944 %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768) 945 %conv6 = trunc i32 %spec.store.select7 to i16 946 ret i16 %conv6 947} 948 949define i16 @utesth_f16i16_mm(half %x) nounwind { 950; CHECK-LABEL: utesth_f16i16_mm: 951; CHECK: # %bb.0: # %entry 952; CHECK-NEXT: pushq %rax 953; CHECK-NEXT: callq __extendhfsf2@PLT 954; CHECK-NEXT: cvttss2si %xmm0, %rcx 955; CHECK-NEXT: cmpl $65535, %ecx # imm = 0xFFFF 956; CHECK-NEXT: movl $65535, %eax # imm = 0xFFFF 957; CHECK-NEXT: cmovbl %ecx, %eax 958; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 959; CHECK-NEXT: popq %rcx 960; CHECK-NEXT: retq 961entry: 962 %conv = fptoui half %x to i32 963 %spec.store.select = call i32 @llvm.umin.i32(i32 %conv, i32 65535) 964 %conv6 = trunc i32 %spec.store.select to i16 965 ret i16 %conv6 966} 967 968define i16 @ustest_f16i16_mm(half %x) nounwind { 969; CHECK-LABEL: ustest_f16i16_mm: 970; CHECK: # %bb.0: # %entry 971; CHECK-NEXT: pushq %rax 972; CHECK-NEXT: callq __extendhfsf2@PLT 973; CHECK-NEXT: cvttss2si %xmm0, %eax 974; CHECK-NEXT: cmpl $65535, %eax # imm = 0xFFFF 975; CHECK-NEXT: movl $65535, %ecx # imm = 0xFFFF 976; CHECK-NEXT: cmovll %eax, %ecx 977; CHECK-NEXT: xorl %eax, %eax 978; CHECK-NEXT: testl %ecx, %ecx 979; CHECK-NEXT: cmovgl %ecx, %eax 980; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 981; CHECK-NEXT: popq %rcx 982; CHECK-NEXT: retq 983entry: 984 %conv = fptosi half %x to i32 985 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 65535) 986 %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 0) 987 %conv6 = trunc i32 %spec.store.select7 to i16 988 ret i16 %conv6 989} 990 991; i64 saturate 992 993define i64 @stest_f64i64_mm(double %x) nounwind { 994; CHECK-LABEL: stest_f64i64_mm: 995; CHECK: # %bb.0: # %entry 996; CHECK-NEXT: cvttsd2si %xmm0, %rax 997; CHECK-NEXT: ucomisd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 998; CHECK-NEXT: movabsq $9223372036854775807, %rcx # imm = 0x7FFFFFFFFFFFFFFF 999; CHECK-NEXT: cmovbeq %rax, %rcx 1000; CHECK-NEXT: xorl %eax, %eax 1001; CHECK-NEXT: ucomisd %xmm0, %xmm0 1002; CHECK-NEXT: cmovnpq %rcx, %rax 1003; CHECK-NEXT: retq 1004entry: 1005 %conv = fptosi double %x to i128 1006 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807) 1007 %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808) 1008 %conv6 = trunc i128 %spec.store.select7 to i64 1009 ret i64 %conv6 1010} 1011 1012define i64 @utest_f64i64_mm(double %x) nounwind { 1013; CHECK-LABEL: utest_f64i64_mm: 1014; CHECK: # %bb.0: # %entry 1015; CHECK-NEXT: pushq %rax 1016; CHECK-NEXT: callq __fixunsdfti@PLT 1017; CHECK-NEXT: xorl %ecx, %ecx 1018; CHECK-NEXT: testq %rdx, %rdx 1019; CHECK-NEXT: cmovneq %rcx, %rax 1020; CHECK-NEXT: popq %rcx 1021; CHECK-NEXT: retq 1022entry: 1023 %conv = fptoui double %x to i128 1024 %spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616) 1025 %conv6 = trunc i128 %spec.store.select to i64 1026 ret i64 %conv6 1027} 1028 1029define i64 @ustest_f64i64_mm(double %x) nounwind { 1030; CHECK-LABEL: ustest_f64i64_mm: 1031; CHECK: # %bb.0: # %entry 1032; CHECK-NEXT: pushq %rax 1033; CHECK-NEXT: callq __fixdfti@PLT 1034; CHECK-NEXT: xorl %ecx, %ecx 1035; CHECK-NEXT: testq %rdx, %rdx 1036; CHECK-NEXT: cmovgq %rcx, %rax 1037; CHECK-NEXT: movl $1, %esi 1038; CHECK-NEXT: cmovleq %rdx, %rsi 1039; CHECK-NEXT: testq %rsi, %rsi 1040; CHECK-NEXT: cmovsq %rcx, %rax 1041; CHECK-NEXT: popq %rcx 1042; CHECK-NEXT: retq 1043entry: 1044 %conv = fptosi double %x to i128 1045 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616) 1046 %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0) 1047 %conv6 = trunc i128 %spec.store.select7 to i64 1048 ret i64 %conv6 1049} 1050 1051define i64 @stest_f32i64_mm(float %x) nounwind { 1052; CHECK-LABEL: stest_f32i64_mm: 1053; CHECK: # %bb.0: # %entry 1054; CHECK-NEXT: cvttss2si %xmm0, %rax 1055; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 1056; CHECK-NEXT: movabsq $9223372036854775807, %rcx # imm = 0x7FFFFFFFFFFFFFFF 1057; CHECK-NEXT: cmovbeq %rax, %rcx 1058; CHECK-NEXT: xorl %eax, %eax 1059; CHECK-NEXT: ucomiss %xmm0, %xmm0 1060; CHECK-NEXT: cmovnpq %rcx, %rax 1061; CHECK-NEXT: retq 1062entry: 1063 %conv = fptosi float %x to i128 1064 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807) 1065 %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808) 1066 %conv6 = trunc i128 %spec.store.select7 to i64 1067 ret i64 %conv6 1068} 1069 1070define i64 @utest_f32i64_mm(float %x) nounwind { 1071; CHECK-LABEL: utest_f32i64_mm: 1072; CHECK: # %bb.0: # %entry 1073; CHECK-NEXT: pushq %rax 1074; CHECK-NEXT: callq __fixunssfti@PLT 1075; CHECK-NEXT: xorl %ecx, %ecx 1076; CHECK-NEXT: testq %rdx, %rdx 1077; CHECK-NEXT: cmovneq %rcx, %rax 1078; CHECK-NEXT: popq %rcx 1079; CHECK-NEXT: retq 1080entry: 1081 %conv = fptoui float %x to i128 1082 %spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616) 1083 %conv6 = trunc i128 %spec.store.select to i64 1084 ret i64 %conv6 1085} 1086 1087define i64 @ustest_f32i64_mm(float %x) nounwind { 1088; CHECK-LABEL: ustest_f32i64_mm: 1089; CHECK: # %bb.0: # %entry 1090; CHECK-NEXT: pushq %rax 1091; CHECK-NEXT: callq __fixsfti@PLT 1092; CHECK-NEXT: xorl %ecx, %ecx 1093; CHECK-NEXT: testq %rdx, %rdx 1094; CHECK-NEXT: cmovgq %rcx, %rax 1095; CHECK-NEXT: movl $1, %esi 1096; CHECK-NEXT: cmovleq %rdx, %rsi 1097; CHECK-NEXT: testq %rsi, %rsi 1098; CHECK-NEXT: cmovsq %rcx, %rax 1099; CHECK-NEXT: popq %rcx 1100; CHECK-NEXT: retq 1101entry: 1102 %conv = fptosi float %x to i128 1103 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616) 1104 %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0) 1105 %conv6 = trunc i128 %spec.store.select7 to i64 1106 ret i64 %conv6 1107} 1108 1109define i64 @stest_f16i64_mm(half %x) nounwind { 1110; CHECK-LABEL: stest_f16i64_mm: 1111; CHECK: # %bb.0: # %entry 1112; CHECK-NEXT: pushq %rax 1113; CHECK-NEXT: callq __extendhfsf2@PLT 1114; CHECK-NEXT: cvttss2si %xmm0, %rax 1115; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 1116; CHECK-NEXT: movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000 1117; CHECK-NEXT: cmovaeq %rax, %rcx 1118; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 1119; CHECK-NEXT: movabsq $9223372036854775807, %rdx # imm = 0x7FFFFFFFFFFFFFFF 1120; CHECK-NEXT: cmovbeq %rcx, %rdx 1121; CHECK-NEXT: xorl %eax, %eax 1122; CHECK-NEXT: ucomiss %xmm0, %xmm0 1123; CHECK-NEXT: cmovnpq %rdx, %rax 1124; CHECK-NEXT: popq %rcx 1125; CHECK-NEXT: retq 1126entry: 1127 %conv = fptosi half %x to i128 1128 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807) 1129 %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808) 1130 %conv6 = trunc i128 %spec.store.select7 to i64 1131 ret i64 %conv6 1132} 1133 1134define i64 @utesth_f16i64_mm(half %x) nounwind { 1135; CHECK-LABEL: utesth_f16i64_mm: 1136; CHECK: # %bb.0: # %entry 1137; CHECK-NEXT: pushq %rax 1138; CHECK-NEXT: callq __fixunshfti@PLT 1139; CHECK-NEXT: xorl %ecx, %ecx 1140; CHECK-NEXT: testq %rdx, %rdx 1141; CHECK-NEXT: cmovneq %rcx, %rax 1142; CHECK-NEXT: popq %rcx 1143; CHECK-NEXT: retq 1144entry: 1145 %conv = fptoui half %x to i128 1146 %spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616) 1147 %conv6 = trunc i128 %spec.store.select to i64 1148 ret i64 %conv6 1149} 1150 1151define i64 @ustest_f16i64_mm(half %x) nounwind { 1152; CHECK-LABEL: ustest_f16i64_mm: 1153; CHECK: # %bb.0: # %entry 1154; CHECK-NEXT: pushq %rax 1155; CHECK-NEXT: callq __fixhfti@PLT 1156; CHECK-NEXT: xorl %ecx, %ecx 1157; CHECK-NEXT: testq %rdx, %rdx 1158; CHECK-NEXT: cmovgq %rcx, %rax 1159; CHECK-NEXT: movl $1, %esi 1160; CHECK-NEXT: cmovleq %rdx, %rsi 1161; CHECK-NEXT: testq %rsi, %rsi 1162; CHECK-NEXT: cmovsq %rcx, %rax 1163; CHECK-NEXT: popq %rcx 1164; CHECK-NEXT: retq 1165entry: 1166 %conv = fptosi half %x to i128 1167 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616) 1168 %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0) 1169 %conv6 = trunc i128 %spec.store.select7 to i64 1170 ret i64 %conv6 1171} 1172 1173declare i32 @llvm.smin.i32(i32, i32) 1174declare i32 @llvm.smax.i32(i32, i32) 1175declare i32 @llvm.umin.i32(i32, i32) 1176declare i64 @llvm.smin.i64(i64, i64) 1177declare i64 @llvm.smax.i64(i64, i64) 1178declare i64 @llvm.umin.i64(i64, i64) 1179declare i128 @llvm.smin.i128(i128, i128) 1180declare i128 @llvm.smax.i128(i128, i128) 1181declare i128 @llvm.umin.i128(i128, i128) 1182