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