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