1; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s 2 3; Test that basic 64-bit integer operations assemble as expected. 4 5target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 6target triple = "wasm32-unknown-unknown" 7 8declare i64 @llvm.ctlz.i64(i64, i1) 9declare i64 @llvm.cttz.i64(i64, i1) 10declare i64 @llvm.ctpop.i64(i64) 11 12; CHECK-LABEL: add64: 13; CHECK-NEXT: .param i64, i64{{$}} 14; CHECK-NEXT: .result i64{{$}} 15; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 16; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 17; CHECK-NEXT: i64.add $push0=, $pop[[L0]], $pop[[L1]]{{$}} 18; CHECK-NEXT: return $pop0{{$}} 19define i64 @add64(i64 %x, i64 %y) { 20 %a = add i64 %x, %y 21 ret i64 %a 22} 23 24; CHECK-LABEL: sub64: 25; CHECK-NEXT: .param i64, i64{{$}} 26; CHECK-NEXT: .result i64{{$}} 27; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 28; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 29; CHECK-NEXT: i64.sub $push0=, $pop[[L0]], $pop[[L1]]{{$}} 30; CHECK-NEXT: return $pop0{{$}} 31define i64 @sub64(i64 %x, i64 %y) { 32 %a = sub i64 %x, %y 33 ret i64 %a 34} 35 36; CHECK-LABEL: mul64: 37; CHECK-NEXT: .param i64, i64{{$}} 38; CHECK-NEXT: .result i64{{$}} 39; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 40; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 41; CHECK-NEXT: i64.mul $push0=, $pop[[L0]], $pop[[L1]]{{$}} 42; CHECK-NEXT: return $pop0{{$}} 43define i64 @mul64(i64 %x, i64 %y) { 44 %a = mul i64 %x, %y 45 ret i64 %a 46} 47 48; CHECK-LABEL: sdiv64: 49; CHECK-NEXT: .param i64, i64{{$}} 50; CHECK-NEXT: .result i64{{$}} 51; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 52; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 53; CHECK-NEXT: i64.div_s $push0=, $pop[[L0]], $pop[[L1]]{{$}} 54; CHECK-NEXT: return $pop0{{$}} 55define i64 @sdiv64(i64 %x, i64 %y) { 56 %a = sdiv i64 %x, %y 57 ret i64 %a 58} 59 60; CHECK-LABEL: udiv64: 61; CHECK-NEXT: .param i64, i64{{$}} 62; CHECK-NEXT: .result i64{{$}} 63; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 64; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 65; CHECK-NEXT: i64.div_u $push0=, $pop[[L0]], $pop[[L1]]{{$}} 66; CHECK-NEXT: return $pop0{{$}} 67define i64 @udiv64(i64 %x, i64 %y) { 68 %a = udiv i64 %x, %y 69 ret i64 %a 70} 71 72; CHECK-LABEL: srem64: 73; CHECK-NEXT: .param i64, i64{{$}} 74; CHECK-NEXT: .result i64{{$}} 75; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 76; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 77; CHECK-NEXT: i64.rem_s $push0=, $pop[[L0]], $pop[[L1]]{{$}} 78; CHECK-NEXT: return $pop0{{$}} 79define i64 @srem64(i64 %x, i64 %y) { 80 %a = srem i64 %x, %y 81 ret i64 %a 82} 83 84; CHECK-LABEL: urem64: 85; CHECK-NEXT: .param i64, i64{{$}} 86; CHECK-NEXT: .result i64{{$}} 87; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 88; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 89; CHECK-NEXT: i64.rem_u $push0=, $pop[[L0]], $pop[[L1]]{{$}} 90; CHECK-NEXT: return $pop0{{$}} 91define i64 @urem64(i64 %x, i64 %y) { 92 %a = urem i64 %x, %y 93 ret i64 %a 94} 95 96; CHECK-LABEL: and64: 97; CHECK-NEXT: .param i64, i64{{$}} 98; CHECK-NEXT: .result i64{{$}} 99; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 100; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 101; CHECK-NEXT: i64.and $push0=, $pop[[L0]], $pop[[L1]]{{$}} 102; CHECK-NEXT: return $pop0{{$}} 103define i64 @and64(i64 %x, i64 %y) { 104 %a = and i64 %x, %y 105 ret i64 %a 106} 107 108; CHECK-LABEL: or64: 109; CHECK-NEXT: .param i64, i64{{$}} 110; CHECK-NEXT: .result i64{{$}} 111; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 112; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 113; CHECK-NEXT: i64.or $push0=, $pop[[L0]], $pop[[L1]]{{$}} 114; CHECK-NEXT: return $pop0{{$}} 115define i64 @or64(i64 %x, i64 %y) { 116 %a = or i64 %x, %y 117 ret i64 %a 118} 119 120; CHECK-LABEL: xor64: 121; CHECK-NEXT: .param i64, i64{{$}} 122; CHECK-NEXT: .result i64{{$}} 123; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 124; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 125; CHECK-NEXT: i64.xor $push0=, $pop[[L0]], $pop[[L1]]{{$}} 126; CHECK-NEXT: return $pop0{{$}} 127define i64 @xor64(i64 %x, i64 %y) { 128 %a = xor i64 %x, %y 129 ret i64 %a 130} 131 132; CHECK-LABEL: shl64: 133; CHECK-NEXT: .param i64, i64{{$}} 134; CHECK-NEXT: .result i64{{$}} 135; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 136; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 137; CHECK-NEXT: i64.shl $push0=, $pop[[L0]], $pop[[L1]]{{$}} 138; CHECK-NEXT: return $pop0{{$}} 139define i64 @shl64(i64 %x, i64 %y) { 140 %a = shl i64 %x, %y 141 ret i64 %a 142} 143 144; CHECK-LABEL: shr64: 145; CHECK-NEXT: .param i64, i64{{$}} 146; CHECK-NEXT: .result i64{{$}} 147; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 148; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 149; CHECK-NEXT: i64.shr_u $push0=, $pop[[L0]], $pop[[L1]]{{$}} 150; CHECK-NEXT: return $pop0{{$}} 151define i64 @shr64(i64 %x, i64 %y) { 152 %a = lshr i64 %x, %y 153 ret i64 %a 154} 155 156; CHECK-LABEL: sar64: 157; CHECK-NEXT: .param i64, i64{{$}} 158; CHECK-NEXT: .result i64{{$}} 159; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 160; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 161; CHECK-NEXT: i64.shr_s $push0=, $pop[[L0]], $pop[[L1]]{{$}} 162; CHECK-NEXT: return $pop0{{$}} 163define i64 @sar64(i64 %x, i64 %y) { 164 %a = ashr i64 %x, %y 165 ret i64 %a 166} 167 168; CHECK-LABEL: clz64: 169; CHECK-NEXT: .param i64{{$}} 170; CHECK-NEXT: .result i64{{$}} 171; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 172; CHECK-NEXT: i64.clz $push0=, $pop[[L0]]{{$}} 173; CHECK-NEXT: return $pop0{{$}} 174define i64 @clz64(i64 %x) { 175 %a = call i64 @llvm.ctlz.i64(i64 %x, i1 false) 176 ret i64 %a 177} 178 179; CHECK-LABEL: clz64_zero_undef: 180; CHECK-NEXT: .param i64{{$}} 181; CHECK-NEXT: .result i64{{$}} 182; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 183; CHECK-NEXT: i64.clz $push0=, $pop[[L0]]{{$}} 184; CHECK-NEXT: return $pop0{{$}} 185define i64 @clz64_zero_undef(i64 %x) { 186 %a = call i64 @llvm.ctlz.i64(i64 %x, i1 true) 187 ret i64 %a 188} 189 190; CHECK-LABEL: ctz64: 191; CHECK-NEXT: .param i64{{$}} 192; CHECK-NEXT: .result i64{{$}} 193; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 194; CHECK-NEXT: i64.ctz $push0=, $pop[[L0]]{{$}} 195; CHECK-NEXT: return $pop0{{$}} 196define i64 @ctz64(i64 %x) { 197 %a = call i64 @llvm.cttz.i64(i64 %x, i1 false) 198 ret i64 %a 199} 200 201; CHECK-LABEL: ctz64_zero_undef: 202; CHECK-NEXT: .param i64{{$}} 203; CHECK-NEXT: .result i64{{$}} 204; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 205; CHECK-NEXT: i64.ctz $push0=, $pop[[L0]]{{$}} 206; CHECK-NEXT: return $pop0{{$}} 207define i64 @ctz64_zero_undef(i64 %x) { 208 %a = call i64 @llvm.cttz.i64(i64 %x, i1 true) 209 ret i64 %a 210} 211 212; CHECK-LABEL: popcnt64: 213; CHECK-NEXT: .param i64{{$}} 214; CHECK-NEXT: .result i64{{$}} 215; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 216; CHECK-NEXT: i64.popcnt $push0=, $pop[[L0]]{{$}} 217; CHECK-NEXT: return $pop0{{$}} 218define i64 @popcnt64(i64 %x) { 219 %a = call i64 @llvm.ctpop.i64(i64 %x) 220 ret i64 %a 221} 222 223; CHECK-LABEL: eqz64: 224; CHECK-NEXT: .param i64{{$}} 225; CHECK-NEXT: .result i32{{$}} 226; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 227; CHECK-NEXT: i64.eqz $push0=, $pop[[L0]]{{$}} 228; CHECK-NEXT: return $pop0{{$}} 229define i32 @eqz64(i64 %x) { 230 %a = icmp eq i64 %x, 0 231 %b = zext i1 %a to i32 232 ret i32 %b 233} 234 235; CHECK-LABEL: rotl: 236; CHECK-NEXT: .param i64, i64{{$}} 237; CHECK-NEXT: .result i64{{$}} 238; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 239; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 240; CHECK-NEXT: i64.rotl $push0=, $pop[[L0]], $pop[[L1]] 241; CHECK-NEXT: return $pop0{{$}} 242define i64 @rotl(i64 %x, i64 %y) { 243 %z = sub i64 64, %y 244 %b = shl i64 %x, %y 245 %c = lshr i64 %x, %z 246 %d = or i64 %b, %c 247 ret i64 %d 248} 249 250; CHECK-LABEL: masked_rotl: 251; CHECK-NEXT: .param i64, i64{{$}} 252; CHECK-NEXT: .result i64{{$}} 253; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 254; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 255; CHECK-NEXT: i64.rotl $push0=, $pop[[L0]], $pop[[L1]] 256; CHECK-NEXT: return $pop0{{$}} 257define i64 @masked_rotl(i64 %x, i64 %y) { 258 %a = and i64 %y, 63 259 %z = sub i64 64, %a 260 %b = shl i64 %x, %a 261 %c = lshr i64 %x, %z 262 %d = or i64 %b, %c 263 ret i64 %d 264} 265 266; CHECK-LABEL: rotr: 267; CHECK-NEXT: .param i64, i64{{$}} 268; CHECK-NEXT: .result i64{{$}} 269; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 270; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 271; CHECK-NEXT: i64.rotr $push0=, $pop[[L0]], $pop[[L1]] 272; CHECK-NEXT: return $pop0{{$}} 273define i64 @rotr(i64 %x, i64 %y) { 274 %z = sub i64 64, %y 275 %b = lshr i64 %x, %y 276 %c = shl i64 %x, %z 277 %d = or i64 %b, %c 278 ret i64 %d 279} 280 281; CHECK-LABEL: masked_rotr: 282; CHECK-NEXT: .param i64, i64{{$}} 283; CHECK-NEXT: .result i64{{$}} 284; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 285; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 286; CHECK-NEXT: i64.rotr $push0=, $pop[[L0]], $pop[[L1]] 287; CHECK-NEXT: return $pop0{{$}} 288define i64 @masked_rotr(i64 %x, i64 %y) { 289 %a = and i64 %y, 63 290 %z = sub i64 64, %a 291 %b = lshr i64 %x, %a 292 %c = shl i64 %x, %z 293 %d = or i64 %b, %c 294 ret i64 %d 295} 296