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