1; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -wasm-enable-unimplemented-simd -mattr=+simd128 --show-mc-encoding | FileCheck %s --check-prefixes CHECK,SIMD128 2; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -wasm-enable-unimplemented-simd -mattr=+simd128 -fast-isel --show-mc-encoding | FileCheck %s --check-prefixes CHECK,SIMD128 3; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 --show-mc-encoding | FileCheck %s --check-prefixes CHECK,SIMD128-VM 4; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 -fast-isel --show-mc-encoding | FileCheck %s --check-prefixes CHECK,SIMD128-VM 5; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=-simd128 --show-mc-encoding | FileCheck %s --check-prefixes CHECK,NO-SIMD128 6; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=-simd128 -fast-isel --show-mc-encoding | FileCheck %s --check-prefixes CHECK,NO-SIMD128 7 8; Test that basic SIMD128 arithmetic operations assemble as expected. 9 10target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 11target triple = "wasm32-unknown-unknown" 12 13; ============================================================================== 14; 16 x i8 15; ============================================================================== 16; CHECK-LABEL: add_v16i8 17; NO-SIMD128-NOT: i8x16 18; SIMD128: .param v128, v128{{$}} 19; SIMD128: .result v128{{$}} 20; SIMD128: i8x16.add $push0=, $0, $1 # encoding: [0xfd,0x18]{{$}} 21; SIMD128: return $pop0 # 22define <16 x i8> @add_v16i8(<16 x i8> %x, <16 x i8> %y) { 23 %a = add <16 x i8> %x, %y 24 ret <16 x i8> %a 25} 26 27; CHECK-LABEL: sub_v16i8 28; NO-SIMD128-NOT: i8x16 29; SIMD128: .param v128, v128{{$}} 30; SIMD128: .result v128{{$}} 31; SIMD128: i8x16.sub $push0=, $0, $1 # encoding: [0xfd,0x1c]{{$}} 32; SIMD128: return $pop0 # 33define <16 x i8> @sub_v16i8(<16 x i8> %x, <16 x i8> %y) { 34 %a = sub <16 x i8> %x, %y 35 ret <16 x i8> %a 36} 37 38; CHECK-LABEL: mul_v16i8 39; NO-SIMD128-NOT: i8x16 40; SIMD128: .param v128, v128{{$}} 41; SIMD128: .result v128{{$}} 42; SIMD128: i8x16.mul $push0=, $0, $1 # encoding: [0xfd,0x20]{{$}} 43; SIMD128: return $pop0 # 44define <16 x i8> @mul_v16i8(<16 x i8> %x, <16 x i8> %y) { 45 %a = mul <16 x i8> %x, %y 46 ret <16 x i8> %a 47} 48 49; CHECK-LABEL: and_v16i8 50; NO-SIMD128-NOT: v128 51; SIMD128: .param v128, v128{{$}} 52; SIMD128: .result v128{{$}} 53; SIMD128: v128.and $push0=, $0, $1 # encoding: [0xfd,0x3b]{{$}} 54; SIMD128: return $pop0 # 55define <16 x i8> @and_v16i8(<16 x i8> %x, <16 x i8> %y) { 56 %a = and <16 x i8> %x, %y 57 ret <16 x i8> %a 58} 59 60; CHECK-LABEL: or_v16i8 61; NO-SIMD128-NOT: v128 62; SIMD128: .param v128, v128{{$}} 63; SIMD128: .result v128{{$}} 64; SIMD128: v128.or $push0=, $0, $1 # encoding: [0xfd,0x3c]{{$}} 65; SIMD128: return $pop0 # 66define <16 x i8> @or_v16i8(<16 x i8> %x, <16 x i8> %y) { 67 %a = or <16 x i8> %x, %y 68 ret <16 x i8> %a 69} 70 71; CHECK-LABEL: xor_v16i8 72; NO-SIMD128-NOT: v128 73; SIMD128: .param v128, v128{{$}} 74; SIMD128: .result v128{{$}} 75; SIMD128: v128.xor $push0=, $0, $1 # encoding: [0xfd,0x3d]{{$}} 76; SIMD128: return $pop0 # 77define <16 x i8> @xor_v16i8(<16 x i8> %x, <16 x i8> %y) { 78 %a = xor <16 x i8> %x, %y 79 ret <16 x i8> %a 80} 81 82; CHECK-LABEL: not_v16i8 83; NO-SIMD128-NOT: v128 84; SIMD128: .param v128{{$}} 85; SIMD128: .result v128{{$}} 86; SIMD128: v128.not $push0=, $0 # encoding: [0xfd,0x3e]{{$}} 87; SIMD128: return $pop0 # 88define <16 x i8> @not_v16i8(<16 x i8> %x) { 89 %a = xor <16 x i8> %x, <i8 -1, i8 -1, i8 -1, i8 -1, 90 i8 -1, i8 -1, i8 -1, i8 -1, 91 i8 -1, i8 -1, i8 -1, i8 -1, 92 i8 -1, i8 -1, i8 -1, i8 -1> 93 ret <16 x i8> %a 94} 95 96; ============================================================================== 97; 8 x i16 98; ============================================================================== 99; CHECK-LABEL: add_v8i16 100; NO-SIMD128-NOT: i16x8 101; SIMD128: .param v128, v128{{$}} 102; SIMD128: .result v128{{$}} 103; SIMD128: i16x8.add $push0=, $0, $1 # encoding: [0xfd,0x19]{{$}} 104; SIMD128: return $pop0 # 105define <8 x i16> @add_v8i16(<8 x i16> %x, <8 x i16> %y) { 106 %a = add <8 x i16> %x, %y 107 ret <8 x i16> %a 108} 109 110; CHECK-LABEL: sub_v8i16 111; NO-SIMD128-NOT: i16x8 112; SIMD128: .param v128, v128{{$}} 113; SIMD128: .result v128{{$}} 114; SIMD128: i16x8.sub $push0=, $0, $1 # encoding: [0xfd,0x1d]{{$}} 115; SIMD128: return $pop0 # 116define <8 x i16> @sub_v8i16(<8 x i16> %x, <8 x i16> %y) { 117 %a = sub <8 x i16> %x, %y 118 ret <8 x i16> %a 119} 120 121; CHECK-LABEL: mul_v8i16 122; NO-SIMD128-NOT: i16x8 123; SIMD128: .param v128, v128{{$}} 124; SIMD128: .result v128{{$}} 125; SIMD128: i16x8.mul $push0=, $0, $1 # encoding: [0xfd,0x21]{{$}} 126; SIMD128: return $pop0 # 127define <8 x i16> @mul_v8i16(<8 x i16> %x, <8 x i16> %y) { 128 %a = mul <8 x i16> %x, %y 129 ret <8 x i16> %a 130} 131 132; CHECK-LABEL: and_v8i16 133; NO-SIMD128-NOT: v128 134; SIMD128: .param v128, v128{{$}} 135; SIMD128: .result v128{{$}} 136; SIMD128: v128.and $push0=, $0, $1 # encoding: [0xfd,0x3b]{{$}} 137; SIMD128: return $pop0 # 138define <8 x i16> @and_v8i16(<8 x i16> %x, <8 x i16> %y) { 139 %a = and <8 x i16> %x, %y 140 ret <8 x i16> %a 141} 142 143; CHECK-LABEL: or_v8i16 144; NO-SIMD128-NOT: v128 145; SIMD128: .param v128, v128{{$}} 146; SIMD128: .result v128{{$}} 147; SIMD128: v128.or $push0=, $0, $1 # encoding: [0xfd,0x3c]{{$}} 148; SIMD128: return $pop0 # 149define <8 x i16> @or_v8i16(<8 x i16> %x, <8 x i16> %y) { 150 %a = or <8 x i16> %x, %y 151 ret <8 x i16> %a 152} 153 154; CHECK-LABEL: xor_v8i16 155; NO-SIMD128-NOT: v128 156; SIMD128: .param v128, v128{{$}} 157; SIMD128: .result v128{{$}} 158; SIMD128: v128.xor $push0=, $0, $1 # encoding: [0xfd,0x3d]{{$}} 159; SIMD128: return $pop0 # 160define <8 x i16> @xor_v8i16(<8 x i16> %x, <8 x i16> %y) { 161 %a = xor <8 x i16> %x, %y 162 ret <8 x i16> %a 163} 164 165; CHECK-LABEL: not_v8i16 166; NO-SIMD128-NOT: v128 167; SIMD128: .param v128{{$}} 168; SIMD128: .result v128{{$}} 169; SIMD128: v128.not $push0=, $0 # encoding: [0xfd,0x3e]{{$}} 170; SIMD128: return $pop0 # 171define <8 x i16> @not_v8i16(<8 x i16> %x) { 172 %a = xor <8 x i16> %x, <i16 -1, i16 -1, i16 -1, i16 -1, 173 i16 -1, i16 -1, i16 -1, i16 -1> 174 ret <8 x i16> %a 175} 176 177; ============================================================================== 178; 4 x i32 179; ============================================================================== 180; CHECK-LABEL: add_v4i32 181; NO-SIMD128-NOT: i32x4 182; SIMD128: .param v128, v128{{$}} 183; SIMD128: .result v128{{$}} 184; SIMD128: i32x4.add $push0=, $0, $1 # encoding: [0xfd,0x1a]{{$}} 185; SIMD128: return $pop0 # 186define <4 x i32> @add_v4i32(<4 x i32> %x, <4 x i32> %y) { 187 %a = add <4 x i32> %x, %y 188 ret <4 x i32> %a 189} 190 191; CHECK-LABEL: sub_v4i32 192; NO-SIMD128-NOT: i32x4 193; SIMD128: .param v128, v128{{$}} 194; SIMD128: .result v128{{$}} 195; SIMD128: i32x4.sub $push0=, $0, $1 # encoding: [0xfd,0x1e]{{$}} 196; SIMD128: return $pop0 # 197define <4 x i32> @sub_v4i32(<4 x i32> %x, <4 x i32> %y) { 198 %a = sub <4 x i32> %x, %y 199 ret <4 x i32> %a 200} 201 202; CHECK-LABEL: mul_v4i32 203; NO-SIMD128-NOT: i32x4 204; SIMD128: .param v128, v128{{$}} 205; SIMD128: .result v128{{$}} 206; SIMD128: i32x4.mul $push0=, $0, $1 # encoding: [0xfd,0x22]{{$}} 207; SIMD128: return $pop0 # 208define <4 x i32> @mul_v4i32(<4 x i32> %x, <4 x i32> %y) { 209 %a = mul <4 x i32> %x, %y 210 ret <4 x i32> %a 211} 212 213; CHECK-LABEL: and_v4i32 214; NO-SIMD128-NOT: v128 215; SIMD128: .param v128, v128{{$}} 216; SIMD128: .result v128{{$}} 217; SIMD128: v128.and $push0=, $0, $1 # encoding: [0xfd,0x3b]{{$}} 218; SIMD128: return $pop0 # 219define <4 x i32> @and_v4i32(<4 x i32> %x, <4 x i32> %y) { 220 %a = and <4 x i32> %x, %y 221 ret <4 x i32> %a 222} 223 224; CHECK-LABEL: or_v4i32 225; NO-SIMD128-NOT: v128 226; SIMD128: .param v128, v128{{$}} 227; SIMD128: .result v128{{$}} 228; SIMD128: v128.or $push0=, $0, $1 # encoding: [0xfd,0x3c]{{$}} 229; SIMD128: return $pop0 # 230define <4 x i32> @or_v4i32(<4 x i32> %x, <4 x i32> %y) { 231 %a = or <4 x i32> %x, %y 232 ret <4 x i32> %a 233} 234 235; CHECK-LABEL: xor_v4i32 236; NO-SIMD128-NOT: v128 237; SIMD128: .param v128, v128{{$}} 238; SIMD128: .result v128{{$}} 239; SIMD128: v128.xor $push0=, $0, $1 # encoding: [0xfd,0x3d]{{$}} 240; SIMD128: return $pop0 # 241define <4 x i32> @xor_v4i32(<4 x i32> %x, <4 x i32> %y) { 242 %a = xor <4 x i32> %x, %y 243 ret <4 x i32> %a 244} 245 246; CHECK-LABEL: not_v4i32 247; NO-SIMD128-NOT: v128 248; SIMD128: .param v128{{$}} 249; SIMD128: .result v128{{$}} 250; SIMD128: v128.not $push0=, $0 # encoding: [0xfd,0x3e]{{$}} 251; SIMD128: return $pop0 # 252define <4 x i32> @not_v4i32(<4 x i32> %x) { 253 %a = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 254 ret <4 x i32> %a 255} 256 257; ============================================================================== 258; 2 x i64 259; ============================================================================== 260; CHECK-LABEL: add_v2i64 261; NO-SIMD128-NOT: i64x2 262; SIMD128-VM-NOT: i64x2 263; SIMD128: .param v128, v128{{$}} 264; SIMD128: .result v128{{$}} 265; SIMD128: i64x2.add $push0=, $0, $1 # encoding: [0xfd,0x1b]{{$}} 266; SIMD128: return $pop0 # 267define <2 x i64> @add_v2i64(<2 x i64> %x, <2 x i64> %y) { 268 %a = add <2 x i64> %x, %y 269 ret <2 x i64> %a 270} 271 272; CHECK-LABEL: sub_v2i64 273; NO-SIMD128-NOT: i64x2 274; SIMD128-VM-NOT: i64x2 275; SIMD128: .param v128, v128{{$}} 276; SIMD128: .result v128{{$}} 277; SIMD128: i64x2.sub $push0=, $0, $1 # encoding: [0xfd,0x1f]{{$}} 278; SIMD128: return $pop0 # 279define <2 x i64> @sub_v2i64(<2 x i64> %x, <2 x i64> %y) { 280 %a = sub <2 x i64> %x, %y 281 ret <2 x i64> %a 282} 283 284; v2i64.mul is not in spec 285; CHECK-LABEL: mul_v2i64 286; NO-SIMD128-NOT: i64x2 287; SIMD128-VM-NOT: i64x2 288; SIMD128-NOT: i64x2.mul 289; SIMD128: i64x2.extract_lane 290; SIMD128: i64.mul 291define <2 x i64> @mul_v2i64(<2 x i64> %x, <2 x i64> %y) { 292 %a = mul <2 x i64> %x, %y 293 ret <2 x i64> %a 294} 295 296; CHECK-LABEL: and_v2i64 297; NO-SIMD128-NOT: v128 298; SIMD128-VM-NOT: v128 299; SIMD128: .param v128, v128{{$}} 300; SIMD128: .result v128{{$}} 301; SIMD128: v128.and $push0=, $0, $1 # encoding: [0xfd,0x3b]{{$}} 302; SIMD128: return $pop0 # 303define <2 x i64> @and_v2i64(<2 x i64> %x, <2 x i64> %y) { 304 %a = and <2 x i64> %x, %y 305 ret <2 x i64> %a 306} 307 308; CHECK-LABEL: or_v2i64 309; NO-SIMD128-NOT: v128 310; SIMD128-VM-NOT: v128 311; SIMD128: .param v128, v128{{$}} 312; SIMD128: .result v128{{$}} 313; SIMD128: v128.or $push0=, $0, $1 # encoding: [0xfd,0x3c]{{$}} 314; SIMD128: return $pop0 # 315define <2 x i64> @or_v2i64(<2 x i64> %x, <2 x i64> %y) { 316 %a = or <2 x i64> %x, %y 317 ret <2 x i64> %a 318} 319 320; CHECK-LABEL: xor_v2i64 321; NO-SIMD128-NOT: v128 322; SIMD128-VM-NOT: v128 323; SIMD128: .param v128, v128{{$}} 324; SIMD128: .result v128{{$}} 325; SIMD128: v128.xor $push0=, $0, $1 # encoding: [0xfd,0x3d]{{$}} 326; SIMD128: return $pop0 # 327define <2 x i64> @xor_v2i64(<2 x i64> %x, <2 x i64> %y) { 328 %a = xor <2 x i64> %x, %y 329 ret <2 x i64> %a 330} 331 332; CHECK-LABEL: not_v2i64 333; NO-SIMD128-NOT: v128 334; SIMD128-VM-NOT: v128 335; SIMD128: .param v128{{$}} 336; SIMD128: .result v128{{$}} 337; SIMD128: v128.not $push0=, $0 # encoding: [0xfd,0x3e]{{$}} 338; SIMD128: return $pop0 # 339define <2 x i64> @not_v2i64(<2 x i64> %x) { 340 %a = xor <2 x i64> %x, <i64 -1, i64 -1> 341 ret <2 x i64> %a 342} 343 344; ============================================================================== 345; 4 x float 346; ============================================================================== 347; CHECK-LABEL: add_v4f32 348; NO-SIMD128-NOT: f32x4 349; SIMD128: .param v128, v128{{$}} 350; SIMD128: .result v128{{$}} 351; SIMD128: f32x4.add $push0=, $0, $1 # encoding: [0xfd,0x7a]{{$}} 352; SIMD128: return $pop0 # 353define <4 x float> @add_v4f32(<4 x float> %x, <4 x float> %y) { 354 %a = fadd <4 x float> %x, %y 355 ret <4 x float> %a 356} 357 358; CHECK-LABEL: sub_v4f32 359; NO-SIMD128-NOT: f32x4 360; SIMD128: .param v128, v128{{$}} 361; SIMD128: .result v128{{$}} 362; SIMD128: f32x4.sub $push0=, $0, $1 # encoding: [0xfd,0x7c]{{$}} 363; SIMD128: return $pop0 # 364define <4 x float> @sub_v4f32(<4 x float> %x, <4 x float> %y) { 365 %a = fsub <4 x float> %x, %y 366 ret <4 x float> %a 367} 368 369; CHECK-LABEL: div_v4f32 370; NO-SIMD128-NOT: f32x4 371; SIMD128: .param v128, v128{{$}} 372; SIMD128: .result v128{{$}} 373; SIMD128: f32x4.div $push0=, $0, $1 # encoding: [0xfd,0x7e]{{$}} 374; SIMD128: return $pop0 # 375define <4 x float> @div_v4f32(<4 x float> %x, <4 x float> %y) { 376 %a = fdiv <4 x float> %x, %y 377 ret <4 x float> %a 378} 379 380; CHECK-LABEL: mul_v4f32 381; NO-SIMD128-NOT: f32x4 382; SIMD128: .param v128, v128{{$}} 383; SIMD128: .result v128{{$}} 384; SIMD128: f32x4.mul $push0=, $0, $1 # encoding: [0xfd,0x80]{{$}} 385; SIMD128: return $pop0 # 386define <4 x float> @mul_v4f32(<4 x float> %x, <4 x float> %y) { 387 %a = fmul <4 x float> %x, %y 388 ret <4 x float> %a 389} 390 391; ============================================================================== 392; 2 x double 393; ============================================================================== 394; CHECK-LABEL: add_v2f64 395; NO-SIMD128-NOT: f64x2 396; SIMD129-VM-NOT: f62x2 397; SIMD128: .param v128, v128{{$}} 398; SIMD128: .result v128{{$}} 399; SIMD128: f64x2.add $push0=, $0, $1 # encoding: [0xfd,0x7b]{{$}} 400; SIMD128: return $pop0 # 401define <2 x double> @add_v2f64(<2 x double> %x, <2 x double> %y) { 402 %a = fadd <2 x double> %x, %y 403 ret <2 x double> %a 404} 405 406; CHECK-LABEL: sub_v2f64 407; NO-SIMD128-NOT: f64x2 408; SIMD129-VM-NOT: f62x2 409; SIMD128: .param v128, v128{{$}} 410; SIMD128: .result v128{{$}} 411; SIMD128: f64x2.sub $push0=, $0, $1 # encoding: [0xfd,0x7d]{{$}} 412; SIMD128: return $pop0 # 413define <2 x double> @sub_v2f64(<2 x double> %x, <2 x double> %y) { 414 %a = fsub <2 x double> %x, %y 415 ret <2 x double> %a 416} 417 418; CHECK-LABEL: div_v2f64 419; NO-SIMD128-NOT: f64x2 420; SIMD129-VM-NOT: f62x2 421; SIMD128: .param v128, v128{{$}} 422; SIMD128: .result v128{{$}} 423; SIMD128: f64x2.div $push0=, $0, $1 # encoding: [0xfd,0x7f]{{$}} 424; SIMD128: return $pop0 # 425define <2 x double> @div_v2f64(<2 x double> %x, <2 x double> %y) { 426 %a = fdiv <2 x double> %x, %y 427 ret <2 x double> %a 428} 429 430; CHECK-LABEL: mul_v2f64 431; NO-SIMD128-NOT: f64x2 432; SIMD129-VM-NOT: f62x2 433; SIMD128: .param v128, v128{{$}} 434; SIMD128: .result v128{{$}} 435; SIMD128: f64x2.mul $push0=, $0, $1 # encoding: [0xfd,0x81]{{$}} 436; SIMD128: return $pop0 # 437define <2 x double> @mul_v2f64(<2 x double> %x, <2 x double> %y) { 438 %a = fmul <2 x double> %x, %y 439 ret <2 x double> %a 440} 441