1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=wasm32-unknown-unknown -mattr=+simd128,+nontrapping-fptoint | FileCheck %s 3 4; i32 saturate 5 6define i32 @stest_f64i32(double %x) { 7; CHECK-LABEL: stest_f64i32: 8; CHECK: .functype stest_f64i32 (f64) -> (i32) 9; CHECK-NEXT: # %bb.0: # %entry 10; CHECK-NEXT: local.get 0 11; CHECK-NEXT: i32.trunc_sat_f64_s 12; CHECK-NEXT: # fallthrough-return 13entry: 14 %conv = fptosi double %x to i64 15 %0 = icmp slt i64 %conv, 2147483647 16 %spec.store.select = select i1 %0, i64 %conv, i64 2147483647 17 %1 = icmp sgt i64 %spec.store.select, -2147483648 18 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 -2147483648 19 %conv6 = trunc i64 %spec.store.select7 to i32 20 ret i32 %conv6 21} 22 23define i32 @utest_f64i32(double %x) { 24; CHECK-LABEL: utest_f64i32: 25; CHECK: .functype utest_f64i32 (f64) -> (i32) 26; CHECK-NEXT: # %bb.0: # %entry 27; CHECK-NEXT: local.get 0 28; CHECK-NEXT: i32.trunc_sat_f64_u 29; CHECK-NEXT: # fallthrough-return 30entry: 31 %conv = fptoui double %x to i64 32 %0 = icmp ult i64 %conv, 4294967295 33 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 34 %conv6 = trunc i64 %spec.store.select to i32 35 ret i32 %conv6 36} 37 38define i32 @ustest_f64i32(double %x) { 39; CHECK-LABEL: ustest_f64i32: 40; CHECK: .functype ustest_f64i32 (f64) -> (i32) 41; CHECK-NEXT: # %bb.0: # %entry 42; CHECK-NEXT: local.get 0 43; CHECK-NEXT: i32.trunc_sat_f64_u 44; CHECK-NEXT: # fallthrough-return 45entry: 46 %conv = fptosi double %x to i64 47 %0 = icmp slt i64 %conv, 4294967295 48 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 49 %1 = icmp sgt i64 %spec.store.select, 0 50 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 0 51 %conv6 = trunc i64 %spec.store.select7 to i32 52 ret i32 %conv6 53} 54 55define i32 @stest_f32i32(float %x) { 56; CHECK-LABEL: stest_f32i32: 57; CHECK: .functype stest_f32i32 (f32) -> (i32) 58; CHECK-NEXT: # %bb.0: # %entry 59; CHECK-NEXT: local.get 0 60; CHECK-NEXT: i32.trunc_sat_f32_s 61; CHECK-NEXT: # fallthrough-return 62entry: 63 %conv = fptosi float %x to i64 64 %0 = icmp slt i64 %conv, 2147483647 65 %spec.store.select = select i1 %0, i64 %conv, i64 2147483647 66 %1 = icmp sgt i64 %spec.store.select, -2147483648 67 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 -2147483648 68 %conv6 = trunc i64 %spec.store.select7 to i32 69 ret i32 %conv6 70} 71 72define i32 @utest_f32i32(float %x) { 73; CHECK-LABEL: utest_f32i32: 74; CHECK: .functype utest_f32i32 (f32) -> (i32) 75; CHECK-NEXT: # %bb.0: # %entry 76; CHECK-NEXT: local.get 0 77; CHECK-NEXT: i32.trunc_sat_f32_u 78; CHECK-NEXT: # fallthrough-return 79entry: 80 %conv = fptoui float %x to i64 81 %0 = icmp ult i64 %conv, 4294967295 82 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 83 %conv6 = trunc i64 %spec.store.select to i32 84 ret i32 %conv6 85} 86 87define i32 @ustest_f32i32(float %x) { 88; CHECK-LABEL: ustest_f32i32: 89; CHECK: .functype ustest_f32i32 (f32) -> (i32) 90; CHECK-NEXT: # %bb.0: # %entry 91; CHECK-NEXT: local.get 0 92; CHECK-NEXT: i32.trunc_sat_f32_u 93; CHECK-NEXT: # fallthrough-return 94entry: 95 %conv = fptosi float %x to i64 96 %0 = icmp slt i64 %conv, 4294967295 97 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 98 %1 = icmp sgt i64 %spec.store.select, 0 99 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 0 100 %conv6 = trunc i64 %spec.store.select7 to i32 101 ret i32 %conv6 102} 103 104define i32 @stest_f16i32(half %x) { 105; CHECK-LABEL: stest_f16i32: 106; CHECK: .functype stest_f16i32 (f32) -> (i32) 107; CHECK-NEXT: # %bb.0: # %entry 108; CHECK-NEXT: local.get 0 109; CHECK-NEXT: call __truncsfhf2 110; CHECK-NEXT: call __extendhfsf2 111; CHECK-NEXT: i32.trunc_sat_f32_s 112; CHECK-NEXT: # fallthrough-return 113entry: 114 %conv = fptosi half %x to i64 115 %0 = icmp slt i64 %conv, 2147483647 116 %spec.store.select = select i1 %0, i64 %conv, i64 2147483647 117 %1 = icmp sgt i64 %spec.store.select, -2147483648 118 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 -2147483648 119 %conv6 = trunc i64 %spec.store.select7 to i32 120 ret i32 %conv6 121} 122 123define i32 @stest_f16i32_cse(half %x) { 124; CHECK-LABEL: stest_f16i32_cse: 125; CHECK: .functype stest_f16i32_cse (f32) -> (i32) 126; CHECK-NEXT: # %bb.0: # %entry 127; CHECK-NEXT: local.get 0 128; CHECK-NEXT: call __truncsfhf2 129; CHECK-NEXT: call __extendhfsf2 130; CHECK-NEXT: i64.trunc_sat_f32_s 131; CHECK-NEXT: i32.wrap_i64 132; CHECK-NEXT: # fallthrough-return 133entry: 134 %conv = fptosi half %x to i64 135 %conv6 = trunc i64 %conv to i32 136 ret i32 %conv6 137} 138 139define i32 @utesth_f16i32(half %x) { 140; CHECK-LABEL: utesth_f16i32: 141; CHECK: .functype utesth_f16i32 (f32) -> (i32) 142; CHECK-NEXT: # %bb.0: # %entry 143; CHECK-NEXT: local.get 0 144; CHECK-NEXT: call __truncsfhf2 145; CHECK-NEXT: call __extendhfsf2 146; CHECK-NEXT: i32.trunc_sat_f32_u 147; CHECK-NEXT: # fallthrough-return 148entry: 149 %conv = fptoui half %x to i64 150 %0 = icmp ult i64 %conv, 4294967295 151 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 152 %conv6 = trunc i64 %spec.store.select to i32 153 ret i32 %conv6 154} 155 156define i32 @utesth_f16i32_cse(half %x) { 157; CHECK-LABEL: utesth_f16i32_cse: 158; CHECK: .functype utesth_f16i32_cse (f32) -> (i32) 159; CHECK-NEXT: # %bb.0: # %entry 160; CHECK-NEXT: local.get 0 161; CHECK-NEXT: call __truncsfhf2 162; CHECK-NEXT: call __extendhfsf2 163; CHECK-NEXT: i64.trunc_sat_f32_u 164; CHECK-NEXT: i32.wrap_i64 165; CHECK-NEXT: # fallthrough-return 166entry: 167 %conv = fptoui half %x to i64 168 %conv6 = trunc i64 %conv to i32 169 ret i32 %conv6 170} 171 172define i32 @ustest_f16i32(half %x) { 173; CHECK-LABEL: ustest_f16i32: 174; CHECK: .functype ustest_f16i32 (f32) -> (i32) 175; CHECK-NEXT: # %bb.0: # %entry 176; CHECK-NEXT: local.get 0 177; CHECK-NEXT: call __truncsfhf2 178; CHECK-NEXT: call __extendhfsf2 179; CHECK-NEXT: i32.trunc_sat_f32_u 180; CHECK-NEXT: # fallthrough-return 181entry: 182 %conv = fptosi half %x to i64 183 %0 = icmp slt i64 %conv, 4294967295 184 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 185 %1 = icmp sgt i64 %spec.store.select, 0 186 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 0 187 %conv6 = trunc i64 %spec.store.select7 to i32 188 ret i32 %conv6 189} 190 191define i32 @ustest_f16i32_cse(half %x) { 192; CHECK-LABEL: ustest_f16i32_cse: 193; CHECK: .functype ustest_f16i32_cse (f32) -> (i32) 194; CHECK-NEXT: # %bb.0: # %entry 195; CHECK-NEXT: local.get 0 196; CHECK-NEXT: call __truncsfhf2 197; CHECK-NEXT: call __extendhfsf2 198; CHECK-NEXT: i32.trunc_sat_f32_u 199; CHECK-NEXT: # fallthrough-return 200entry: 201 %conv = fptosi half %x to i64 202 %0 = icmp sgt i64 %conv, 0 203 %spec.store.select7 = select i1 %0, i64 %conv, i64 0 204 %conv6 = trunc i64 %spec.store.select7 to i32 205 ret i32 %conv6 206} 207 208; i16 saturate 209 210define i16 @stest_f64i16(double %x) { 211; CHECK-LABEL: stest_f64i16: 212; CHECK: .functype stest_f64i16 (f64) -> (i32) 213; CHECK-NEXT: .local i32 214; CHECK-NEXT: # %bb.0: # %entry 215; CHECK-NEXT: local.get 0 216; CHECK-NEXT: i32.trunc_sat_f64_s 217; CHECK-NEXT: local.tee 1 218; CHECK-NEXT: i32.const 32767 219; CHECK-NEXT: local.get 1 220; CHECK-NEXT: i32.const 32767 221; CHECK-NEXT: i32.lt_s 222; CHECK-NEXT: i32.select 223; CHECK-NEXT: local.tee 1 224; CHECK-NEXT: i32.const -32768 225; CHECK-NEXT: local.get 1 226; CHECK-NEXT: i32.const -32768 227; CHECK-NEXT: i32.gt_s 228; CHECK-NEXT: i32.select 229; CHECK-NEXT: # fallthrough-return 230entry: 231 %conv = fptosi double %x to i32 232 %0 = icmp slt i32 %conv, 32767 233 %spec.store.select = select i1 %0, i32 %conv, i32 32767 234 %1 = icmp sgt i32 %spec.store.select, -32768 235 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 -32768 236 %conv6 = trunc i32 %spec.store.select7 to i16 237 ret i16 %conv6 238} 239 240define i16 @utest_f64i16(double %x) { 241; CHECK-LABEL: utest_f64i16: 242; CHECK: .functype utest_f64i16 (f64) -> (i32) 243; CHECK-NEXT: .local i32 244; CHECK-NEXT: # %bb.0: # %entry 245; CHECK-NEXT: local.get 0 246; CHECK-NEXT: i32.trunc_sat_f64_u 247; CHECK-NEXT: local.tee 1 248; CHECK-NEXT: i32.const 65535 249; CHECK-NEXT: local.get 1 250; CHECK-NEXT: i32.const 65535 251; CHECK-NEXT: i32.lt_u 252; CHECK-NEXT: i32.select 253; CHECK-NEXT: # fallthrough-return 254entry: 255 %conv = fptoui double %x to i32 256 %0 = icmp ult i32 %conv, 65535 257 %spec.store.select = select i1 %0, i32 %conv, i32 65535 258 %conv6 = trunc i32 %spec.store.select to i16 259 ret i16 %conv6 260} 261 262define i16 @ustest_f64i16(double %x) { 263; CHECK-LABEL: ustest_f64i16: 264; CHECK: .functype ustest_f64i16 (f64) -> (i32) 265; CHECK-NEXT: .local i32 266; CHECK-NEXT: # %bb.0: # %entry 267; CHECK-NEXT: local.get 0 268; CHECK-NEXT: i32.trunc_sat_f64_s 269; CHECK-NEXT: local.tee 1 270; CHECK-NEXT: i32.const 65535 271; CHECK-NEXT: local.get 1 272; CHECK-NEXT: i32.const 65535 273; CHECK-NEXT: i32.lt_s 274; CHECK-NEXT: i32.select 275; CHECK-NEXT: local.tee 1 276; CHECK-NEXT: i32.const 0 277; CHECK-NEXT: local.get 1 278; CHECK-NEXT: i32.const 0 279; CHECK-NEXT: i32.gt_s 280; CHECK-NEXT: i32.select 281; CHECK-NEXT: # fallthrough-return 282entry: 283 %conv = fptosi double %x to i32 284 %0 = icmp slt i32 %conv, 65535 285 %spec.store.select = select i1 %0, i32 %conv, i32 65535 286 %1 = icmp sgt i32 %spec.store.select, 0 287 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 0 288 %conv6 = trunc i32 %spec.store.select7 to i16 289 ret i16 %conv6 290} 291 292define i16 @stest_f32i16(float %x) { 293; CHECK-LABEL: stest_f32i16: 294; CHECK: .functype stest_f32i16 (f32) -> (i32) 295; CHECK-NEXT: .local i32 296; CHECK-NEXT: # %bb.0: # %entry 297; CHECK-NEXT: local.get 0 298; CHECK-NEXT: i32.trunc_sat_f32_s 299; CHECK-NEXT: local.tee 1 300; CHECK-NEXT: i32.const 32767 301; CHECK-NEXT: local.get 1 302; CHECK-NEXT: i32.const 32767 303; CHECK-NEXT: i32.lt_s 304; CHECK-NEXT: i32.select 305; CHECK-NEXT: local.tee 1 306; CHECK-NEXT: i32.const -32768 307; CHECK-NEXT: local.get 1 308; CHECK-NEXT: i32.const -32768 309; CHECK-NEXT: i32.gt_s 310; CHECK-NEXT: i32.select 311; CHECK-NEXT: # fallthrough-return 312entry: 313 %conv = fptosi float %x to i32 314 %0 = icmp slt i32 %conv, 32767 315 %spec.store.select = select i1 %0, i32 %conv, i32 32767 316 %1 = icmp sgt i32 %spec.store.select, -32768 317 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 -32768 318 %conv6 = trunc i32 %spec.store.select7 to i16 319 ret i16 %conv6 320} 321 322define i16 @utest_f32i16(float %x) { 323; CHECK-LABEL: utest_f32i16: 324; CHECK: .functype utest_f32i16 (f32) -> (i32) 325; CHECK-NEXT: .local i32 326; CHECK-NEXT: # %bb.0: # %entry 327; CHECK-NEXT: local.get 0 328; CHECK-NEXT: i32.trunc_sat_f32_u 329; CHECK-NEXT: local.tee 1 330; CHECK-NEXT: i32.const 65535 331; CHECK-NEXT: local.get 1 332; CHECK-NEXT: i32.const 65535 333; CHECK-NEXT: i32.lt_u 334; CHECK-NEXT: i32.select 335; CHECK-NEXT: # fallthrough-return 336entry: 337 %conv = fptoui float %x to i32 338 %0 = icmp ult i32 %conv, 65535 339 %spec.store.select = select i1 %0, i32 %conv, i32 65535 340 %conv6 = trunc i32 %spec.store.select to i16 341 ret i16 %conv6 342} 343 344define i16 @ustest_f32i16(float %x) { 345; CHECK-LABEL: ustest_f32i16: 346; CHECK: .functype ustest_f32i16 (f32) -> (i32) 347; CHECK-NEXT: .local i32 348; CHECK-NEXT: # %bb.0: # %entry 349; CHECK-NEXT: local.get 0 350; CHECK-NEXT: i32.trunc_sat_f32_s 351; CHECK-NEXT: local.tee 1 352; CHECK-NEXT: i32.const 65535 353; CHECK-NEXT: local.get 1 354; CHECK-NEXT: i32.const 65535 355; CHECK-NEXT: i32.lt_s 356; CHECK-NEXT: i32.select 357; CHECK-NEXT: local.tee 1 358; CHECK-NEXT: i32.const 0 359; CHECK-NEXT: local.get 1 360; CHECK-NEXT: i32.const 0 361; CHECK-NEXT: i32.gt_s 362; CHECK-NEXT: i32.select 363; CHECK-NEXT: # fallthrough-return 364entry: 365 %conv = fptosi float %x to i32 366 %0 = icmp slt i32 %conv, 65535 367 %spec.store.select = select i1 %0, i32 %conv, i32 65535 368 %1 = icmp sgt i32 %spec.store.select, 0 369 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 0 370 %conv6 = trunc i32 %spec.store.select7 to i16 371 ret i16 %conv6 372} 373 374define i16 @stest_f16i16(half %x) { 375; CHECK-LABEL: stest_f16i16: 376; CHECK: .functype stest_f16i16 (f32) -> (i32) 377; CHECK-NEXT: .local i32 378; CHECK-NEXT: # %bb.0: # %entry 379; CHECK-NEXT: local.get 0 380; CHECK-NEXT: call __truncsfhf2 381; CHECK-NEXT: call __extendhfsf2 382; CHECK-NEXT: i32.trunc_sat_f32_s 383; CHECK-NEXT: local.tee 1 384; CHECK-NEXT: i32.const 32767 385; CHECK-NEXT: local.get 1 386; CHECK-NEXT: i32.const 32767 387; CHECK-NEXT: i32.lt_s 388; CHECK-NEXT: i32.select 389; CHECK-NEXT: local.tee 1 390; CHECK-NEXT: i32.const -32768 391; CHECK-NEXT: local.get 1 392; CHECK-NEXT: i32.const -32768 393; CHECK-NEXT: i32.gt_s 394; CHECK-NEXT: i32.select 395; CHECK-NEXT: # fallthrough-return 396entry: 397 %conv = fptosi half %x to i32 398 %0 = icmp slt i32 %conv, 32767 399 %spec.store.select = select i1 %0, i32 %conv, i32 32767 400 %1 = icmp sgt i32 %spec.store.select, -32768 401 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 -32768 402 %conv6 = trunc i32 %spec.store.select7 to i16 403 ret i16 %conv6 404} 405 406define i16 @utesth_f16i16(half %x) { 407; CHECK-LABEL: utesth_f16i16: 408; CHECK: .functype utesth_f16i16 (f32) -> (i32) 409; CHECK-NEXT: .local i32 410; CHECK-NEXT: # %bb.0: # %entry 411; CHECK-NEXT: local.get 0 412; CHECK-NEXT: call __truncsfhf2 413; CHECK-NEXT: call __extendhfsf2 414; CHECK-NEXT: i32.trunc_sat_f32_u 415; CHECK-NEXT: local.tee 1 416; CHECK-NEXT: i32.const 65535 417; CHECK-NEXT: local.get 1 418; CHECK-NEXT: i32.const 65535 419; CHECK-NEXT: i32.lt_u 420; CHECK-NEXT: i32.select 421; CHECK-NEXT: # fallthrough-return 422entry: 423 %conv = fptoui half %x to i32 424 %0 = icmp ult i32 %conv, 65535 425 %spec.store.select = select i1 %0, i32 %conv, i32 65535 426 %conv6 = trunc i32 %spec.store.select to i16 427 ret i16 %conv6 428} 429 430define i16 @utesth_f16i16_cse(half %x) { 431; CHECK-LABEL: utesth_f16i16_cse: 432; CHECK: .functype utesth_f16i16_cse (f32) -> (i32) 433; CHECK-NEXT: # %bb.0: # %entry 434; CHECK-NEXT: local.get 0 435; CHECK-NEXT: call __truncsfhf2 436; CHECK-NEXT: call __extendhfsf2 437; CHECK-NEXT: i32.trunc_sat_f32_u 438; CHECK-NEXT: # fallthrough-return 439entry: 440 %conv = fptoui half %x to i32 441 %conv6 = trunc i32 %conv to i16 442 ret i16 %conv6 443} 444 445define i16 @ustest_f16i16(half %x) { 446; CHECK-LABEL: ustest_f16i16: 447; CHECK: .functype ustest_f16i16 (f32) -> (i32) 448; CHECK-NEXT: .local i32 449; CHECK-NEXT: # %bb.0: # %entry 450; CHECK-NEXT: local.get 0 451; CHECK-NEXT: call __truncsfhf2 452; CHECK-NEXT: call __extendhfsf2 453; CHECK-NEXT: i32.trunc_sat_f32_s 454; CHECK-NEXT: local.tee 1 455; CHECK-NEXT: i32.const 65535 456; CHECK-NEXT: local.get 1 457; CHECK-NEXT: i32.const 65535 458; CHECK-NEXT: i32.lt_s 459; CHECK-NEXT: i32.select 460; CHECK-NEXT: local.tee 1 461; CHECK-NEXT: i32.const 0 462; CHECK-NEXT: local.get 1 463; CHECK-NEXT: i32.const 0 464; CHECK-NEXT: i32.gt_s 465; CHECK-NEXT: i32.select 466; CHECK-NEXT: # fallthrough-return 467entry: 468 %conv = fptosi half %x to i32 469 %0 = icmp slt i32 %conv, 65535 470 %spec.store.select = select i1 %0, i32 %conv, i32 65535 471 %1 = icmp sgt i32 %spec.store.select, 0 472 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 0 473 %conv6 = trunc i32 %spec.store.select7 to i16 474 ret i16 %conv6 475} 476 477define i16 @ustest_f16i16_cse(half %x) { 478; CHECK-LABEL: ustest_f16i16_cse: 479; CHECK: .functype ustest_f16i16_cse (f32) -> (i32) 480; CHECK-NEXT: # %bb.0: # %entry 481; CHECK-NEXT: local.get 0 482; CHECK-NEXT: call __truncsfhf2 483; CHECK-NEXT: call __extendhfsf2 484; CHECK-NEXT: i32.trunc_sat_f32_u 485; CHECK-NEXT: # fallthrough-return 486entry: 487 %conv = fptosi half %x to i32 488 %0 = icmp sgt i32 %conv, 0 489 %spec.store.select7 = select i1 %0, i32 %conv, i32 0 490 %conv6 = trunc i32 %spec.store.select7 to i16 491 ret i16 %conv6 492} 493 494; i64 saturate 495 496define i64 @stest_f64i64(double %x) { 497; CHECK-LABEL: stest_f64i64: 498; CHECK: .functype stest_f64i64 (f64) -> (i64) 499; CHECK-NEXT: # %bb.0: # %entry 500; CHECK-NEXT: local.get 0 501; CHECK-NEXT: i64.trunc_sat_f64_s 502; CHECK-NEXT: # fallthrough-return 503entry: 504 %conv = fptosi double %x to i128 505 %0 = icmp slt i128 %conv, 9223372036854775807 506 %spec.store.select = select i1 %0, i128 %conv, i128 9223372036854775807 507 %1 = icmp sgt i128 %spec.store.select, -9223372036854775808 508 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 -9223372036854775808 509 %conv6 = trunc i128 %spec.store.select7 to i64 510 ret i64 %conv6 511} 512 513define i64 @utest_f64i64(double %x) { 514; CHECK-LABEL: utest_f64i64: 515; CHECK: .functype utest_f64i64 (f64) -> (i64) 516; CHECK-NEXT: .local i32, i64, i64 517; CHECK-NEXT: # %bb.0: # %entry 518; CHECK-NEXT: global.get __stack_pointer 519; CHECK-NEXT: i32.const 16 520; CHECK-NEXT: i32.sub 521; CHECK-NEXT: local.tee 1 522; CHECK-NEXT: global.set __stack_pointer 523; CHECK-NEXT: local.get 1 524; CHECK-NEXT: local.get 0 525; CHECK-NEXT: call __fixunsdfti 526; CHECK-NEXT: local.get 1 527; CHECK-NEXT: i64.load 8 528; CHECK-NEXT: local.set 2 529; CHECK-NEXT: local.get 1 530; CHECK-NEXT: i64.load 0 531; CHECK-NEXT: local.set 3 532; CHECK-NEXT: local.get 1 533; CHECK-NEXT: i32.const 16 534; CHECK-NEXT: i32.add 535; CHECK-NEXT: global.set __stack_pointer 536; CHECK-NEXT: local.get 3 537; CHECK-NEXT: i64.const 0 538; CHECK-NEXT: local.get 2 539; CHECK-NEXT: i64.eqz 540; CHECK-NEXT: i64.select 541; CHECK-NEXT: # fallthrough-return 542entry: 543 %conv = fptoui double %x to i128 544 %0 = icmp ult i128 %conv, 18446744073709551616 545 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 546 %conv6 = trunc i128 %spec.store.select to i64 547 ret i64 %conv6 548} 549 550define i64 @utest_f64i64_cse_combine(double %x) #0 { 551; CHECK-LABEL: utest_f64i64_cse_combine: 552; CHECK: .functype utest_f64i64_cse_combine (f64) -> (i64) 553; CHECK-NEXT: .local i32, i64, i64 554; CHECK-NEXT: # %bb.0: # %entry 555; CHECK-NEXT: global.get __stack_pointer 556; CHECK-NEXT: i32.const 16 557; CHECK-NEXT: i32.sub 558; CHECK-NEXT: local.tee 1 559; CHECK-NEXT: global.set __stack_pointer 560; CHECK-NEXT: local.get 1 561; CHECK-NEXT: local.get 0 562; CHECK-NEXT: call __fixunsdfti 563; CHECK-NEXT: local.get 1 564; CHECK-NEXT: i64.load 8 565; CHECK-NEXT: local.set 2 566; CHECK-NEXT: local.get 1 567; CHECK-NEXT: i64.load 0 568; CHECK-NEXT: local.set 3 569; CHECK-NEXT: local.get 1 570; CHECK-NEXT: i32.const 16 571; CHECK-NEXT: i32.add 572; CHECK-NEXT: global.set __stack_pointer 573; CHECK-NEXT: local.get 3 574; CHECK-NEXT: i64.const 0 575; CHECK-NEXT: local.get 2 576; CHECK-NEXT: i64.eqz 577; CHECK-NEXT: i64.select 578; CHECK-NEXT: # fallthrough-return 579entry: 580 %conv = fptoui double %x to i128 581 %spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616) 582 %conv6 = trunc i128 %spec.store.select to i64 583 ret i64 %conv6 584} 585 586 587define i64 @ustest_f64i64(double %x) { 588; CHECK-LABEL: ustest_f64i64: 589; CHECK: .functype ustest_f64i64 (f64) -> (i64) 590; CHECK-NEXT: .local i32, i64, i64 591; CHECK-NEXT: # %bb.0: # %entry 592; CHECK-NEXT: global.get __stack_pointer 593; CHECK-NEXT: i32.const 16 594; CHECK-NEXT: i32.sub 595; CHECK-NEXT: local.tee 1 596; CHECK-NEXT: global.set __stack_pointer 597; CHECK-NEXT: local.get 1 598; CHECK-NEXT: local.get 0 599; CHECK-NEXT: call __fixdfti 600; CHECK-NEXT: local.get 1 601; CHECK-NEXT: i64.load 8 602; CHECK-NEXT: local.set 2 603; CHECK-NEXT: local.get 1 604; CHECK-NEXT: i64.load 0 605; CHECK-NEXT: local.set 3 606; CHECK-NEXT: local.get 1 607; CHECK-NEXT: i32.const 16 608; CHECK-NEXT: i32.add 609; CHECK-NEXT: global.set __stack_pointer 610; CHECK-NEXT: local.get 3 611; CHECK-NEXT: i64.const 0 612; CHECK-NEXT: local.get 2 613; CHECK-NEXT: i64.const 1 614; CHECK-NEXT: i64.lt_s 615; CHECK-NEXT: local.tee 1 616; CHECK-NEXT: i64.select 617; CHECK-NEXT: local.tee 3 618; CHECK-NEXT: i64.const 0 619; CHECK-NEXT: local.get 3 620; CHECK-NEXT: i64.const 0 621; CHECK-NEXT: i64.ne 622; CHECK-NEXT: local.get 2 623; CHECK-NEXT: i64.const 1 624; CHECK-NEXT: local.get 1 625; CHECK-NEXT: i64.select 626; CHECK-NEXT: local.tee 2 627; CHECK-NEXT: i64.const 0 628; CHECK-NEXT: i64.gt_s 629; CHECK-NEXT: local.get 2 630; CHECK-NEXT: i64.eqz 631; CHECK-NEXT: i32.select 632; CHECK-NEXT: i64.select 633; CHECK-NEXT: # fallthrough-return 634entry: 635 %conv = fptosi double %x to i128 636 %0 = icmp slt i128 %conv, 18446744073709551616 637 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 638 %1 = icmp sgt i128 %spec.store.select, 0 639 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 0 640 %conv6 = trunc i128 %spec.store.select7 to i64 641 ret i64 %conv6 642} 643 644define i64 @ustest_f64i64_cse_combine(double %x) #0 { 645; CHECK-LABEL: ustest_f64i64_cse_combine: 646; CHECK: .functype ustest_f64i64_cse_combine (f64) -> (i64) 647; CHECK-NEXT: .local i32, i64, i64 648; CHECK-NEXT: # %bb.0: # %entry 649; CHECK-NEXT: global.get __stack_pointer 650; CHECK-NEXT: i32.const 16 651; CHECK-NEXT: i32.sub 652; CHECK-NEXT: local.tee 1 653; CHECK-NEXT: global.set __stack_pointer 654; CHECK-NEXT: local.get 1 655; CHECK-NEXT: local.get 0 656; CHECK-NEXT: call __fixdfti 657; CHECK-NEXT: local.get 1 658; CHECK-NEXT: i64.load 8 659; CHECK-NEXT: local.set 2 660; CHECK-NEXT: local.get 1 661; CHECK-NEXT: i64.load 0 662; CHECK-NEXT: local.set 3 663; CHECK-NEXT: local.get 1 664; CHECK-NEXT: i32.const 16 665; CHECK-NEXT: i32.add 666; CHECK-NEXT: global.set __stack_pointer 667; CHECK-NEXT: i64.const 0 668; CHECK-NEXT: local.get 3 669; CHECK-NEXT: i64.const 0 670; CHECK-NEXT: local.get 2 671; CHECK-NEXT: i64.const 1 672; CHECK-NEXT: i64.lt_s 673; CHECK-NEXT: local.tee 1 674; CHECK-NEXT: i64.select 675; CHECK-NEXT: local.get 2 676; CHECK-NEXT: i64.const 1 677; CHECK-NEXT: local.get 1 678; CHECK-NEXT: i64.select 679; CHECK-NEXT: i64.const 0 680; CHECK-NEXT: i64.lt_s 681; CHECK-NEXT: i64.select 682; CHECK-NEXT: # fallthrough-return 683entry: 684 %conv = fptosi double %x to i128 685 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616) 686 %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0) 687 %conv6 = trunc i128 %spec.store.select7 to i64 688 ret i64 %conv6 689} 690 691define i64 @stest_f32i64(float %x) { 692; CHECK-LABEL: stest_f32i64: 693; CHECK: .functype stest_f32i64 (f32) -> (i64) 694; CHECK-NEXT: # %bb.0: # %entry 695; CHECK-NEXT: local.get 0 696; CHECK-NEXT: i64.trunc_sat_f32_s 697; CHECK-NEXT: # fallthrough-return 698entry: 699 %conv = fptosi float %x to i128 700 %0 = icmp slt i128 %conv, 9223372036854775807 701 %spec.store.select = select i1 %0, i128 %conv, i128 9223372036854775807 702 %1 = icmp sgt i128 %spec.store.select, -9223372036854775808 703 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 -9223372036854775808 704 %conv6 = trunc i128 %spec.store.select7 to i64 705 ret i64 %conv6 706} 707 708define i64 @utest_f32i64(float %x) { 709; CHECK-LABEL: utest_f32i64: 710; CHECK: .functype utest_f32i64 (f32) -> (i64) 711; CHECK-NEXT: .local i32, i64, i64 712; CHECK-NEXT: # %bb.0: # %entry 713; CHECK-NEXT: global.get __stack_pointer 714; CHECK-NEXT: i32.const 16 715; CHECK-NEXT: i32.sub 716; CHECK-NEXT: local.tee 1 717; CHECK-NEXT: global.set __stack_pointer 718; CHECK-NEXT: local.get 1 719; CHECK-NEXT: local.get 0 720; CHECK-NEXT: call __fixunssfti 721; CHECK-NEXT: local.get 1 722; CHECK-NEXT: i64.load 8 723; CHECK-NEXT: local.set 2 724; CHECK-NEXT: local.get 1 725; CHECK-NEXT: i64.load 0 726; CHECK-NEXT: local.set 3 727; CHECK-NEXT: local.get 1 728; CHECK-NEXT: i32.const 16 729; CHECK-NEXT: i32.add 730; CHECK-NEXT: global.set __stack_pointer 731; CHECK-NEXT: local.get 3 732; CHECK-NEXT: i64.const 0 733; CHECK-NEXT: local.get 2 734; CHECK-NEXT: i64.eqz 735; CHECK-NEXT: i64.select 736; CHECK-NEXT: # fallthrough-return 737entry: 738 %conv = fptoui float %x to i128 739 %0 = icmp ult i128 %conv, 18446744073709551616 740 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 741 %conv6 = trunc i128 %spec.store.select to i64 742 ret i64 %conv6 743} 744 745define i64 @stest_f32i64_cse_combine(float %x) #0 { 746; CHECK-LABEL: stest_f32i64_cse_combine: 747; CHECK: .functype stest_f32i64_cse_combine (f32) -> (i64) 748; CHECK-NEXT: # %bb.0: # %entry 749; CHECK-NEXT: local.get 0 750; CHECK-NEXT: i64.trunc_sat_f32_s 751; CHECK-NEXT: # fallthrough-return 752entry: 753 %conv = fptosi float %x to i128 754 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807) 755 %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808) 756 %conv6 = trunc i128 %spec.store.select7 to i64 757 ret i64 %conv6 758} 759 760define i64 @ustest_f32i64(float %x) { 761; CHECK-LABEL: ustest_f32i64: 762; CHECK: .functype ustest_f32i64 (f32) -> (i64) 763; CHECK-NEXT: .local i32, i64, i64 764; CHECK-NEXT: # %bb.0: # %entry 765; CHECK-NEXT: global.get __stack_pointer 766; CHECK-NEXT: i32.const 16 767; CHECK-NEXT: i32.sub 768; CHECK-NEXT: local.tee 1 769; CHECK-NEXT: global.set __stack_pointer 770; CHECK-NEXT: local.get 1 771; CHECK-NEXT: local.get 0 772; CHECK-NEXT: call __fixsfti 773; CHECK-NEXT: local.get 1 774; CHECK-NEXT: i64.load 8 775; CHECK-NEXT: local.set 2 776; CHECK-NEXT: local.get 1 777; CHECK-NEXT: i64.load 0 778; CHECK-NEXT: local.set 3 779; CHECK-NEXT: local.get 1 780; CHECK-NEXT: i32.const 16 781; CHECK-NEXT: i32.add 782; CHECK-NEXT: global.set __stack_pointer 783; CHECK-NEXT: local.get 3 784; CHECK-NEXT: i64.const 0 785; CHECK-NEXT: local.get 2 786; CHECK-NEXT: i64.const 1 787; CHECK-NEXT: i64.lt_s 788; CHECK-NEXT: local.tee 1 789; CHECK-NEXT: i64.select 790; CHECK-NEXT: local.tee 3 791; CHECK-NEXT: i64.const 0 792; CHECK-NEXT: local.get 3 793; CHECK-NEXT: i64.const 0 794; CHECK-NEXT: i64.ne 795; CHECK-NEXT: local.get 2 796; CHECK-NEXT: i64.const 1 797; CHECK-NEXT: local.get 1 798; CHECK-NEXT: i64.select 799; CHECK-NEXT: local.tee 2 800; CHECK-NEXT: i64.const 0 801; CHECK-NEXT: i64.gt_s 802; CHECK-NEXT: local.get 2 803; CHECK-NEXT: i64.eqz 804; CHECK-NEXT: i32.select 805; CHECK-NEXT: i64.select 806; CHECK-NEXT: # fallthrough-return 807entry: 808 %conv = fptosi float %x to i128 809 %0 = icmp slt i128 %conv, 18446744073709551616 810 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 811 %1 = icmp sgt i128 %spec.store.select, 0 812 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 0 813 %conv6 = trunc i128 %spec.store.select7 to i64 814 ret i64 %conv6 815} 816 817define i64 @ustest_f32i64_cse_combine(float %x) #0 { 818; CHECK-LABEL: ustest_f32i64_cse_combine: 819; CHECK: .functype ustest_f32i64_cse_combine (f32) -> (i64) 820; CHECK-NEXT: .local i32, i64, i64 821; CHECK-NEXT: # %bb.0: # %entry 822; CHECK-NEXT: global.get __stack_pointer 823; CHECK-NEXT: i32.const 16 824; CHECK-NEXT: i32.sub 825; CHECK-NEXT: local.tee 1 826; CHECK-NEXT: global.set __stack_pointer 827; CHECK-NEXT: local.get 1 828; CHECK-NEXT: local.get 0 829; CHECK-NEXT: call __fixsfti 830; CHECK-NEXT: local.get 1 831; CHECK-NEXT: i64.load 8 832; CHECK-NEXT: local.set 2 833; CHECK-NEXT: local.get 1 834; CHECK-NEXT: i64.load 0 835; CHECK-NEXT: local.set 3 836; CHECK-NEXT: local.get 1 837; CHECK-NEXT: i32.const 16 838; CHECK-NEXT: i32.add 839; CHECK-NEXT: global.set __stack_pointer 840; CHECK-NEXT: i64.const 0 841; CHECK-NEXT: local.get 3 842; CHECK-NEXT: i64.const 0 843; CHECK-NEXT: local.get 2 844; CHECK-NEXT: i64.const 1 845; CHECK-NEXT: i64.lt_s 846; CHECK-NEXT: local.tee 1 847; CHECK-NEXT: i64.select 848; CHECK-NEXT: local.get 2 849; CHECK-NEXT: i64.const 1 850; CHECK-NEXT: local.get 1 851; CHECK-NEXT: i64.select 852; CHECK-NEXT: i64.const 0 853; CHECK-NEXT: i64.lt_s 854; CHECK-NEXT: i64.select 855; CHECK-NEXT: # fallthrough-return 856entry: 857 %conv = fptosi float %x to i128 858 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616) 859 %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0) 860 %conv6 = trunc i128 %spec.store.select7 to i64 861 ret i64 %conv6 862} 863 864define i64 @stest_f16i64(half %x) { 865; CHECK-LABEL: stest_f16i64: 866; CHECK: .functype stest_f16i64 (f32) -> (i64) 867; CHECK-NEXT: # %bb.0: # %entry 868; CHECK-NEXT: local.get 0 869; CHECK-NEXT: call __truncsfhf2 870; CHECK-NEXT: call __extendhfsf2 871; CHECK-NEXT: i64.trunc_sat_f32_s 872; CHECK-NEXT: # fallthrough-return 873entry: 874 %conv = fptosi half %x to i128 875 %0 = icmp slt i128 %conv, 9223372036854775807 876 %spec.store.select = select i1 %0, i128 %conv, i128 9223372036854775807 877 %1 = icmp sgt i128 %spec.store.select, -9223372036854775808 878 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 -9223372036854775808 879 %conv6 = trunc i128 %spec.store.select7 to i64 880 ret i64 %conv6 881} 882 883define i64 @utesth_f16i64(half %x) { 884; CHECK-LABEL: utesth_f16i64: 885; CHECK: .functype utesth_f16i64 (f32) -> (i64) 886; CHECK-NEXT: .local i32, i64, i64 887; CHECK-NEXT: # %bb.0: # %entry 888; CHECK-NEXT: global.get __stack_pointer 889; CHECK-NEXT: i32.const 16 890; CHECK-NEXT: i32.sub 891; CHECK-NEXT: local.tee 1 892; CHECK-NEXT: global.set __stack_pointer 893; CHECK-NEXT: local.get 1 894; CHECK-NEXT: local.get 0 895; CHECK-NEXT: call __truncsfhf2 896; CHECK-NEXT: call __extendhfsf2 897; CHECK-NEXT: call __fixunssfti 898; CHECK-NEXT: local.get 1 899; CHECK-NEXT: i64.load 8 900; CHECK-NEXT: local.set 2 901; CHECK-NEXT: local.get 1 902; CHECK-NEXT: i64.load 0 903; CHECK-NEXT: local.set 3 904; CHECK-NEXT: local.get 1 905; CHECK-NEXT: i32.const 16 906; CHECK-NEXT: i32.add 907; CHECK-NEXT: global.set __stack_pointer 908; CHECK-NEXT: local.get 3 909; CHECK-NEXT: i64.const 0 910; CHECK-NEXT: local.get 2 911; CHECK-NEXT: i64.eqz 912; CHECK-NEXT: i64.select 913; CHECK-NEXT: # fallthrough-return 914entry: 915 %conv = fptoui half %x to i128 916 %0 = icmp ult i128 %conv, 18446744073709551616 917 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 918 %conv6 = trunc i128 %spec.store.select to i64 919 ret i64 %conv6 920} 921 922define i64 @utesth_f16i64_cse(half %x) { 923; CHECK-LABEL: utesth_f16i64_cse: 924; CHECK: .functype utesth_f16i64_cse (f32) -> (i64) 925; CHECK-NEXT: .local i32, i64 926; CHECK-NEXT: # %bb.0: # %entry 927; CHECK-NEXT: global.get __stack_pointer 928; CHECK-NEXT: i32.const 16 929; CHECK-NEXT: i32.sub 930; CHECK-NEXT: local.tee 1 931; CHECK-NEXT: global.set __stack_pointer 932; CHECK-NEXT: local.get 1 933; CHECK-NEXT: local.get 0 934; CHECK-NEXT: call __truncsfhf2 935; CHECK-NEXT: call __extendhfsf2 936; CHECK-NEXT: call __fixunssfti 937; CHECK-NEXT: local.get 1 938; CHECK-NEXT: i64.load 0 939; CHECK-NEXT: local.set 2 940; CHECK-NEXT: local.get 1 941; CHECK-NEXT: i32.const 16 942; CHECK-NEXT: i32.add 943; CHECK-NEXT: global.set __stack_pointer 944; CHECK-NEXT: local.get 2 945; CHECK-NEXT: # fallthrough-return 946entry: 947 %conv = fptoui half %x to i128 948 %conv6 = trunc i128 %conv to i64 949 ret i64 %conv6 950} 951 952define i64 @ustest_f16i64(half %x) { 953; CHECK-LABEL: ustest_f16i64: 954; CHECK: .functype ustest_f16i64 (f32) -> (i64) 955; CHECK-NEXT: .local i32, i64, i64 956; CHECK-NEXT: # %bb.0: # %entry 957; CHECK-NEXT: global.get __stack_pointer 958; CHECK-NEXT: i32.const 16 959; CHECK-NEXT: i32.sub 960; CHECK-NEXT: local.tee 1 961; CHECK-NEXT: global.set __stack_pointer 962; CHECK-NEXT: local.get 1 963; CHECK-NEXT: local.get 0 964; CHECK-NEXT: call __truncsfhf2 965; CHECK-NEXT: call __extendhfsf2 966; CHECK-NEXT: call __fixsfti 967; CHECK-NEXT: local.get 1 968; CHECK-NEXT: i64.load 8 969; CHECK-NEXT: local.set 2 970; CHECK-NEXT: local.get 1 971; CHECK-NEXT: i64.load 0 972; CHECK-NEXT: local.set 3 973; CHECK-NEXT: local.get 1 974; CHECK-NEXT: i32.const 16 975; CHECK-NEXT: i32.add 976; CHECK-NEXT: global.set __stack_pointer 977; CHECK-NEXT: local.get 3 978; CHECK-NEXT: i64.const 0 979; CHECK-NEXT: local.get 2 980; CHECK-NEXT: i64.const 1 981; CHECK-NEXT: i64.lt_s 982; CHECK-NEXT: local.tee 1 983; CHECK-NEXT: i64.select 984; CHECK-NEXT: local.tee 3 985; CHECK-NEXT: i64.const 0 986; CHECK-NEXT: local.get 3 987; CHECK-NEXT: i64.const 0 988; CHECK-NEXT: i64.ne 989; CHECK-NEXT: local.get 2 990; CHECK-NEXT: i64.const 1 991; CHECK-NEXT: local.get 1 992; CHECK-NEXT: i64.select 993; CHECK-NEXT: local.tee 2 994; CHECK-NEXT: i64.const 0 995; CHECK-NEXT: i64.gt_s 996; CHECK-NEXT: local.get 2 997; CHECK-NEXT: i64.eqz 998; CHECK-NEXT: i32.select 999; CHECK-NEXT: i64.select 1000; CHECK-NEXT: # fallthrough-return 1001entry: 1002 %conv = fptosi half %x to i128 1003 %0 = icmp slt i128 %conv, 18446744073709551616 1004 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 1005 %1 = icmp sgt i128 %spec.store.select, 0 1006 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 0 1007 %conv6 = trunc i128 %spec.store.select7 to i64 1008 ret i64 %conv6 1009} 1010 1011 1012 1013 1014; i32 saturate 1015 1016define i32 @stest_f64i32_mm(double %x) { 1017; CHECK-LABEL: stest_f64i32_mm: 1018; CHECK: .functype stest_f64i32_mm (f64) -> (i32) 1019; CHECK-NEXT: # %bb.0: # %entry 1020; CHECK-NEXT: local.get 0 1021; CHECK-NEXT: i32.trunc_sat_f64_s 1022; CHECK-NEXT: # fallthrough-return 1023entry: 1024 %conv = fptosi double %x to i64 1025 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) 1026 %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648) 1027 %conv6 = trunc i64 %spec.store.select7 to i32 1028 ret i32 %conv6 1029} 1030 1031define i32 @utest_f64i32_mm(double %x) { 1032; CHECK-LABEL: utest_f64i32_mm: 1033; CHECK: .functype utest_f64i32_mm (f64) -> (i32) 1034; CHECK-NEXT: # %bb.0: # %entry 1035; CHECK-NEXT: local.get 0 1036; CHECK-NEXT: i32.trunc_sat_f64_u 1037; CHECK-NEXT: # fallthrough-return 1038entry: 1039 %conv = fptoui double %x to i64 1040 %spec.store.select = call i64 @llvm.umin.i64(i64 %conv, i64 4294967295) 1041 %conv6 = trunc i64 %spec.store.select to i32 1042 ret i32 %conv6 1043} 1044 1045define i32 @ustest_f64i32_mm(double %x) { 1046; CHECK-LABEL: ustest_f64i32_mm: 1047; CHECK: .functype ustest_f64i32_mm (f64) -> (i32) 1048; CHECK-NEXT: # %bb.0: # %entry 1049; CHECK-NEXT: local.get 0 1050; CHECK-NEXT: i32.trunc_sat_f64_u 1051; CHECK-NEXT: # fallthrough-return 1052entry: 1053 %conv = fptosi double %x to i64 1054 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 4294967295) 1055 %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 0) 1056 %conv6 = trunc i64 %spec.store.select7 to i32 1057 ret i32 %conv6 1058} 1059 1060define i32 @stest_f32i32_mm(float %x) { 1061; CHECK-LABEL: stest_f32i32_mm: 1062; CHECK: .functype stest_f32i32_mm (f32) -> (i32) 1063; CHECK-NEXT: # %bb.0: # %entry 1064; CHECK-NEXT: local.get 0 1065; CHECK-NEXT: i32.trunc_sat_f32_s 1066; CHECK-NEXT: # fallthrough-return 1067entry: 1068 %conv = fptosi float %x to i64 1069 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) 1070 %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648) 1071 %conv6 = trunc i64 %spec.store.select7 to i32 1072 ret i32 %conv6 1073} 1074 1075define i32 @utest_f32i32_mm(float %x) { 1076; CHECK-LABEL: utest_f32i32_mm: 1077; CHECK: .functype utest_f32i32_mm (f32) -> (i32) 1078; CHECK-NEXT: # %bb.0: # %entry 1079; CHECK-NEXT: local.get 0 1080; CHECK-NEXT: i32.trunc_sat_f32_u 1081; CHECK-NEXT: # fallthrough-return 1082entry: 1083 %conv = fptoui float %x to i64 1084 %spec.store.select = call i64 @llvm.umin.i64(i64 %conv, i64 4294967295) 1085 %conv6 = trunc i64 %spec.store.select to i32 1086 ret i32 %conv6 1087} 1088 1089define i32 @ustest_f32i32_mm(float %x) { 1090; CHECK-LABEL: ustest_f32i32_mm: 1091; CHECK: .functype ustest_f32i32_mm (f32) -> (i32) 1092; CHECK-NEXT: # %bb.0: # %entry 1093; CHECK-NEXT: local.get 0 1094; CHECK-NEXT: i32.trunc_sat_f32_u 1095; CHECK-NEXT: # fallthrough-return 1096entry: 1097 %conv = fptosi float %x to i64 1098 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 4294967295) 1099 %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 0) 1100 %conv6 = trunc i64 %spec.store.select7 to i32 1101 ret i32 %conv6 1102} 1103 1104define i32 @stest_f16i32_mm(half %x) { 1105; CHECK-LABEL: stest_f16i32_mm: 1106; CHECK: .functype stest_f16i32_mm (f32) -> (i32) 1107; CHECK-NEXT: # %bb.0: # %entry 1108; CHECK-NEXT: local.get 0 1109; CHECK-NEXT: call __truncsfhf2 1110; CHECK-NEXT: call __extendhfsf2 1111; CHECK-NEXT: i32.trunc_sat_f32_s 1112; CHECK-NEXT: # fallthrough-return 1113entry: 1114 %conv = fptosi half %x to i64 1115 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) 1116 %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648) 1117 %conv6 = trunc i64 %spec.store.select7 to i32 1118 ret i32 %conv6 1119} 1120 1121define i32 @utesth_f16i32_mm(half %x) { 1122; CHECK-LABEL: utesth_f16i32_mm: 1123; CHECK: .functype utesth_f16i32_mm (f32) -> (i32) 1124; CHECK-NEXT: # %bb.0: # %entry 1125; CHECK-NEXT: local.get 0 1126; CHECK-NEXT: call __truncsfhf2 1127; CHECK-NEXT: call __extendhfsf2 1128; CHECK-NEXT: i32.trunc_sat_f32_u 1129; CHECK-NEXT: # fallthrough-return 1130entry: 1131 %conv = fptoui half %x to i64 1132 %spec.store.select = call i64 @llvm.umin.i64(i64 %conv, i64 4294967295) 1133 %conv6 = trunc i64 %spec.store.select to i32 1134 ret i32 %conv6 1135} 1136 1137define i32 @ustest_f16i32_mm(half %x) { 1138; CHECK-LABEL: ustest_f16i32_mm: 1139; CHECK: .functype ustest_f16i32_mm (f32) -> (i32) 1140; CHECK-NEXT: # %bb.0: # %entry 1141; CHECK-NEXT: local.get 0 1142; CHECK-NEXT: call __truncsfhf2 1143; CHECK-NEXT: call __extendhfsf2 1144; CHECK-NEXT: i32.trunc_sat_f32_u 1145; CHECK-NEXT: # fallthrough-return 1146entry: 1147 %conv = fptosi half %x to i64 1148 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 4294967295) 1149 %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 0) 1150 %conv6 = trunc i64 %spec.store.select7 to i32 1151 ret i32 %conv6 1152} 1153 1154define i32 @ustest_f16i32_mm_cse(half %x) { 1155; CHECK-LABEL: ustest_f16i32_mm_cse: 1156; CHECK: .functype ustest_f16i32_mm_cse (f32) -> (i32) 1157; CHECK-NEXT: # %bb.0: # %entry 1158; CHECK-NEXT: local.get 0 1159; CHECK-NEXT: call __truncsfhf2 1160; CHECK-NEXT: call __extendhfsf2 1161; CHECK-NEXT: i32.trunc_sat_f32_u 1162; CHECK-NEXT: # fallthrough-return 1163entry: 1164 %conv = fptosi half %x to i64 1165 %spec.store.select7 = call i64 @llvm.smax.i64(i64 %conv, i64 0) 1166 %conv6 = trunc i64 %spec.store.select7 to i32 1167 ret i32 %conv6 1168} 1169 1170; i16 saturate 1171 1172define i16 @stest_f64i16_mm(double %x) { 1173; CHECK-LABEL: stest_f64i16_mm: 1174; CHECK: .functype stest_f64i16_mm (f64) -> (i32) 1175; CHECK-NEXT: .local i32 1176; CHECK-NEXT: # %bb.0: # %entry 1177; CHECK-NEXT: local.get 0 1178; CHECK-NEXT: i32.trunc_sat_f64_s 1179; CHECK-NEXT: local.tee 1 1180; CHECK-NEXT: i32.const 32767 1181; CHECK-NEXT: local.get 1 1182; CHECK-NEXT: i32.const 32767 1183; CHECK-NEXT: i32.lt_s 1184; CHECK-NEXT: i32.select 1185; CHECK-NEXT: local.tee 1 1186; CHECK-NEXT: i32.const -32768 1187; CHECK-NEXT: local.get 1 1188; CHECK-NEXT: i32.const -32768 1189; CHECK-NEXT: i32.gt_s 1190; CHECK-NEXT: i32.select 1191; CHECK-NEXT: # fallthrough-return 1192entry: 1193 %conv = fptosi double %x to i32 1194 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 32767) 1195 %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768) 1196 %conv6 = trunc i32 %spec.store.select7 to i16 1197 ret i16 %conv6 1198} 1199 1200define i16 @utest_f64i16_mm(double %x) { 1201; CHECK-LABEL: utest_f64i16_mm: 1202; CHECK: .functype utest_f64i16_mm (f64) -> (i32) 1203; CHECK-NEXT: .local i32 1204; CHECK-NEXT: # %bb.0: # %entry 1205; CHECK-NEXT: local.get 0 1206; CHECK-NEXT: i32.trunc_sat_f64_u 1207; CHECK-NEXT: local.tee 1 1208; CHECK-NEXT: i32.const 65535 1209; CHECK-NEXT: local.get 1 1210; CHECK-NEXT: i32.const 65535 1211; CHECK-NEXT: i32.lt_u 1212; CHECK-NEXT: i32.select 1213; CHECK-NEXT: # fallthrough-return 1214entry: 1215 %conv = fptoui double %x to i32 1216 %spec.store.select = call i32 @llvm.umin.i32(i32 %conv, i32 65535) 1217 %conv6 = trunc i32 %spec.store.select to i16 1218 ret i16 %conv6 1219} 1220 1221define i16 @ustest_f64i16_mm(double %x) { 1222; CHECK-LABEL: ustest_f64i16_mm: 1223; CHECK: .functype ustest_f64i16_mm (f64) -> (i32) 1224; CHECK-NEXT: .local i32 1225; CHECK-NEXT: # %bb.0: # %entry 1226; CHECK-NEXT: local.get 0 1227; CHECK-NEXT: i32.trunc_sat_f64_s 1228; CHECK-NEXT: local.tee 1 1229; CHECK-NEXT: i32.const 65535 1230; CHECK-NEXT: local.get 1 1231; CHECK-NEXT: i32.const 65535 1232; CHECK-NEXT: i32.lt_s 1233; CHECK-NEXT: i32.select 1234; CHECK-NEXT: local.tee 1 1235; CHECK-NEXT: i32.const 0 1236; CHECK-NEXT: local.get 1 1237; CHECK-NEXT: i32.const 0 1238; CHECK-NEXT: i32.gt_s 1239; CHECK-NEXT: i32.select 1240; CHECK-NEXT: # fallthrough-return 1241entry: 1242 %conv = fptosi double %x to i32 1243 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 65535) 1244 %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 0) 1245 %conv6 = trunc i32 %spec.store.select7 to i16 1246 ret i16 %conv6 1247} 1248 1249define i16 @stest_f32i16_mm(float %x) { 1250; CHECK-LABEL: stest_f32i16_mm: 1251; CHECK: .functype stest_f32i16_mm (f32) -> (i32) 1252; CHECK-NEXT: .local i32 1253; CHECK-NEXT: # %bb.0: # %entry 1254; CHECK-NEXT: local.get 0 1255; CHECK-NEXT: i32.trunc_sat_f32_s 1256; CHECK-NEXT: local.tee 1 1257; CHECK-NEXT: i32.const 32767 1258; CHECK-NEXT: local.get 1 1259; CHECK-NEXT: i32.const 32767 1260; CHECK-NEXT: i32.lt_s 1261; CHECK-NEXT: i32.select 1262; CHECK-NEXT: local.tee 1 1263; CHECK-NEXT: i32.const -32768 1264; CHECK-NEXT: local.get 1 1265; CHECK-NEXT: i32.const -32768 1266; CHECK-NEXT: i32.gt_s 1267; CHECK-NEXT: i32.select 1268; CHECK-NEXT: # fallthrough-return 1269entry: 1270 %conv = fptosi float %x to i32 1271 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 32767) 1272 %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768) 1273 %conv6 = trunc i32 %spec.store.select7 to i16 1274 ret i16 %conv6 1275} 1276 1277define i16 @utest_f32i16_mm(float %x) { 1278; CHECK-LABEL: utest_f32i16_mm: 1279; CHECK: .functype utest_f32i16_mm (f32) -> (i32) 1280; CHECK-NEXT: .local i32 1281; CHECK-NEXT: # %bb.0: # %entry 1282; CHECK-NEXT: local.get 0 1283; CHECK-NEXT: i32.trunc_sat_f32_u 1284; CHECK-NEXT: local.tee 1 1285; CHECK-NEXT: i32.const 65535 1286; CHECK-NEXT: local.get 1 1287; CHECK-NEXT: i32.const 65535 1288; CHECK-NEXT: i32.lt_u 1289; CHECK-NEXT: i32.select 1290; CHECK-NEXT: # fallthrough-return 1291entry: 1292 %conv = fptoui float %x to i32 1293 %spec.store.select = call i32 @llvm.umin.i32(i32 %conv, i32 65535) 1294 %conv6 = trunc i32 %spec.store.select to i16 1295 ret i16 %conv6 1296} 1297 1298define i16 @ustest_f32i16_mm(float %x) { 1299; CHECK-LABEL: ustest_f32i16_mm: 1300; CHECK: .functype ustest_f32i16_mm (f32) -> (i32) 1301; CHECK-NEXT: .local i32 1302; CHECK-NEXT: # %bb.0: # %entry 1303; CHECK-NEXT: local.get 0 1304; CHECK-NEXT: i32.trunc_sat_f32_s 1305; CHECK-NEXT: local.tee 1 1306; CHECK-NEXT: i32.const 65535 1307; CHECK-NEXT: local.get 1 1308; CHECK-NEXT: i32.const 65535 1309; CHECK-NEXT: i32.lt_s 1310; CHECK-NEXT: i32.select 1311; CHECK-NEXT: local.tee 1 1312; CHECK-NEXT: i32.const 0 1313; CHECK-NEXT: local.get 1 1314; CHECK-NEXT: i32.const 0 1315; CHECK-NEXT: i32.gt_s 1316; CHECK-NEXT: i32.select 1317; CHECK-NEXT: # fallthrough-return 1318entry: 1319 %conv = fptosi float %x to i32 1320 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 65535) 1321 %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 0) 1322 %conv6 = trunc i32 %spec.store.select7 to i16 1323 ret i16 %conv6 1324} 1325 1326define i16 @stest_f16i16_mm(half %x) { 1327; CHECK-LABEL: stest_f16i16_mm: 1328; CHECK: .functype stest_f16i16_mm (f32) -> (i32) 1329; CHECK-NEXT: .local i32 1330; CHECK-NEXT: # %bb.0: # %entry 1331; CHECK-NEXT: local.get 0 1332; CHECK-NEXT: call __truncsfhf2 1333; CHECK-NEXT: call __extendhfsf2 1334; CHECK-NEXT: i32.trunc_sat_f32_s 1335; CHECK-NEXT: local.tee 1 1336; CHECK-NEXT: i32.const 32767 1337; CHECK-NEXT: local.get 1 1338; CHECK-NEXT: i32.const 32767 1339; CHECK-NEXT: i32.lt_s 1340; CHECK-NEXT: i32.select 1341; CHECK-NEXT: local.tee 1 1342; CHECK-NEXT: i32.const -32768 1343; CHECK-NEXT: local.get 1 1344; CHECK-NEXT: i32.const -32768 1345; CHECK-NEXT: i32.gt_s 1346; CHECK-NEXT: i32.select 1347; CHECK-NEXT: # fallthrough-return 1348entry: 1349 %conv = fptosi half %x to i32 1350 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 32767) 1351 %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768) 1352 %conv6 = trunc i32 %spec.store.select7 to i16 1353 ret i16 %conv6 1354} 1355 1356define i16 @utesth_f16i16_mm(half %x) { 1357; CHECK-LABEL: utesth_f16i16_mm: 1358; CHECK: .functype utesth_f16i16_mm (f32) -> (i32) 1359; CHECK-NEXT: .local i32 1360; CHECK-NEXT: # %bb.0: # %entry 1361; CHECK-NEXT: local.get 0 1362; CHECK-NEXT: call __truncsfhf2 1363; CHECK-NEXT: call __extendhfsf2 1364; CHECK-NEXT: i32.trunc_sat_f32_u 1365; CHECK-NEXT: local.tee 1 1366; CHECK-NEXT: i32.const 65535 1367; CHECK-NEXT: local.get 1 1368; CHECK-NEXT: i32.const 65535 1369; CHECK-NEXT: i32.lt_u 1370; CHECK-NEXT: i32.select 1371; CHECK-NEXT: # fallthrough-return 1372entry: 1373 %conv = fptoui half %x to i32 1374 %spec.store.select = call i32 @llvm.umin.i32(i32 %conv, i32 65535) 1375 %conv6 = trunc i32 %spec.store.select to i16 1376 ret i16 %conv6 1377} 1378 1379define i16 @ustest_f16i16_mm(half %x) { 1380; CHECK-LABEL: ustest_f16i16_mm: 1381; CHECK: .functype ustest_f16i16_mm (f32) -> (i32) 1382; CHECK-NEXT: .local i32 1383; CHECK-NEXT: # %bb.0: # %entry 1384; CHECK-NEXT: local.get 0 1385; CHECK-NEXT: call __truncsfhf2 1386; CHECK-NEXT: call __extendhfsf2 1387; CHECK-NEXT: i32.trunc_sat_f32_s 1388; CHECK-NEXT: local.tee 1 1389; CHECK-NEXT: i32.const 65535 1390; CHECK-NEXT: local.get 1 1391; CHECK-NEXT: i32.const 65535 1392; CHECK-NEXT: i32.lt_s 1393; CHECK-NEXT: i32.select 1394; CHECK-NEXT: local.tee 1 1395; CHECK-NEXT: i32.const 0 1396; CHECK-NEXT: local.get 1 1397; CHECK-NEXT: i32.const 0 1398; CHECK-NEXT: i32.gt_s 1399; CHECK-NEXT: i32.select 1400; CHECK-NEXT: # fallthrough-return 1401entry: 1402 %conv = fptosi half %x to i32 1403 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 65535) 1404 %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 0) 1405 %conv6 = trunc i32 %spec.store.select7 to i16 1406 ret i16 %conv6 1407} 1408 1409define i16 @ustest_f16i16_mm_cse(half %x) { 1410; CHECK-LABEL: ustest_f16i16_mm_cse: 1411; CHECK: .functype ustest_f16i16_mm_cse (f32) -> (i32) 1412; CHECK-NEXT: # %bb.0: # %entry 1413; CHECK-NEXT: local.get 0 1414; CHECK-NEXT: call __truncsfhf2 1415; CHECK-NEXT: call __extendhfsf2 1416; CHECK-NEXT: i32.trunc_sat_f32_u 1417; CHECK-NEXT: # fallthrough-return 1418entry: 1419 %conv = fptosi half %x to i32 1420 %spec.store.select7 = call i32 @llvm.smax.i32(i32 %conv, i32 0) 1421 %conv6 = trunc i32 %spec.store.select7 to i16 1422 ret i16 %conv6 1423} 1424 1425; i64 saturate 1426 1427define i64 @stest_f64i64_mm(double %x) { 1428; CHECK-LABEL: stest_f64i64_mm: 1429; CHECK: .functype stest_f64i64_mm (f64) -> (i64) 1430; CHECK-NEXT: # %bb.0: # %entry 1431; CHECK-NEXT: local.get 0 1432; CHECK-NEXT: i64.trunc_sat_f64_s 1433; CHECK-NEXT: # fallthrough-return 1434entry: 1435 %conv = fptosi double %x to i128 1436 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807) 1437 %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808) 1438 %conv6 = trunc i128 %spec.store.select7 to i64 1439 ret i64 %conv6 1440} 1441 1442define i64 @utest_f64i64_mm(double %x) { 1443; CHECK-LABEL: utest_f64i64_mm: 1444; CHECK: .functype utest_f64i64_mm (f64) -> (i64) 1445; CHECK-NEXT: .local i32, i64, i64 1446; CHECK-NEXT: # %bb.0: # %entry 1447; CHECK-NEXT: global.get __stack_pointer 1448; CHECK-NEXT: i32.const 16 1449; CHECK-NEXT: i32.sub 1450; CHECK-NEXT: local.tee 1 1451; CHECK-NEXT: global.set __stack_pointer 1452; CHECK-NEXT: local.get 1 1453; CHECK-NEXT: local.get 0 1454; CHECK-NEXT: call __fixunsdfti 1455; CHECK-NEXT: local.get 1 1456; CHECK-NEXT: i64.load 8 1457; CHECK-NEXT: local.set 2 1458; CHECK-NEXT: local.get 1 1459; CHECK-NEXT: i64.load 0 1460; CHECK-NEXT: local.set 3 1461; CHECK-NEXT: local.get 1 1462; CHECK-NEXT: i32.const 16 1463; CHECK-NEXT: i32.add 1464; CHECK-NEXT: global.set __stack_pointer 1465; CHECK-NEXT: local.get 3 1466; CHECK-NEXT: i64.const 0 1467; CHECK-NEXT: local.get 2 1468; CHECK-NEXT: i64.eqz 1469; CHECK-NEXT: i64.select 1470; CHECK-NEXT: # fallthrough-return 1471entry: 1472 %conv = fptoui double %x to i128 1473 %spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616) 1474 %conv6 = trunc i128 %spec.store.select to i64 1475 ret i64 %conv6 1476} 1477 1478define i64 @ustest_f64i64_mm(double %x) { 1479; CHECK-LABEL: ustest_f64i64_mm: 1480; CHECK: .functype ustest_f64i64_mm (f64) -> (i64) 1481; CHECK-NEXT: .local i32, i64, i64 1482; CHECK-NEXT: # %bb.0: # %entry 1483; CHECK-NEXT: global.get __stack_pointer 1484; CHECK-NEXT: i32.const 16 1485; CHECK-NEXT: i32.sub 1486; CHECK-NEXT: local.tee 1 1487; CHECK-NEXT: global.set __stack_pointer 1488; CHECK-NEXT: local.get 1 1489; CHECK-NEXT: local.get 0 1490; CHECK-NEXT: call __fixdfti 1491; CHECK-NEXT: local.get 1 1492; CHECK-NEXT: i64.load 8 1493; CHECK-NEXT: local.set 2 1494; CHECK-NEXT: local.get 1 1495; CHECK-NEXT: i64.load 0 1496; CHECK-NEXT: local.set 3 1497; CHECK-NEXT: local.get 1 1498; CHECK-NEXT: i32.const 16 1499; CHECK-NEXT: i32.add 1500; CHECK-NEXT: global.set __stack_pointer 1501; CHECK-NEXT: i64.const 0 1502; CHECK-NEXT: local.get 3 1503; CHECK-NEXT: i64.const 0 1504; CHECK-NEXT: local.get 2 1505; CHECK-NEXT: i64.const 1 1506; CHECK-NEXT: i64.lt_s 1507; CHECK-NEXT: local.tee 1 1508; CHECK-NEXT: i64.select 1509; CHECK-NEXT: local.get 2 1510; CHECK-NEXT: i64.const 1 1511; CHECK-NEXT: local.get 1 1512; CHECK-NEXT: i64.select 1513; CHECK-NEXT: i64.const 0 1514; CHECK-NEXT: i64.lt_s 1515; CHECK-NEXT: i64.select 1516; CHECK-NEXT: # fallthrough-return 1517entry: 1518 %conv = fptosi double %x to i128 1519 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616) 1520 %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0) 1521 %conv6 = trunc i128 %spec.store.select7 to i64 1522 ret i64 %conv6 1523} 1524 1525define i64 @stest_f32i64_mm(float %x) { 1526; CHECK-LABEL: stest_f32i64_mm: 1527; CHECK: .functype stest_f32i64_mm (f32) -> (i64) 1528; CHECK-NEXT: # %bb.0: # %entry 1529; CHECK-NEXT: local.get 0 1530; CHECK-NEXT: i64.trunc_sat_f32_s 1531; CHECK-NEXT: # fallthrough-return 1532entry: 1533 %conv = fptosi float %x to i128 1534 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807) 1535 %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808) 1536 %conv6 = trunc i128 %spec.store.select7 to i64 1537 ret i64 %conv6 1538} 1539 1540define i64 @utest_f32i64_mm(float %x) { 1541; CHECK-LABEL: utest_f32i64_mm: 1542; CHECK: .functype utest_f32i64_mm (f32) -> (i64) 1543; CHECK-NEXT: .local i32, i64, i64 1544; CHECK-NEXT: # %bb.0: # %entry 1545; CHECK-NEXT: global.get __stack_pointer 1546; CHECK-NEXT: i32.const 16 1547; CHECK-NEXT: i32.sub 1548; CHECK-NEXT: local.tee 1 1549; CHECK-NEXT: global.set __stack_pointer 1550; CHECK-NEXT: local.get 1 1551; CHECK-NEXT: local.get 0 1552; CHECK-NEXT: call __fixunssfti 1553; CHECK-NEXT: local.get 1 1554; CHECK-NEXT: i64.load 8 1555; CHECK-NEXT: local.set 2 1556; CHECK-NEXT: local.get 1 1557; CHECK-NEXT: i64.load 0 1558; CHECK-NEXT: local.set 3 1559; CHECK-NEXT: local.get 1 1560; CHECK-NEXT: i32.const 16 1561; CHECK-NEXT: i32.add 1562; CHECK-NEXT: global.set __stack_pointer 1563; CHECK-NEXT: local.get 3 1564; CHECK-NEXT: i64.const 0 1565; CHECK-NEXT: local.get 2 1566; CHECK-NEXT: i64.eqz 1567; CHECK-NEXT: i64.select 1568; CHECK-NEXT: # fallthrough-return 1569entry: 1570 %conv = fptoui float %x to i128 1571 %spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616) 1572 %conv6 = trunc i128 %spec.store.select to i64 1573 ret i64 %conv6 1574} 1575 1576define i64 @ustest_f32i64_mm(float %x) { 1577; CHECK-LABEL: ustest_f32i64_mm: 1578; CHECK: .functype ustest_f32i64_mm (f32) -> (i64) 1579; CHECK-NEXT: .local i32, i64, i64 1580; CHECK-NEXT: # %bb.0: # %entry 1581; CHECK-NEXT: global.get __stack_pointer 1582; CHECK-NEXT: i32.const 16 1583; CHECK-NEXT: i32.sub 1584; CHECK-NEXT: local.tee 1 1585; CHECK-NEXT: global.set __stack_pointer 1586; CHECK-NEXT: local.get 1 1587; CHECK-NEXT: local.get 0 1588; CHECK-NEXT: call __fixsfti 1589; CHECK-NEXT: local.get 1 1590; CHECK-NEXT: i64.load 8 1591; CHECK-NEXT: local.set 2 1592; CHECK-NEXT: local.get 1 1593; CHECK-NEXT: i64.load 0 1594; CHECK-NEXT: local.set 3 1595; CHECK-NEXT: local.get 1 1596; CHECK-NEXT: i32.const 16 1597; CHECK-NEXT: i32.add 1598; CHECK-NEXT: global.set __stack_pointer 1599; CHECK-NEXT: i64.const 0 1600; CHECK-NEXT: local.get 3 1601; CHECK-NEXT: i64.const 0 1602; CHECK-NEXT: local.get 2 1603; CHECK-NEXT: i64.const 1 1604; CHECK-NEXT: i64.lt_s 1605; CHECK-NEXT: local.tee 1 1606; CHECK-NEXT: i64.select 1607; CHECK-NEXT: local.get 2 1608; CHECK-NEXT: i64.const 1 1609; CHECK-NEXT: local.get 1 1610; CHECK-NEXT: i64.select 1611; CHECK-NEXT: i64.const 0 1612; CHECK-NEXT: i64.lt_s 1613; CHECK-NEXT: i64.select 1614; CHECK-NEXT: # fallthrough-return 1615entry: 1616 %conv = fptosi float %x to i128 1617 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616) 1618 %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0) 1619 %conv6 = trunc i128 %spec.store.select7 to i64 1620 ret i64 %conv6 1621} 1622 1623define i64 @stest_f16i64_mm(half %x) { 1624; CHECK-LABEL: stest_f16i64_mm: 1625; CHECK: .functype stest_f16i64_mm (f32) -> (i64) 1626; CHECK-NEXT: # %bb.0: # %entry 1627; CHECK-NEXT: local.get 0 1628; CHECK-NEXT: call __truncsfhf2 1629; CHECK-NEXT: call __extendhfsf2 1630; CHECK-NEXT: i64.trunc_sat_f32_s 1631; CHECK-NEXT: # fallthrough-return 1632entry: 1633 %conv = fptosi half %x to i128 1634 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807) 1635 %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808) 1636 %conv6 = trunc i128 %spec.store.select7 to i64 1637 ret i64 %conv6 1638} 1639 1640define i64 @utesth_f16i64_mm(half %x) { 1641; CHECK-LABEL: utesth_f16i64_mm: 1642; CHECK: .functype utesth_f16i64_mm (f32) -> (i64) 1643; CHECK-NEXT: .local i32, i64, i64 1644; CHECK-NEXT: # %bb.0: # %entry 1645; CHECK-NEXT: global.get __stack_pointer 1646; CHECK-NEXT: i32.const 16 1647; CHECK-NEXT: i32.sub 1648; CHECK-NEXT: local.tee 1 1649; CHECK-NEXT: global.set __stack_pointer 1650; CHECK-NEXT: local.get 1 1651; CHECK-NEXT: local.get 0 1652; CHECK-NEXT: call __truncsfhf2 1653; CHECK-NEXT: call __extendhfsf2 1654; CHECK-NEXT: call __fixunssfti 1655; CHECK-NEXT: local.get 1 1656; CHECK-NEXT: i64.load 8 1657; CHECK-NEXT: local.set 2 1658; CHECK-NEXT: local.get 1 1659; CHECK-NEXT: i64.load 0 1660; CHECK-NEXT: local.set 3 1661; CHECK-NEXT: local.get 1 1662; CHECK-NEXT: i32.const 16 1663; CHECK-NEXT: i32.add 1664; CHECK-NEXT: global.set __stack_pointer 1665; CHECK-NEXT: local.get 3 1666; CHECK-NEXT: i64.const 0 1667; CHECK-NEXT: local.get 2 1668; CHECK-NEXT: i64.eqz 1669; CHECK-NEXT: i64.select 1670; CHECK-NEXT: # fallthrough-return 1671entry: 1672 %conv = fptoui half %x to i128 1673 %spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616) 1674 %conv6 = trunc i128 %spec.store.select to i64 1675 ret i64 %conv6 1676} 1677 1678define i64 @ustest_f16i64_mm(half %x) { 1679; CHECK-LABEL: ustest_f16i64_mm: 1680; CHECK: .functype ustest_f16i64_mm (f32) -> (i64) 1681; CHECK-NEXT: .local i32, i64, i64 1682; CHECK-NEXT: # %bb.0: # %entry 1683; CHECK-NEXT: global.get __stack_pointer 1684; CHECK-NEXT: i32.const 16 1685; CHECK-NEXT: i32.sub 1686; CHECK-NEXT: local.tee 1 1687; CHECK-NEXT: global.set __stack_pointer 1688; CHECK-NEXT: local.get 1 1689; CHECK-NEXT: local.get 0 1690; CHECK-NEXT: call __truncsfhf2 1691; CHECK-NEXT: call __extendhfsf2 1692; CHECK-NEXT: call __fixsfti 1693; CHECK-NEXT: local.get 1 1694; CHECK-NEXT: i64.load 8 1695; CHECK-NEXT: local.set 2 1696; CHECK-NEXT: local.get 1 1697; CHECK-NEXT: i64.load 0 1698; CHECK-NEXT: local.set 3 1699; CHECK-NEXT: local.get 1 1700; CHECK-NEXT: i32.const 16 1701; CHECK-NEXT: i32.add 1702; CHECK-NEXT: global.set __stack_pointer 1703; CHECK-NEXT: i64.const 0 1704; CHECK-NEXT: local.get 3 1705; CHECK-NEXT: i64.const 0 1706; CHECK-NEXT: local.get 2 1707; CHECK-NEXT: i64.const 1 1708; CHECK-NEXT: i64.lt_s 1709; CHECK-NEXT: local.tee 1 1710; CHECK-NEXT: i64.select 1711; CHECK-NEXT: local.get 2 1712; CHECK-NEXT: i64.const 1 1713; CHECK-NEXT: local.get 1 1714; CHECK-NEXT: i64.select 1715; CHECK-NEXT: i64.const 0 1716; CHECK-NEXT: i64.lt_s 1717; CHECK-NEXT: i64.select 1718; CHECK-NEXT: # fallthrough-return 1719entry: 1720 %conv = fptosi half %x to i128 1721 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616) 1722 %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0) 1723 %conv6 = trunc i128 %spec.store.select7 to i64 1724 ret i64 %conv6 1725} 1726 1727define i64 @utesth_f16i64_mm_cse(half %x) { 1728; CHECK-LABEL: utesth_f16i64_mm_cse: 1729; CHECK: .functype utesth_f16i64_mm_cse (f32) -> (i64) 1730; CHECK-NEXT: .local i32, i64 1731; CHECK-NEXT: # %bb.0: # %entry 1732; CHECK-NEXT: global.get __stack_pointer 1733; CHECK-NEXT: i32.const 16 1734; CHECK-NEXT: i32.sub 1735; CHECK-NEXT: local.tee 1 1736; CHECK-NEXT: global.set __stack_pointer 1737; CHECK-NEXT: local.get 1 1738; CHECK-NEXT: local.get 0 1739; CHECK-NEXT: call __truncsfhf2 1740; CHECK-NEXT: call __extendhfsf2 1741; CHECK-NEXT: call __fixunssfti 1742; CHECK-NEXT: local.get 1 1743; CHECK-NEXT: i64.load 0 1744; CHECK-NEXT: local.set 2 1745; CHECK-NEXT: local.get 1 1746; CHECK-NEXT: i32.const 16 1747; CHECK-NEXT: i32.add 1748; CHECK-NEXT: global.set __stack_pointer 1749; CHECK-NEXT: local.get 2 1750; CHECK-NEXT: # fallthrough-return 1751entry: 1752 %conv = fptoui half %x to i128 1753 %conv6 = trunc i128 %conv to i64 1754 ret i64 %conv6 1755} 1756 1757declare i32 @llvm.smin.i32(i32, i32) 1758declare i32 @llvm.smax.i32(i32, i32) 1759declare i32 @llvm.umin.i32(i32, i32) 1760declare i64 @llvm.smin.i64(i64, i64) 1761declare i64 @llvm.smax.i64(i64, i64) 1762declare i64 @llvm.umin.i64(i64, i64) 1763declare i128 @llvm.smin.i128(i128, i128) 1764declare i128 @llvm.smax.i128(i128, i128) 1765declare i128 @llvm.umin.i128(i128, i128) 1766