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 5 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 6 target triple = "wasm32-unknown-unknown" 7 8 declare i32 @llvm.ctlz.i32(i32, i1) 9 declare i32 @llvm.cttz.i32(i32, i1) 10 declare 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{{$}} 17 define 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{{$}} 27 define 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{{$}} 37 define 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{{$}} 47 define 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{{$}} 57 define 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{{$}} 67 define 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{{$}} 77 define 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{{$}} 87 define 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{{$}} 97 define 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{{$}} 107 define 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{{$}} 117 define 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{{$}} 127 define 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{{$}} 137 define 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{{$}} 147 define 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{{$}} 157 define 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{{$}} 167 define 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{{$}} 177 define 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{{$}} 187 define 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{{$}} 197 define 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{{$}} 208 define 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{{$}} 221 define 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{{$}} 235 define 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{{$}} 248 define 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