1; RUN: llc < %s -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -wasm-enable-unimplemented-simd -mattr=+simd128 --show-mc-encoding | FileCheck %s --check-prefixes CHECK,SIMD128 2; RUN: llc < %s -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -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 -disable-wasm-explicit-locals -mattr=+simd128 --show-mc-encoding | FileCheck %s --check-prefixes CHECK,SIMD128-VM 4; RUN: llc < %s -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+simd128 -fast-isel --show-mc-encoding | FileCheck %s --check-prefixes CHECK,SIMD128-VM 5; RUN: llc < %s -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=-simd128 --show-mc-encoding | FileCheck %s --check-prefixes CHECK,NO-SIMD128 6; RUN: llc < %s -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -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: i8x16 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: i8x16 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: i8x16 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; ============================================================================== 83; 8 x i16 84; ============================================================================== 85; CHECK-LABEL: add_v8i16 86; NO-SIMD128-NOT: i16x8 87; SIMD128: .param v128, v128{{$}} 88; SIMD128: .result v128{{$}} 89; SIMD128: i16x8.add $push0=, $0, $1 # encoding: [0xfd,0x19]{{$}} 90; SIMD128: return $pop0 # 91define <8 x i16> @add_v8i16(<8 x i16> %x, <8 x i16> %y) { 92 %a = add <8 x i16> %x, %y 93 ret <8 x i16> %a 94} 95 96; CHECK-LABEL: sub_v8i16 97; NO-SIMD128-NOT: i16x8 98; SIMD128: .param v128, v128{{$}} 99; SIMD128: .result v128{{$}} 100; SIMD128: i16x8.sub $push0=, $0, $1 # encoding: [0xfd,0x1d]{{$}} 101; SIMD128: return $pop0 # 102define <8 x i16> @sub_v8i16(<8 x i16> %x, <8 x i16> %y) { 103 %a = sub <8 x i16> %x, %y 104 ret <8 x i16> %a 105} 106 107; CHECK-LABEL: mul_v8i16 108; NO-SIMD128-NOT: i16x8 109; SIMD128: .param v128, v128{{$}} 110; SIMD128: .result v128{{$}} 111; SIMD128: i16x8.mul $push0=, $0, $1 # encoding: [0xfd,0x21]{{$}} 112; SIMD128: return $pop0 # 113define <8 x i16> @mul_v8i16(<8 x i16> %x, <8 x i16> %y) { 114 %a = mul <8 x i16> %x, %y 115 ret <8 x i16> %a 116} 117 118; CHECK-LABEL: and_v8i16 119; NO-SIMD128-NOT: i16x8 120; SIMD128: .param v128, v128{{$}} 121; SIMD128: .result v128{{$}} 122; SIMD128: v128.and $push0=, $0, $1 # encoding: [0xfd,0x3b]{{$}} 123; SIMD128: return $pop0 # 124define <8 x i16> @and_v8i16(<8 x i16> %x, <8 x i16> %y) { 125 %a = and <8 x i16> %x, %y 126 ret <8 x i16> %a 127} 128 129; CHECK-LABEL: or_v8i16 130; NO-SIMD128-NOT: i16x8 131; SIMD128: .param v128, v128{{$}} 132; SIMD128: .result v128{{$}} 133; SIMD128: v128.or $push0=, $0, $1 # encoding: [0xfd,0x3c]{{$}} 134; SIMD128: return $pop0 # 135define <8 x i16> @or_v8i16(<8 x i16> %x, <8 x i16> %y) { 136 %a = or <8 x i16> %x, %y 137 ret <8 x i16> %a 138} 139 140; CHECK-LABEL: xor_v8i16 141; NO-SIMD128-NOT: i16x8 142; SIMD128: .param v128, v128{{$}} 143; SIMD128: .result v128{{$}} 144; SIMD128: v128.xor $push0=, $0, $1 # encoding: [0xfd,0x3d]{{$}} 145; SIMD128: return $pop0 # 146define <8 x i16> @xor_v8i16(<8 x i16> %x, <8 x i16> %y) { 147 %a = xor <8 x i16> %x, %y 148 ret <8 x i16> %a 149} 150 151; ============================================================================== 152; 4 x i32 153; ============================================================================== 154; CHECK-LABEL: add_v4i32 155; NO-SIMD128-NOT: i32x4 156; SIMD128: .param v128, v128{{$}} 157; SIMD128: .result v128{{$}} 158; SIMD128: i32x4.add $push0=, $0, $1 # encoding: [0xfd,0x1a]{{$}} 159; SIMD128: return $pop0 # 160define <4 x i32> @add_v4i32(<4 x i32> %x, <4 x i32> %y) { 161 %a = add <4 x i32> %x, %y 162 ret <4 x i32> %a 163} 164 165; CHECK-LABEL: sub_v4i32 166; NO-SIMD128-NOT: i32x4 167; SIMD128: .param v128, v128{{$}} 168; SIMD128: .result v128{{$}} 169; SIMD128: i32x4.sub $push0=, $0, $1 # encoding: [0xfd,0x1e]{{$}} 170; SIMD128: return $pop0 # 171define <4 x i32> @sub_v4i32(<4 x i32> %x, <4 x i32> %y) { 172 %a = sub <4 x i32> %x, %y 173 ret <4 x i32> %a 174} 175 176; CHECK-LABEL: mul_v4i32 177; NO-SIMD128-NOT: i32x4 178; SIMD128: .param v128, v128{{$}} 179; SIMD128: .result v128{{$}} 180; SIMD128: i32x4.mul $push0=, $0, $1 # encoding: [0xfd,0x22]{{$}} 181; SIMD128: return $pop0 # 182define <4 x i32> @mul_v4i32(<4 x i32> %x, <4 x i32> %y) { 183 %a = mul <4 x i32> %x, %y 184 ret <4 x i32> %a 185} 186 187; CHECK-LABEL: and_v4i32 188; NO-SIMD128-NOT: i32x4 189; SIMD128: .param v128, v128{{$}} 190; SIMD128: .result v128{{$}} 191; SIMD128: v128.and $push0=, $0, $1 # encoding: [0xfd,0x3b]{{$}} 192; SIMD128: return $pop0 # 193define <4 x i32> @and_v4i32(<4 x i32> %x, <4 x i32> %y) { 194 %a = and <4 x i32> %x, %y 195 ret <4 x i32> %a 196} 197 198; CHECK-LABEL: or_v4i32 199; NO-SIMD128-NOT: i32x4 200; SIMD128: .param v128, v128{{$}} 201; SIMD128: .result v128{{$}} 202; SIMD128: v128.or $push0=, $0, $1 # encoding: [0xfd,0x3c]{{$}} 203; SIMD128: return $pop0 # 204define <4 x i32> @or_v4i32(<4 x i32> %x, <4 x i32> %y) { 205 %a = or <4 x i32> %x, %y 206 ret <4 x i32> %a 207} 208 209; CHECK-LABEL: xor_v4i32 210; NO-SIMD128-NOT: i32x4 211; SIMD128: .param v128, v128{{$}} 212; SIMD128: .result v128{{$}} 213; SIMD128: v128.xor $push0=, $0, $1 # encoding: [0xfd,0x3d]{{$}} 214; SIMD128: return $pop0 # 215define <4 x i32> @xor_v4i32(<4 x i32> %x, <4 x i32> %y) { 216 %a = xor <4 x i32> %x, %y 217 ret <4 x i32> %a 218} 219 220; ============================================================================== 221; 2 x i64 222; ============================================================================== 223; CHECK-LABEL: add_v2i64 224; NO-SIMD128-NOT: i64x2 225; SIMD128-VM-NOT: i64x2 226; SIMD128: .param v128, v128{{$}} 227; SIMD128: .result v128{{$}} 228; SIMD128: i64x2.add $push0=, $0, $1 # encoding: [0xfd,0x1b]{{$}} 229; SIMD128: return $pop0 # 230define <2 x i64> @add_v2i64(<2 x i64> %x, <2 x i64> %y) { 231 %a = add <2 x i64> %x, %y 232 ret <2 x i64> %a 233} 234 235; CHECK-LABEL: sub_v2i64 236; NO-SIMD128-NOT: i64x2 237; SIMD128-VM-NOT: i64x2 238; SIMD128: .param v128, v128{{$}} 239; SIMD128: .result v128{{$}} 240; SIMD128: i64x2.sub $push0=, $0, $1 # encoding: [0xfd,0x1f]{{$}} 241; SIMD128: return $pop0 # 242define <2 x i64> @sub_v2i64(<2 x i64> %x, <2 x i64> %y) { 243 %a = sub <2 x i64> %x, %y 244 ret <2 x i64> %a 245} 246 247; v2i64.mul is not in spec 248; CHECK-LABEL: mul_v2i64 249; NO-SIMD128-NOT: i64x2 250; SIMD128-VM-NOT: i64x2 251; SIMD128-NOT: i64x2.mul 252; SIMD128: i64x2.extract_lane 253; SIMD128: i64.mul 254define <2 x i64> @mul_v2i64(<2 x i64> %x, <2 x i64> %y) { 255 %a = mul <2 x i64> %x, %y 256 ret <2 x i64> %a 257} 258 259; CHECK-LABEL: and_v2i64 260; NO-SIMD128-NOT: i64x2 261; SIMD128: .param v128, v128{{$}} 262; SIMD128: .result v128{{$}} 263; SIMD128: v128.and $push0=, $0, $1 # encoding: [0xfd,0x3b]{{$}} 264; SIMD128: return $pop0 # 265define <2 x i64> @and_v2i64(<2 x i64> %x, <2 x i64> %y) { 266 %a = and <2 x i64> %x, %y 267 ret <2 x i64> %a 268} 269 270; CHECK-LABEL: or_v2i64 271; NO-SIMD128-NOT: i64x2 272; SIMD128: .param v128, v128{{$}} 273; SIMD128: .result v128{{$}} 274; SIMD128: v128.or $push0=, $0, $1 # encoding: [0xfd,0x3c]{{$}} 275; SIMD128: return $pop0 # 276define <2 x i64> @or_v2i64(<2 x i64> %x, <2 x i64> %y) { 277 %a = or <2 x i64> %x, %y 278 ret <2 x i64> %a 279} 280 281; CHECK-LABEL: xor_v2i64 282; NO-SIMD128-NOT: i64x2 283; SIMD128: .param v128, v128{{$}} 284; SIMD128: .result v128{{$}} 285; SIMD128: v128.xor $push0=, $0, $1 # encoding: [0xfd,0x3d]{{$}} 286; SIMD128: return $pop0 # 287define <2 x i64> @xor_v2i64(<2 x i64> %x, <2 x i64> %y) { 288 %a = xor <2 x i64> %x, %y 289 ret <2 x i64> %a 290} 291 292; ============================================================================== 293; 4 x float 294; ============================================================================== 295; CHECK-LABEL: add_v4f32 296; NO-SIMD128-NOT: f32x4 297; SIMD128: .param v128, v128{{$}} 298; SIMD128: .result v128{{$}} 299; SIMD128: f32x4.add $push0=, $0, $1 # encoding: [0xfd,0x7a]{{$}} 300; SIMD128: return $pop0 # 301define <4 x float> @add_v4f32(<4 x float> %x, <4 x float> %y) { 302 %a = fadd <4 x float> %x, %y 303 ret <4 x float> %a 304} 305 306; CHECK-LABEL: sub_v4f32 307; NO-SIMD128-NOT: f32x4 308; SIMD128: .param v128, v128{{$}} 309; SIMD128: .result v128{{$}} 310; SIMD128: f32x4.sub $push0=, $0, $1 # encoding: [0xfd,0x7c]{{$}} 311; SIMD128: return $pop0 # 312define <4 x float> @sub_v4f32(<4 x float> %x, <4 x float> %y) { 313 %a = fsub <4 x float> %x, %y 314 ret <4 x float> %a 315} 316 317; CHECK-LABEL: div_v4f32 318; NO-SIMD128-NOT: f32x4 319; SIMD128: .param v128, v128{{$}} 320; SIMD128: .result v128{{$}} 321; SIMD128: f32x4.div $push0=, $0, $1 # encoding: [0xfd,0x7e]{{$}} 322; SIMD128: return $pop0 # 323define <4 x float> @div_v4f32(<4 x float> %x, <4 x float> %y) { 324 %a = fdiv <4 x float> %x, %y 325 ret <4 x float> %a 326} 327 328; CHECK-LABEL: mul_v4f32 329; NO-SIMD128-NOT: f32x4 330; SIMD128: .param v128, v128{{$}} 331; SIMD128: .result v128{{$}} 332; SIMD128: f32x4.mul $push0=, $0, $1 # encoding: [0xfd,0x80]{{$}} 333; SIMD128: return $pop0 # 334define <4 x float> @mul_v4f32(<4 x float> %x, <4 x float> %y) { 335 %a = fmul <4 x float> %x, %y 336 ret <4 x float> %a 337} 338 339; ============================================================================== 340; 2 x double 341; ============================================================================== 342; CHECK-LABEL: add_v2f64 343; NO-SIMD128-NOT: f64x2 344; SIMD129-VM-NOT: f62x2 345; SIMD128: .param v128, v128{{$}} 346; SIMD128: .result v128{{$}} 347; SIMD128: f64x2.add $push0=, $0, $1 # encoding: [0xfd,0x7b]{{$}} 348; SIMD128: return $pop0 # 349define <2 x double> @add_v2f64(<2 x double> %x, <2 x double> %y) { 350 %a = fadd <2 x double> %x, %y 351 ret <2 x double> %a 352} 353 354; CHECK-LABEL: sub_v2f64 355; NO-SIMD128-NOT: f64x2 356; SIMD129-VM-NOT: f62x2 357; SIMD128: .param v128, v128{{$}} 358; SIMD128: .result v128{{$}} 359; SIMD128: f64x2.sub $push0=, $0, $1 # encoding: [0xfd,0x7d]{{$}} 360; SIMD128: return $pop0 # 361define <2 x double> @sub_v2f64(<2 x double> %x, <2 x double> %y) { 362 %a = fsub <2 x double> %x, %y 363 ret <2 x double> %a 364} 365 366; CHECK-LABEL: div_v2f64 367; NO-SIMD128-NOT: f64x2 368; SIMD129-VM-NOT: f62x2 369; SIMD128: .param v128, v128{{$}} 370; SIMD128: .result v128{{$}} 371; SIMD128: f64x2.div $push0=, $0, $1 # encoding: [0xfd,0x7f]{{$}} 372; SIMD128: return $pop0 # 373define <2 x double> @div_v2f64(<2 x double> %x, <2 x double> %y) { 374 %a = fdiv <2 x double> %x, %y 375 ret <2 x double> %a 376} 377 378; CHECK-LABEL: mul_v2f64 379; NO-SIMD128-NOT: f64x2 380; SIMD129-VM-NOT: f62x2 381; SIMD128: .param v128, v128{{$}} 382; SIMD128: .result v128{{$}} 383; SIMD128: f64x2.mul $push0=, $0, $1 # encoding: [0xfd,0x81]{{$}} 384; SIMD128: return $pop0 # 385define <2 x double> @mul_v2f64(<2 x double> %x, <2 x double> %y) { 386 %a = fmul <2 x double> %x, %y 387 ret <2 x double> %a 388} 389