1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s 3 4; Test that basic 128-bit integer operations assemble as expected. 5 6target triple = "wasm32-unknown-unknown" 7 8declare i128 @llvm.ctlz.i128(i128, i1) 9declare i128 @llvm.cttz.i128(i128, i1) 10declare i128 @llvm.ctpop.i128(i128) 11 12define i128 @add128(i128 %x, i128 %y) { 13; CHECK-LABEL: add128: 14; CHECK: .functype add128 (i32, i64, i64, i64, i64) -> () 15; CHECK-NEXT: # %bb.0: 16; CHECK-NEXT: local.get $push8=, 0 17; CHECK-NEXT: local.get $push7=, 1 18; CHECK-NEXT: local.get $push6=, 3 19; CHECK-NEXT: i64.add $push5=, $pop7, $pop6 20; CHECK-NEXT: local.tee $push4=, 3, $pop5 21; CHECK-NEXT: i64.store 0($pop8), $pop4 22; CHECK-NEXT: local.get $push13=, 0 23; CHECK-NEXT: local.get $push10=, 2 24; CHECK-NEXT: local.get $push9=, 4 25; CHECK-NEXT: i64.add $push0=, $pop10, $pop9 26; CHECK-NEXT: local.get $push12=, 3 27; CHECK-NEXT: local.get $push11=, 1 28; CHECK-NEXT: i64.lt_u $push1=, $pop12, $pop11 29; CHECK-NEXT: i64.extend_i32_u $push2=, $pop1 30; CHECK-NEXT: i64.add $push3=, $pop0, $pop2 31; CHECK-NEXT: i64.store 8($pop13), $pop3 32; CHECK-NEXT: return 33 %a = add i128 %x, %y 34 ret i128 %a 35} 36 37define i128 @sub128(i128 %x, i128 %y) { 38; CHECK-LABEL: sub128: 39; CHECK: .functype sub128 (i32, i64, i64, i64, i64) -> () 40; CHECK-NEXT: # %bb.0: 41; CHECK-NEXT: local.get $push7=, 0 42; CHECK-NEXT: local.get $push6=, 1 43; CHECK-NEXT: local.get $push5=, 3 44; CHECK-NEXT: i64.sub $push0=, $pop6, $pop5 45; CHECK-NEXT: i64.store 0($pop7), $pop0 46; CHECK-NEXT: local.get $push12=, 0 47; CHECK-NEXT: local.get $push9=, 2 48; CHECK-NEXT: local.get $push8=, 4 49; CHECK-NEXT: i64.sub $push1=, $pop9, $pop8 50; CHECK-NEXT: local.get $push11=, 1 51; CHECK-NEXT: local.get $push10=, 3 52; CHECK-NEXT: i64.lt_u $push2=, $pop11, $pop10 53; CHECK-NEXT: i64.extend_i32_u $push3=, $pop2 54; CHECK-NEXT: i64.sub $push4=, $pop1, $pop3 55; CHECK-NEXT: i64.store 8($pop12), $pop4 56; CHECK-NEXT: return 57 %a = sub i128 %x, %y 58 ret i128 %a 59} 60 61define i128 @mul128(i128 %x, i128 %y) { 62; CHECK-LABEL: mul128: 63; CHECK: .functype mul128 (i32, i64, i64, i64, i64) -> () 64; CHECK-NEXT: .local i32 65; CHECK-NEXT: # %bb.0: 66; CHECK-NEXT: global.get $push2=, __stack_pointer 67; CHECK-NEXT: i32.const $push3=, 16 68; CHECK-NEXT: i32.sub $push7=, $pop2, $pop3 69; CHECK-NEXT: local.tee $push6=, 5, $pop7 70; CHECK-NEXT: global.set __stack_pointer, $pop6 71; CHECK-NEXT: local.get $push12=, 5 72; CHECK-NEXT: local.get $push11=, 1 73; CHECK-NEXT: local.get $push10=, 2 74; CHECK-NEXT: local.get $push9=, 3 75; CHECK-NEXT: local.get $push8=, 4 76; CHECK-NEXT: call __multi3, $pop12, $pop11, $pop10, $pop9, $pop8 77; CHECK-NEXT: local.get $push14=, 0 78; CHECK-NEXT: local.get $push13=, 5 79; CHECK-NEXT: i64.load $push0=, 8($pop13) 80; CHECK-NEXT: i64.store 8($pop14), $pop0 81; CHECK-NEXT: local.get $push16=, 0 82; CHECK-NEXT: local.get $push15=, 5 83; CHECK-NEXT: i64.load $push1=, 0($pop15) 84; CHECK-NEXT: i64.store 0($pop16), $pop1 85; CHECK-NEXT: local.get $push17=, 5 86; CHECK-NEXT: i32.const $push4=, 16 87; CHECK-NEXT: i32.add $push5=, $pop17, $pop4 88; CHECK-NEXT: global.set __stack_pointer, $pop5 89; CHECK-NEXT: return 90 %a = mul i128 %x, %y 91 ret i128 %a 92} 93 94define i128 @sdiv128(i128 %x, i128 %y) { 95; CHECK-LABEL: sdiv128: 96; CHECK: .functype sdiv128 (i32, i64, i64, i64, i64) -> () 97; CHECK-NEXT: .local i32 98; CHECK-NEXT: # %bb.0: 99; CHECK-NEXT: global.get $push2=, __stack_pointer 100; CHECK-NEXT: i32.const $push3=, 16 101; CHECK-NEXT: i32.sub $push7=, $pop2, $pop3 102; CHECK-NEXT: local.tee $push6=, 5, $pop7 103; CHECK-NEXT: global.set __stack_pointer, $pop6 104; CHECK-NEXT: local.get $push12=, 5 105; CHECK-NEXT: local.get $push11=, 1 106; CHECK-NEXT: local.get $push10=, 2 107; CHECK-NEXT: local.get $push9=, 3 108; CHECK-NEXT: local.get $push8=, 4 109; CHECK-NEXT: call __divti3, $pop12, $pop11, $pop10, $pop9, $pop8 110; CHECK-NEXT: local.get $push14=, 0 111; CHECK-NEXT: local.get $push13=, 5 112; CHECK-NEXT: i64.load $push0=, 8($pop13) 113; CHECK-NEXT: i64.store 8($pop14), $pop0 114; CHECK-NEXT: local.get $push16=, 0 115; CHECK-NEXT: local.get $push15=, 5 116; CHECK-NEXT: i64.load $push1=, 0($pop15) 117; CHECK-NEXT: i64.store 0($pop16), $pop1 118; CHECK-NEXT: local.get $push17=, 5 119; CHECK-NEXT: i32.const $push4=, 16 120; CHECK-NEXT: i32.add $push5=, $pop17, $pop4 121; CHECK-NEXT: global.set __stack_pointer, $pop5 122; CHECK-NEXT: return 123 %a = sdiv i128 %x, %y 124 ret i128 %a 125} 126 127define i128 @udiv128(i128 %x, i128 %y) { 128; CHECK-LABEL: udiv128: 129; CHECK: .functype udiv128 (i32, i64, i64, i64, i64) -> () 130; CHECK-NEXT: .local i32 131; CHECK-NEXT: # %bb.0: 132; CHECK-NEXT: global.get $push2=, __stack_pointer 133; CHECK-NEXT: i32.const $push3=, 16 134; CHECK-NEXT: i32.sub $push7=, $pop2, $pop3 135; CHECK-NEXT: local.tee $push6=, 5, $pop7 136; CHECK-NEXT: global.set __stack_pointer, $pop6 137; CHECK-NEXT: local.get $push12=, 5 138; CHECK-NEXT: local.get $push11=, 1 139; CHECK-NEXT: local.get $push10=, 2 140; CHECK-NEXT: local.get $push9=, 3 141; CHECK-NEXT: local.get $push8=, 4 142; CHECK-NEXT: call __udivti3, $pop12, $pop11, $pop10, $pop9, $pop8 143; CHECK-NEXT: local.get $push14=, 0 144; CHECK-NEXT: local.get $push13=, 5 145; CHECK-NEXT: i64.load $push0=, 8($pop13) 146; CHECK-NEXT: i64.store 8($pop14), $pop0 147; CHECK-NEXT: local.get $push16=, 0 148; CHECK-NEXT: local.get $push15=, 5 149; CHECK-NEXT: i64.load $push1=, 0($pop15) 150; CHECK-NEXT: i64.store 0($pop16), $pop1 151; CHECK-NEXT: local.get $push17=, 5 152; CHECK-NEXT: i32.const $push4=, 16 153; CHECK-NEXT: i32.add $push5=, $pop17, $pop4 154; CHECK-NEXT: global.set __stack_pointer, $pop5 155; CHECK-NEXT: return 156 %a = udiv i128 %x, %y 157 ret i128 %a 158} 159 160define i128 @srem128(i128 %x, i128 %y) { 161; CHECK-LABEL: srem128: 162; CHECK: .functype srem128 (i32, i64, i64, i64, i64) -> () 163; CHECK-NEXT: .local i32 164; CHECK-NEXT: # %bb.0: 165; CHECK-NEXT: global.get $push2=, __stack_pointer 166; CHECK-NEXT: i32.const $push3=, 16 167; CHECK-NEXT: i32.sub $push7=, $pop2, $pop3 168; CHECK-NEXT: local.tee $push6=, 5, $pop7 169; CHECK-NEXT: global.set __stack_pointer, $pop6 170; CHECK-NEXT: local.get $push12=, 5 171; CHECK-NEXT: local.get $push11=, 1 172; CHECK-NEXT: local.get $push10=, 2 173; CHECK-NEXT: local.get $push9=, 3 174; CHECK-NEXT: local.get $push8=, 4 175; CHECK-NEXT: call __modti3, $pop12, $pop11, $pop10, $pop9, $pop8 176; CHECK-NEXT: local.get $push14=, 0 177; CHECK-NEXT: local.get $push13=, 5 178; CHECK-NEXT: i64.load $push0=, 8($pop13) 179; CHECK-NEXT: i64.store 8($pop14), $pop0 180; CHECK-NEXT: local.get $push16=, 0 181; CHECK-NEXT: local.get $push15=, 5 182; CHECK-NEXT: i64.load $push1=, 0($pop15) 183; CHECK-NEXT: i64.store 0($pop16), $pop1 184; CHECK-NEXT: local.get $push17=, 5 185; CHECK-NEXT: i32.const $push4=, 16 186; CHECK-NEXT: i32.add $push5=, $pop17, $pop4 187; CHECK-NEXT: global.set __stack_pointer, $pop5 188; CHECK-NEXT: return 189 %a = srem i128 %x, %y 190 ret i128 %a 191} 192 193define i128 @urem128(i128 %x, i128 %y) { 194; CHECK-LABEL: urem128: 195; CHECK: .functype urem128 (i32, i64, i64, i64, i64) -> () 196; CHECK-NEXT: .local i32 197; CHECK-NEXT: # %bb.0: 198; CHECK-NEXT: global.get $push2=, __stack_pointer 199; CHECK-NEXT: i32.const $push3=, 16 200; CHECK-NEXT: i32.sub $push7=, $pop2, $pop3 201; CHECK-NEXT: local.tee $push6=, 5, $pop7 202; CHECK-NEXT: global.set __stack_pointer, $pop6 203; CHECK-NEXT: local.get $push12=, 5 204; CHECK-NEXT: local.get $push11=, 1 205; CHECK-NEXT: local.get $push10=, 2 206; CHECK-NEXT: local.get $push9=, 3 207; CHECK-NEXT: local.get $push8=, 4 208; CHECK-NEXT: call __umodti3, $pop12, $pop11, $pop10, $pop9, $pop8 209; CHECK-NEXT: local.get $push14=, 0 210; CHECK-NEXT: local.get $push13=, 5 211; CHECK-NEXT: i64.load $push0=, 8($pop13) 212; CHECK-NEXT: i64.store 8($pop14), $pop0 213; CHECK-NEXT: local.get $push16=, 0 214; CHECK-NEXT: local.get $push15=, 5 215; CHECK-NEXT: i64.load $push1=, 0($pop15) 216; CHECK-NEXT: i64.store 0($pop16), $pop1 217; CHECK-NEXT: local.get $push17=, 5 218; CHECK-NEXT: i32.const $push4=, 16 219; CHECK-NEXT: i32.add $push5=, $pop17, $pop4 220; CHECK-NEXT: global.set __stack_pointer, $pop5 221; CHECK-NEXT: return 222 %a = urem i128 %x, %y 223 ret i128 %a 224} 225 226define i128 @and128(i128 %x, i128 %y) { 227; CHECK-LABEL: and128: 228; CHECK: .functype and128 (i32, i64, i64, i64, i64) -> () 229; CHECK-NEXT: # %bb.0: 230; CHECK-NEXT: local.get $push4=, 0 231; CHECK-NEXT: local.get $push3=, 2 232; CHECK-NEXT: local.get $push2=, 4 233; CHECK-NEXT: i64.and $push0=, $pop3, $pop2 234; CHECK-NEXT: i64.store 8($pop4), $pop0 235; CHECK-NEXT: local.get $push7=, 0 236; CHECK-NEXT: local.get $push6=, 1 237; CHECK-NEXT: local.get $push5=, 3 238; CHECK-NEXT: i64.and $push1=, $pop6, $pop5 239; CHECK-NEXT: i64.store 0($pop7), $pop1 240; CHECK-NEXT: return 241 %a = and i128 %x, %y 242 ret i128 %a 243} 244 245define i128 @or128(i128 %x, i128 %y) { 246; CHECK-LABEL: or128: 247; CHECK: .functype or128 (i32, i64, i64, i64, i64) -> () 248; CHECK-NEXT: # %bb.0: 249; CHECK-NEXT: local.get $push4=, 0 250; CHECK-NEXT: local.get $push3=, 2 251; CHECK-NEXT: local.get $push2=, 4 252; CHECK-NEXT: i64.or $push0=, $pop3, $pop2 253; CHECK-NEXT: i64.store 8($pop4), $pop0 254; CHECK-NEXT: local.get $push7=, 0 255; CHECK-NEXT: local.get $push6=, 1 256; CHECK-NEXT: local.get $push5=, 3 257; CHECK-NEXT: i64.or $push1=, $pop6, $pop5 258; CHECK-NEXT: i64.store 0($pop7), $pop1 259; CHECK-NEXT: return 260 %a = or i128 %x, %y 261 ret i128 %a 262} 263 264define i128 @xor128(i128 %x, i128 %y) { 265; CHECK-LABEL: xor128: 266; CHECK: .functype xor128 (i32, i64, i64, i64, i64) -> () 267; CHECK-NEXT: # %bb.0: 268; CHECK-NEXT: local.get $push4=, 0 269; CHECK-NEXT: local.get $push3=, 2 270; CHECK-NEXT: local.get $push2=, 4 271; CHECK-NEXT: i64.xor $push0=, $pop3, $pop2 272; CHECK-NEXT: i64.store 8($pop4), $pop0 273; CHECK-NEXT: local.get $push7=, 0 274; CHECK-NEXT: local.get $push6=, 1 275; CHECK-NEXT: local.get $push5=, 3 276; CHECK-NEXT: i64.xor $push1=, $pop6, $pop5 277; CHECK-NEXT: i64.store 0($pop7), $pop1 278; CHECK-NEXT: return 279 %a = xor i128 %x, %y 280 ret i128 %a 281} 282 283define i128 @shl128(i128 %x, i128 %y) { 284; CHECK-LABEL: shl128: 285; CHECK: .functype shl128 (i32, i64, i64, i64, i64) -> () 286; CHECK-NEXT: .local i32 287; CHECK-NEXT: # %bb.0: 288; CHECK-NEXT: global.get $push3=, __stack_pointer 289; CHECK-NEXT: i32.const $push4=, 16 290; CHECK-NEXT: i32.sub $push8=, $pop3, $pop4 291; CHECK-NEXT: local.tee $push7=, 5, $pop8 292; CHECK-NEXT: global.set __stack_pointer, $pop7 293; CHECK-NEXT: local.get $push12=, 5 294; CHECK-NEXT: local.get $push11=, 1 295; CHECK-NEXT: local.get $push10=, 2 296; CHECK-NEXT: local.get $push9=, 3 297; CHECK-NEXT: i32.wrap_i64 $push0=, $pop9 298; CHECK-NEXT: call __ashlti3, $pop12, $pop11, $pop10, $pop0 299; CHECK-NEXT: local.get $push14=, 0 300; CHECK-NEXT: local.get $push13=, 5 301; CHECK-NEXT: i64.load $push1=, 8($pop13) 302; CHECK-NEXT: i64.store 8($pop14), $pop1 303; CHECK-NEXT: local.get $push16=, 0 304; CHECK-NEXT: local.get $push15=, 5 305; CHECK-NEXT: i64.load $push2=, 0($pop15) 306; CHECK-NEXT: i64.store 0($pop16), $pop2 307; CHECK-NEXT: local.get $push17=, 5 308; CHECK-NEXT: i32.const $push5=, 16 309; CHECK-NEXT: i32.add $push6=, $pop17, $pop5 310; CHECK-NEXT: global.set __stack_pointer, $pop6 311; CHECK-NEXT: return 312 %a = shl i128 %x, %y 313 ret i128 %a 314} 315 316define i128 @shr128(i128 %x, i128 %y) { 317; CHECK-LABEL: shr128: 318; CHECK: .functype shr128 (i32, i64, i64, i64, i64) -> () 319; CHECK-NEXT: .local i32 320; CHECK-NEXT: # %bb.0: 321; CHECK-NEXT: global.get $push3=, __stack_pointer 322; CHECK-NEXT: i32.const $push4=, 16 323; CHECK-NEXT: i32.sub $push8=, $pop3, $pop4 324; CHECK-NEXT: local.tee $push7=, 5, $pop8 325; CHECK-NEXT: global.set __stack_pointer, $pop7 326; CHECK-NEXT: local.get $push12=, 5 327; CHECK-NEXT: local.get $push11=, 1 328; CHECK-NEXT: local.get $push10=, 2 329; CHECK-NEXT: local.get $push9=, 3 330; CHECK-NEXT: i32.wrap_i64 $push0=, $pop9 331; CHECK-NEXT: call __lshrti3, $pop12, $pop11, $pop10, $pop0 332; CHECK-NEXT: local.get $push14=, 0 333; CHECK-NEXT: local.get $push13=, 5 334; CHECK-NEXT: i64.load $push1=, 8($pop13) 335; CHECK-NEXT: i64.store 8($pop14), $pop1 336; CHECK-NEXT: local.get $push16=, 0 337; CHECK-NEXT: local.get $push15=, 5 338; CHECK-NEXT: i64.load $push2=, 0($pop15) 339; CHECK-NEXT: i64.store 0($pop16), $pop2 340; CHECK-NEXT: local.get $push17=, 5 341; CHECK-NEXT: i32.const $push5=, 16 342; CHECK-NEXT: i32.add $push6=, $pop17, $pop5 343; CHECK-NEXT: global.set __stack_pointer, $pop6 344; CHECK-NEXT: return 345 %a = lshr i128 %x, %y 346 ret i128 %a 347} 348 349define i128 @sar128(i128 %x, i128 %y) { 350; CHECK-LABEL: sar128: 351; CHECK: .functype sar128 (i32, i64, i64, i64, i64) -> () 352; CHECK-NEXT: .local i32 353; CHECK-NEXT: # %bb.0: 354; CHECK-NEXT: global.get $push3=, __stack_pointer 355; CHECK-NEXT: i32.const $push4=, 16 356; CHECK-NEXT: i32.sub $push8=, $pop3, $pop4 357; CHECK-NEXT: local.tee $push7=, 5, $pop8 358; CHECK-NEXT: global.set __stack_pointer, $pop7 359; CHECK-NEXT: local.get $push12=, 5 360; CHECK-NEXT: local.get $push11=, 1 361; CHECK-NEXT: local.get $push10=, 2 362; CHECK-NEXT: local.get $push9=, 3 363; CHECK-NEXT: i32.wrap_i64 $push0=, $pop9 364; CHECK-NEXT: call __ashrti3, $pop12, $pop11, $pop10, $pop0 365; CHECK-NEXT: local.get $push14=, 0 366; CHECK-NEXT: local.get $push13=, 5 367; CHECK-NEXT: i64.load $push1=, 8($pop13) 368; CHECK-NEXT: i64.store 8($pop14), $pop1 369; CHECK-NEXT: local.get $push16=, 0 370; CHECK-NEXT: local.get $push15=, 5 371; CHECK-NEXT: i64.load $push2=, 0($pop15) 372; CHECK-NEXT: i64.store 0($pop16), $pop2 373; CHECK-NEXT: local.get $push17=, 5 374; CHECK-NEXT: i32.const $push5=, 16 375; CHECK-NEXT: i32.add $push6=, $pop17, $pop5 376; CHECK-NEXT: global.set __stack_pointer, $pop6 377; CHECK-NEXT: return 378 %a = ashr i128 %x, %y 379 ret i128 %a 380} 381 382define i128 @clz128(i128 %x) { 383; CHECK-LABEL: clz128: 384; CHECK: .functype clz128 (i32, i64, i64) -> () 385; CHECK-NEXT: # %bb.0: 386; CHECK-NEXT: local.get $push8=, 0 387; CHECK-NEXT: i64.const $push0=, 0 388; CHECK-NEXT: i64.store 8($pop8), $pop0 389; CHECK-NEXT: local.get $push12=, 0 390; CHECK-NEXT: local.get $push9=, 2 391; CHECK-NEXT: i64.clz $push5=, $pop9 392; CHECK-NEXT: local.get $push10=, 1 393; CHECK-NEXT: i64.clz $push2=, $pop10 394; CHECK-NEXT: i64.const $push3=, 64 395; CHECK-NEXT: i64.add $push4=, $pop2, $pop3 396; CHECK-NEXT: local.get $push11=, 2 397; CHECK-NEXT: i64.const $push7=, 0 398; CHECK-NEXT: i64.ne $push1=, $pop11, $pop7 399; CHECK-NEXT: i64.select $push6=, $pop5, $pop4, $pop1 400; CHECK-NEXT: i64.store 0($pop12), $pop6 401; CHECK-NEXT: return 402 %a = call i128 @llvm.ctlz.i128(i128 %x, i1 false) 403 ret i128 %a 404} 405 406define i128 @clz128_zero_undef(i128 %x) { 407; CHECK-LABEL: clz128_zero_undef: 408; CHECK: .functype clz128_zero_undef (i32, i64, i64) -> () 409; CHECK-NEXT: # %bb.0: 410; CHECK-NEXT: local.get $push8=, 0 411; CHECK-NEXT: i64.const $push0=, 0 412; CHECK-NEXT: i64.store 8($pop8), $pop0 413; CHECK-NEXT: local.get $push12=, 0 414; CHECK-NEXT: local.get $push9=, 2 415; CHECK-NEXT: i64.clz $push5=, $pop9 416; CHECK-NEXT: local.get $push10=, 1 417; CHECK-NEXT: i64.clz $push2=, $pop10 418; CHECK-NEXT: i64.const $push3=, 64 419; CHECK-NEXT: i64.add $push4=, $pop2, $pop3 420; CHECK-NEXT: local.get $push11=, 2 421; CHECK-NEXT: i64.const $push7=, 0 422; CHECK-NEXT: i64.ne $push1=, $pop11, $pop7 423; CHECK-NEXT: i64.select $push6=, $pop5, $pop4, $pop1 424; CHECK-NEXT: i64.store 0($pop12), $pop6 425; CHECK-NEXT: return 426 %a = call i128 @llvm.ctlz.i128(i128 %x, i1 true) 427 ret i128 %a 428} 429 430define i128 @ctz128(i128 %x) { 431; CHECK-LABEL: ctz128: 432; CHECK: .functype ctz128 (i32, i64, i64) -> () 433; CHECK-NEXT: # %bb.0: 434; CHECK-NEXT: local.get $push8=, 0 435; CHECK-NEXT: i64.const $push0=, 0 436; CHECK-NEXT: i64.store 8($pop8), $pop0 437; CHECK-NEXT: local.get $push12=, 0 438; CHECK-NEXT: local.get $push9=, 1 439; CHECK-NEXT: i64.ctz $push5=, $pop9 440; CHECK-NEXT: local.get $push10=, 2 441; CHECK-NEXT: i64.ctz $push2=, $pop10 442; CHECK-NEXT: i64.const $push3=, 64 443; CHECK-NEXT: i64.add $push4=, $pop2, $pop3 444; CHECK-NEXT: local.get $push11=, 1 445; CHECK-NEXT: i64.const $push7=, 0 446; CHECK-NEXT: i64.ne $push1=, $pop11, $pop7 447; CHECK-NEXT: i64.select $push6=, $pop5, $pop4, $pop1 448; CHECK-NEXT: i64.store 0($pop12), $pop6 449; CHECK-NEXT: return 450 %a = call i128 @llvm.cttz.i128(i128 %x, i1 false) 451 ret i128 %a 452} 453 454define i128 @ctz128_zero_undef(i128 %x) { 455; CHECK-LABEL: ctz128_zero_undef: 456; CHECK: .functype ctz128_zero_undef (i32, i64, i64) -> () 457; CHECK-NEXT: # %bb.0: 458; CHECK-NEXT: local.get $push8=, 0 459; CHECK-NEXT: i64.const $push0=, 0 460; CHECK-NEXT: i64.store 8($pop8), $pop0 461; CHECK-NEXT: local.get $push12=, 0 462; CHECK-NEXT: local.get $push9=, 1 463; CHECK-NEXT: i64.ctz $push5=, $pop9 464; CHECK-NEXT: local.get $push10=, 2 465; CHECK-NEXT: i64.ctz $push2=, $pop10 466; CHECK-NEXT: i64.const $push3=, 64 467; CHECK-NEXT: i64.add $push4=, $pop2, $pop3 468; CHECK-NEXT: local.get $push11=, 1 469; CHECK-NEXT: i64.const $push7=, 0 470; CHECK-NEXT: i64.ne $push1=, $pop11, $pop7 471; CHECK-NEXT: i64.select $push6=, $pop5, $pop4, $pop1 472; CHECK-NEXT: i64.store 0($pop12), $pop6 473; CHECK-NEXT: return 474 %a = call i128 @llvm.cttz.i128(i128 %x, i1 true) 475 ret i128 %a 476} 477 478define i128 @popcnt128(i128 %x) { 479; CHECK-LABEL: popcnt128: 480; CHECK: .functype popcnt128 (i32, i64, i64) -> () 481; CHECK-NEXT: # %bb.0: 482; CHECK-NEXT: local.get $push4=, 0 483; CHECK-NEXT: i64.const $push0=, 0 484; CHECK-NEXT: i64.store 8($pop4), $pop0 485; CHECK-NEXT: local.get $push7=, 0 486; CHECK-NEXT: local.get $push5=, 1 487; CHECK-NEXT: i64.popcnt $push2=, $pop5 488; CHECK-NEXT: local.get $push6=, 2 489; CHECK-NEXT: i64.popcnt $push1=, $pop6 490; CHECK-NEXT: i64.add $push3=, $pop2, $pop1 491; CHECK-NEXT: i64.store 0($pop7), $pop3 492; CHECK-NEXT: return 493 %a = call i128 @llvm.ctpop.i128(i128 %x) 494 ret i128 %a 495} 496 497define i32 @eqz128(i128 %x) { 498; CHECK-LABEL: eqz128: 499; CHECK: .functype eqz128 (i64, i64) -> (i32) 500; CHECK-NEXT: # %bb.0: 501; CHECK-NEXT: local.get $push3=, 0 502; CHECK-NEXT: local.get $push2=, 1 503; CHECK-NEXT: i64.or $push0=, $pop3, $pop2 504; CHECK-NEXT: i64.eqz $push1=, $pop0 505; CHECK-NEXT: return $pop1 506 %a = icmp eq i128 %x, 0 507 %b = zext i1 %a to i32 508 ret i32 %b 509} 510 511define i128 @rotl(i128 %x, i128 %y) { 512; CHECK-LABEL: rotl: 513; CHECK: .functype rotl (i32, i64, i64, i64, i64) -> () 514; CHECK-NEXT: .local i32, i32 515; CHECK-NEXT: # %bb.0: 516; CHECK-NEXT: global.get $push8=, __stack_pointer 517; CHECK-NEXT: i32.const $push9=, 32 518; CHECK-NEXT: i32.sub $push17=, $pop8, $pop9 519; CHECK-NEXT: local.tee $push16=, 5, $pop17 520; CHECK-NEXT: global.set __stack_pointer, $pop16 521; CHECK-NEXT: local.get $push18=, 5 522; CHECK-NEXT: i32.const $push12=, 16 523; CHECK-NEXT: i32.add $push13=, $pop18, $pop12 524; CHECK-NEXT: local.get $push21=, 1 525; CHECK-NEXT: local.get $push20=, 2 526; CHECK-NEXT: local.get $push19=, 3 527; CHECK-NEXT: i32.wrap_i64 $push15=, $pop19 528; CHECK-NEXT: local.tee $push14=, 6, $pop15 529; CHECK-NEXT: call __ashlti3, $pop13, $pop21, $pop20, $pop14 530; CHECK-NEXT: local.get $push25=, 5 531; CHECK-NEXT: local.get $push24=, 1 532; CHECK-NEXT: local.get $push23=, 2 533; CHECK-NEXT: i32.const $push0=, 128 534; CHECK-NEXT: local.get $push22=, 6 535; CHECK-NEXT: i32.sub $push1=, $pop0, $pop22 536; CHECK-NEXT: call __lshrti3, $pop25, $pop24, $pop23, $pop1 537; CHECK-NEXT: local.get $push28=, 0 538; CHECK-NEXT: local.get $push26=, 5 539; CHECK-NEXT: i64.load $push2=, 24($pop26) 540; CHECK-NEXT: local.get $push27=, 5 541; CHECK-NEXT: i64.load $push3=, 8($pop27) 542; CHECK-NEXT: i64.or $push4=, $pop2, $pop3 543; CHECK-NEXT: i64.store 8($pop28), $pop4 544; CHECK-NEXT: local.get $push31=, 0 545; CHECK-NEXT: local.get $push29=, 5 546; CHECK-NEXT: i64.load $push5=, 16($pop29) 547; CHECK-NEXT: local.get $push30=, 5 548; CHECK-NEXT: i64.load $push6=, 0($pop30) 549; CHECK-NEXT: i64.or $push7=, $pop5, $pop6 550; CHECK-NEXT: i64.store 0($pop31), $pop7 551; CHECK-NEXT: local.get $push32=, 5 552; CHECK-NEXT: i32.const $push10=, 32 553; CHECK-NEXT: i32.add $push11=, $pop32, $pop10 554; CHECK-NEXT: global.set __stack_pointer, $pop11 555; CHECK-NEXT: return 556 %z = sub i128 128, %y 557 %b = shl i128 %x, %y 558 %c = lshr i128 %x, %z 559 %d = or i128 %b, %c 560 ret i128 %d 561} 562 563define i128 @masked_rotl(i128 %x, i128 %y) { 564; CHECK-LABEL: masked_rotl: 565; CHECK: .functype masked_rotl (i32, i64, i64, i64, i64) -> () 566; CHECK-NEXT: .local i32, i32 567; CHECK-NEXT: # %bb.0: 568; CHECK-NEXT: global.get $push10=, __stack_pointer 569; CHECK-NEXT: i32.const $push11=, 32 570; CHECK-NEXT: i32.sub $push19=, $pop10, $pop11 571; CHECK-NEXT: local.tee $push18=, 5, $pop19 572; CHECK-NEXT: global.set __stack_pointer, $pop18 573; CHECK-NEXT: local.get $push20=, 5 574; CHECK-NEXT: i32.const $push14=, 16 575; CHECK-NEXT: i32.add $push15=, $pop20, $pop14 576; CHECK-NEXT: local.get $push23=, 1 577; CHECK-NEXT: local.get $push22=, 2 578; CHECK-NEXT: local.get $push21=, 3 579; CHECK-NEXT: i32.wrap_i64 $push0=, $pop21 580; CHECK-NEXT: i32.const $push1=, 127 581; CHECK-NEXT: i32.and $push17=, $pop0, $pop1 582; CHECK-NEXT: local.tee $push16=, 6, $pop17 583; CHECK-NEXT: call __ashlti3, $pop15, $pop23, $pop22, $pop16 584; CHECK-NEXT: local.get $push27=, 5 585; CHECK-NEXT: local.get $push26=, 1 586; CHECK-NEXT: local.get $push25=, 2 587; CHECK-NEXT: i32.const $push2=, 128 588; CHECK-NEXT: local.get $push24=, 6 589; CHECK-NEXT: i32.sub $push3=, $pop2, $pop24 590; CHECK-NEXT: call __lshrti3, $pop27, $pop26, $pop25, $pop3 591; CHECK-NEXT: local.get $push30=, 0 592; CHECK-NEXT: local.get $push28=, 5 593; CHECK-NEXT: i64.load $push4=, 24($pop28) 594; CHECK-NEXT: local.get $push29=, 5 595; CHECK-NEXT: i64.load $push5=, 8($pop29) 596; CHECK-NEXT: i64.or $push6=, $pop4, $pop5 597; CHECK-NEXT: i64.store 8($pop30), $pop6 598; CHECK-NEXT: local.get $push33=, 0 599; CHECK-NEXT: local.get $push31=, 5 600; CHECK-NEXT: i64.load $push7=, 16($pop31) 601; CHECK-NEXT: local.get $push32=, 5 602; CHECK-NEXT: i64.load $push8=, 0($pop32) 603; CHECK-NEXT: i64.or $push9=, $pop7, $pop8 604; CHECK-NEXT: i64.store 0($pop33), $pop9 605; CHECK-NEXT: local.get $push34=, 5 606; CHECK-NEXT: i32.const $push12=, 32 607; CHECK-NEXT: i32.add $push13=, $pop34, $pop12 608; CHECK-NEXT: global.set __stack_pointer, $pop13 609; CHECK-NEXT: return 610 %a = and i128 %y, 127 611 %z = sub i128 128, %a 612 %b = shl i128 %x, %a 613 %c = lshr i128 %x, %z 614 %d = or i128 %b, %c 615 ret i128 %d 616} 617 618define i128 @rotr(i128 %x, i128 %y) { 619; CHECK-LABEL: rotr: 620; CHECK: .functype rotr (i32, i64, i64, i64, i64) -> () 621; CHECK-NEXT: .local i32, i32 622; CHECK-NEXT: # %bb.0: 623; CHECK-NEXT: global.get $push8=, __stack_pointer 624; CHECK-NEXT: i32.const $push9=, 32 625; CHECK-NEXT: i32.sub $push17=, $pop8, $pop9 626; CHECK-NEXT: local.tee $push16=, 5, $pop17 627; CHECK-NEXT: global.set __stack_pointer, $pop16 628; CHECK-NEXT: local.get $push18=, 5 629; CHECK-NEXT: i32.const $push12=, 16 630; CHECK-NEXT: i32.add $push13=, $pop18, $pop12 631; CHECK-NEXT: local.get $push21=, 1 632; CHECK-NEXT: local.get $push20=, 2 633; CHECK-NEXT: local.get $push19=, 3 634; CHECK-NEXT: i32.wrap_i64 $push15=, $pop19 635; CHECK-NEXT: local.tee $push14=, 6, $pop15 636; CHECK-NEXT: call __lshrti3, $pop13, $pop21, $pop20, $pop14 637; CHECK-NEXT: local.get $push25=, 5 638; CHECK-NEXT: local.get $push24=, 1 639; CHECK-NEXT: local.get $push23=, 2 640; CHECK-NEXT: i32.const $push0=, 128 641; CHECK-NEXT: local.get $push22=, 6 642; CHECK-NEXT: i32.sub $push1=, $pop0, $pop22 643; CHECK-NEXT: call __ashlti3, $pop25, $pop24, $pop23, $pop1 644; CHECK-NEXT: local.get $push28=, 0 645; CHECK-NEXT: local.get $push26=, 5 646; CHECK-NEXT: i64.load $push2=, 24($pop26) 647; CHECK-NEXT: local.get $push27=, 5 648; CHECK-NEXT: i64.load $push3=, 8($pop27) 649; CHECK-NEXT: i64.or $push4=, $pop2, $pop3 650; CHECK-NEXT: i64.store 8($pop28), $pop4 651; CHECK-NEXT: local.get $push31=, 0 652; CHECK-NEXT: local.get $push29=, 5 653; CHECK-NEXT: i64.load $push5=, 16($pop29) 654; CHECK-NEXT: local.get $push30=, 5 655; CHECK-NEXT: i64.load $push6=, 0($pop30) 656; CHECK-NEXT: i64.or $push7=, $pop5, $pop6 657; CHECK-NEXT: i64.store 0($pop31), $pop7 658; CHECK-NEXT: local.get $push32=, 5 659; CHECK-NEXT: i32.const $push10=, 32 660; CHECK-NEXT: i32.add $push11=, $pop32, $pop10 661; CHECK-NEXT: global.set __stack_pointer, $pop11 662; CHECK-NEXT: return 663 %z = sub i128 128, %y 664 %b = lshr i128 %x, %y 665 %c = shl i128 %x, %z 666 %d = or i128 %b, %c 667 ret i128 %d 668} 669 670define i128 @masked_rotr(i128 %x, i128 %y) { 671; CHECK-LABEL: masked_rotr: 672; CHECK: .functype masked_rotr (i32, i64, i64, i64, i64) -> () 673; CHECK-NEXT: .local i32, i32 674; CHECK-NEXT: # %bb.0: 675; CHECK-NEXT: global.get $push10=, __stack_pointer 676; CHECK-NEXT: i32.const $push11=, 32 677; CHECK-NEXT: i32.sub $push19=, $pop10, $pop11 678; CHECK-NEXT: local.tee $push18=, 5, $pop19 679; CHECK-NEXT: global.set __stack_pointer, $pop18 680; CHECK-NEXT: local.get $push20=, 5 681; CHECK-NEXT: i32.const $push14=, 16 682; CHECK-NEXT: i32.add $push15=, $pop20, $pop14 683; CHECK-NEXT: local.get $push23=, 1 684; CHECK-NEXT: local.get $push22=, 2 685; CHECK-NEXT: local.get $push21=, 3 686; CHECK-NEXT: i32.wrap_i64 $push0=, $pop21 687; CHECK-NEXT: i32.const $push1=, 127 688; CHECK-NEXT: i32.and $push17=, $pop0, $pop1 689; CHECK-NEXT: local.tee $push16=, 6, $pop17 690; CHECK-NEXT: call __lshrti3, $pop15, $pop23, $pop22, $pop16 691; CHECK-NEXT: local.get $push27=, 5 692; CHECK-NEXT: local.get $push26=, 1 693; CHECK-NEXT: local.get $push25=, 2 694; CHECK-NEXT: i32.const $push2=, 128 695; CHECK-NEXT: local.get $push24=, 6 696; CHECK-NEXT: i32.sub $push3=, $pop2, $pop24 697; CHECK-NEXT: call __ashlti3, $pop27, $pop26, $pop25, $pop3 698; CHECK-NEXT: local.get $push30=, 0 699; CHECK-NEXT: local.get $push28=, 5 700; CHECK-NEXT: i64.load $push4=, 24($pop28) 701; CHECK-NEXT: local.get $push29=, 5 702; CHECK-NEXT: i64.load $push5=, 8($pop29) 703; CHECK-NEXT: i64.or $push6=, $pop4, $pop5 704; CHECK-NEXT: i64.store 8($pop30), $pop6 705; CHECK-NEXT: local.get $push33=, 0 706; CHECK-NEXT: local.get $push31=, 5 707; CHECK-NEXT: i64.load $push7=, 16($pop31) 708; CHECK-NEXT: local.get $push32=, 5 709; CHECK-NEXT: i64.load $push8=, 0($pop32) 710; CHECK-NEXT: i64.or $push9=, $pop7, $pop8 711; CHECK-NEXT: i64.store 0($pop33), $pop9 712; CHECK-NEXT: local.get $push34=, 5 713; CHECK-NEXT: i32.const $push12=, 32 714; CHECK-NEXT: i32.add $push13=, $pop34, $pop12 715; CHECK-NEXT: global.set __stack_pointer, $pop13 716; CHECK-NEXT: return 717 %a = and i128 %y, 127 718 %z = sub i128 128, %a 719 %b = lshr i128 %x, %a 720 %c = shl i128 %x, %z 721 %d = or i128 %b, %c 722 ret i128 %d 723} 724