1; RUN: llc < %s -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -wasm-enable-unimplemented-simd -mattr=+simd128,+sign-ext --show-mc-encoding | FileCheck %s --check-prefixes CHECK,SIMD128 2; RUN: llc < %s -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+simd128,+sign-ext --show-mc-encoding | FileCheck %s --check-prefixes CHECK,SIMD128-VM 3; RUN: llc < %s -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=-simd128,+sign-ext --show-mc-encoding | FileCheck %s --check-prefixes CHECK,NO-SIMD128 4 5; Test that basic SIMD128 vector manipulation operations assemble as expected. 6 7target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 8target triple = "wasm32-unknown-unknown" 9 10; ============================================================================== 11; 16 x i8 12; ============================================================================== 13; CHECK-LABEL: const_v16i8: 14; NO-SIMD128-NOT: i8x16 15; SIMD128: .result v128{{$}} 16; SIMD128: v128.const $push0=, 17; SIMD128-SAME: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 18; SIMD128-SAME: # encoding: [0xfd,0x00, 19; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 20; SIMD128-SAME: 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f]{{$}} 21define <16 x i8> @const_v16i8() { 22 ret <16 x i8> <i8 00, i8 01, i8 02, i8 03, i8 04, i8 05, i8 06, i8 07, 23 i8 08, i8 09, i8 10, i8 11, i8 12, i8 13, i8 14, i8 15> 24} 25 26; CHECK-LABEL: splat_v16i8: 27; NO-SIMD128-NOT: i8x16 28; SIMD128: .param i32{{$}} 29; SIMD128: .result v128{{$}} 30; SIMD128: i8x16.splat $push0=, $0 # encoding: [0xfd,0x03]{{$}} 31; SIMD128: return $pop0 # encoding: [0x0f]{{$}} 32define <16 x i8> @splat_v16i8(i8 %x) { 33 %v = insertelement <16 x i8> undef, i8 %x, i32 0 34 %res = shufflevector <16 x i8> %v, <16 x i8> undef, 35 <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, 36 i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 37 ret <16 x i8> %res 38} 39 40; CHECK-LABEL: extract_v16i8_s: 41; NO-SIMD128-NOT: i8x16 42; SIMD128: .param v128{{$}} 43; SIMD128: .result i32{{$}} 44; SIMD128: i8x16.extract_lane_s $push0=, $0, 13 # encoding: [0xfd,0x09,0x0d]{{$}} 45; SIMD128: return $pop0 # 46define i32 @extract_v16i8_s(<16 x i8> %v) { 47 %elem = extractelement <16 x i8> %v, i8 13 48 %a = sext i8 %elem to i32 49 ret i32 %a 50} 51 52; CHECK-LABEL: extract_v16i8_u: 53; NO-SIMD128-NOT: i8x16 54; SIMD128: .param v128{{$}} 55; SIMD128: .result i32{{$}} 56; SIMD128: i8x16.extract_lane_u $push0=, $0, 13 # encoding: [0xfd,0x0a,0x0d]{{$}} 57; SIMD128: return $pop0 # 58define i32 @extract_v16i8_u(<16 x i8> %v) { 59 %elem = extractelement <16 x i8> %v, i8 13 60 %a = zext i8 %elem to i32 61 ret i32 %a 62} 63 64; CHECK-LABEL: extract_v16i8: 65; NO-SIMD128-NOT: i8x16 66; SIMD128: .param v128{{$}} 67; SIMD128: .result i32{{$}} 68; SIMD128: i8x16.extract_lane_u $push0=, $0, 13 # encoding: [0xfd,0x0a,0x0d]{{$}} 69; SIMD128: return $pop0 # 70define i8 @extract_v16i8(<16 x i8> %v) { 71 %elem = extractelement <16 x i8> %v, i8 13 72 ret i8 %elem 73} 74 75; CHECK-LABEL: replace_v16i8: 76; NO-SIMD128-NOT: i8x16 77; SIMD128: .param v128, i32{{$}} 78; SIMD128: .result v128{{$}} 79; SIMD128: i8x16.replace_lane $push0=, $0, 11, $1 # encoding: [0xfd,0x11,0x0b]{{$}} 80; SIMD128: return $pop0 # encoding: [0x0f]{{$}} 81define <16 x i8> @replace_v16i8(<16 x i8> %v, i8 %x) { 82 %res = insertelement <16 x i8> %v, i8 %x, i32 11 83 ret <16 x i8> %res 84} 85 86; ============================================================================== 87; 8 x i16 88; ============================================================================== 89; CHECK-LABEL: const_v8i16: 90; NO-SIMD128-NOT: i16x8 91; SIMD128: .result v128{{$}} 92; SIMD128: v128.const $push0=, 256, 770, 1284, 1798, 2312, 2826, 3340, 3854 93; SIMD128-SAME: # encoding: [0xfd,0x00, 94; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 95; SIMD128-SAME: 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f]{{$}} 96define <8 x i16> @const_v8i16() { 97 ret <8 x i16> <i16 256, i16 770, i16 1284, i16 1798, 98 i16 2312, i16 2826, i16 3340, i16 3854> 99} 100 101; CHECK-LABEL: splat_v8i16: 102; NO-SIMD128-NOT: i16x8 103; SIMD128: .param i32{{$}} 104; SIMD128: .result v128{{$}} 105; SIMD128: i16x8.splat $push0=, $0 # encoding: [0xfd,0x04]{{$}} 106; SIMD128: return $pop0 # encoding: [0x0f]{{$}} 107define <8 x i16> @splat_v8i16(i16 %x) { 108 %v = insertelement <8 x i16> undef, i16 %x, i32 0 109 %res = shufflevector <8 x i16> %v, <8 x i16> undef, 110 <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 111 ret <8 x i16> %res 112} 113 114; CHECK-LABEL: extract_v8i16_s: 115; NO-SIMD128-NOT: i16x8 116; SIMD128: .param v128{{$}} 117; SIMD128: .result i32{{$}} 118; SIMD128: i16x8.extract_lane_s $push0=, $0, 5 # encoding: [0xfd,0x0b,0x05]{{$}} 119; SIMD128: return $pop0 # 120define i32 @extract_v8i16_s(<8 x i16> %v) { 121 %elem = extractelement <8 x i16> %v, i16 5 122 %a = sext i16 %elem to i32 123 ret i32 %a 124} 125 126; CHECK-LABEL: extract_v8i16_u: 127; NO-SIMD128-NOT: i16x8 128; SIMD128: .param v128{{$}} 129; SIMD128: .result i32{{$}} 130; SIMD128: i16x8.extract_lane_u $push0=, $0, 5 # encoding: [0xfd,0x0c,0x05]{{$}} 131; SIMD128: return $pop0 # 132define i32 @extract_v8i16_u(<8 x i16> %v) { 133 %elem = extractelement <8 x i16> %v, i16 5 134 %a = zext i16 %elem to i32 135 ret i32 %a 136} 137 138; CHECK-LABEL: extract_v8i16: 139; NO-SIMD128-NOT: i16x8 140; SIMD128: .param v128{{$}} 141; SIMD128: .result i32{{$}} 142; SIMD128: i16x8.extract_lane_u $push0=, $0, 5 # encoding: [0xfd,0x0c,0x05]{{$}} 143; SIMD128: return $pop0 # 144define i16 @extract_v8i16(<8 x i16> %v) { 145 %elem = extractelement <8 x i16> %v, i16 5 146 ret i16 %elem 147} 148 149; CHECK-LABEL: replace_v8i16: 150; NO-SIMD128-NOT: i16x8 151; SIMD128: .param v128, i32{{$}} 152; SIMD128: .result v128{{$}} 153; SIMD128: i16x8.replace_lane $push0=, $0, 7, $1 # encoding: [0xfd,0x12,0x07]{{$}} 154; SIMD128: return $pop0 # encoding: [0x0f]{{$}} 155define <8 x i16> @replace_v8i16(<8 x i16> %v, i16 %x) { 156 %res = insertelement <8 x i16> %v, i16 %x, i32 7 157 ret <8 x i16> %res 158} 159 160; ============================================================================== 161; 4 x i32 162; ============================================================================== 163; CHECK-LABEL: const_v4i32: 164; NO-SIMD128-NOT: i32x4 165; SIMD128: .result v128{{$}} 166; SIMD128: v128.const $push0=, 50462976, 117835012, 185207048, 252579084 167; SIMD128-SAME: # encoding: [0xfd,0x00, 168; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 169; SIMD128-SAME: 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f]{{$}} 170define <4 x i32> @const_v4i32() { 171 ret <4 x i32> <i32 50462976, i32 117835012, i32 185207048, i32 252579084> 172} 173 174; CHECK-LABEL: splat_v4i32: 175; NO-SIMD128-NOT: i32x4 176; SIMD128: .param i32{{$}} 177; SIMD128: .result v128{{$}} 178; SIMD128: i32x4.splat $push0=, $0 # encoding: [0xfd,0x05]{{$}} 179; SIMD128: return $pop0 # encoding: [0x0f]{{$}} 180define <4 x i32> @splat_v4i32(i32 %x) { 181 %v = insertelement <4 x i32> undef, i32 %x, i32 0 182 %res = shufflevector <4 x i32> %v, <4 x i32> undef, 183 <4 x i32> <i32 0, i32 0, i32 0, i32 0> 184 ret <4 x i32> %res 185} 186 187; CHECK-LABEL: extract_v4i32: 188; NO-SIMD128-NOT: i32x4 189; SIMD128: .param v128{{$}} 190; SIMD128: .result i32{{$}} 191; SIMD128: i32x4.extract_lane $push0=, $0, 3 # encoding: [0xfd,0x0d,0x03]{{$}} 192; SIMD128: return $pop0 # 193define i32 @extract_v4i32(<4 x i32> %v) { 194 %elem = extractelement <4 x i32> %v, i32 3 195 ret i32 %elem 196} 197 198; CHECK-LABEL: replace_v4i32: 199; NO-SIMD128-NOT: i32x4 200; SIMD128: .param v128, i32{{$}} 201; SIMD128: .result v128{{$}} 202; SIMD128: i32x4.replace_lane $push0=, $0, 2, $1 # encoding: [0xfd,0x13,0x02]{{$}} 203; SIMD128: return $pop0 # encoding: [0x0f]{{$}} 204define <4 x i32> @replace_v4i32(<4 x i32> %v, i32 %x) { 205 %res = insertelement <4 x i32> %v, i32 %x, i32 2 206 ret <4 x i32> %res 207} 208 209; ============================================================================== 210; 2 x i64 211; ============================================================================== 212; CHECK-LABEL: const_v2i64: 213; NO-SIMD128-NOT: i64x2 214; SIMD128-VM-NOT: i64x2 215; SIMD128: .result v128{{$}} 216; SIMD128: v128.const $push0=, 506097522914230528, 1084818905618843912 217; SIMD128-SAME: # encoding: [0xfd,0x00, 218; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 219; SIMD128-SAME: 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f]{{$}} 220define <2 x i64> @const_v2i64() { 221 ret <2 x i64> <i64 506097522914230528, i64 1084818905618843912> 222} 223 224; CHECK-LABEL: splat_v2i64: 225; NO-SIMD128-NOT: i64x2 226; SIMD128-VM-NOT: i64x2 227; SIMD128: .param i64{{$}} 228; SIMD128: .result v128{{$}} 229; SIMD128: i64x2.splat $push0=, $0 # encoding: [0xfd,0x06]{{$}} 230; SIMD128: return $pop0 # encoding: [0x0f]{{$}} 231define <2 x i64> @splat_v2i64(i64 %x) { 232 %t1 = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0 233 %res = insertelement <2 x i64> %t1, i64 %x, i32 1 234 ret <2 x i64> %res 235} 236 237; CHECK-LABEL: extract_v2i64: 238; NO-SIMD128-NOT: i64x2 239; SIMD128-VM-NOT: i64x2 240; SIMD128: .param v128{{$}} 241; SIMD128: .result i64{{$}} 242; SIMD128: i64x2.extract_lane $push0=, $0, 1 # encoding: [0xfd,0x0e,0x01]{{$}} 243; SIMD128: return $pop0 # 244define i64 @extract_v2i64(<2 x i64> %v) { 245 %elem = extractelement <2 x i64> %v, i64 1 246 ret i64 %elem 247} 248 249; CHECK-LABEL: replace_v2i64: 250; NO-SIMD128-NOT: i64x2 251; SIMD128-VM-NOT: i64x2 252; SIMD128: .param v128, i64{{$}} 253; SIMD128: .result v128{{$}} 254; SIMD128: i64x2.replace_lane $push0=, $0, 0, $1 # encoding: [0xfd,0x14,0x00]{{$}} 255; SIMD128: return $pop0 # encoding: [0x0f]{{$}} 256define <2 x i64> @replace_v2i64(<2 x i64> %v, i64 %x) { 257 %res = insertelement <2 x i64> %v, i64 %x, i32 0 258 ret <2 x i64> %res 259} 260 261; ============================================================================== 262; 4 x f32 263; ============================================================================== 264; CHECK-LABEL: const_v4f32: 265; NO-SIMD128-NOT: f32x4 266; SIMD128: .result v128{{$}} 267; SIMD128: v128.const $push0=, 268; SIMD128-SAME: 0x1.0402p-121, 0x1.0c0a08p-113, 0x1.14121p-105, 0x1.1c1a18p-97 269; SIMD128-SAME: # encoding: [0xfd,0x00, 270; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 271; SIMD128-SAME: 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f]{{$}} 272define <4 x float> @const_v4f32() { 273 ret <4 x float> <float 0x3860402000000000, float 0x38e0c0a080000000, 274 float 0x3961412100000000, float 0x39e1c1a180000000> 275} 276 277; CHECK-LABEL: splat_v4f32: 278; NO-SIMD128-NOT: f32x4 279; SIMD128: .param f32{{$}} 280; SIMD128: .result v128{{$}} 281; SIMD128: f32x4.splat $push0=, $0 # encoding: [0xfd,0x07]{{$}} 282; SIMD128: return $pop0 # encoding: [0x0f]{{$}} 283define <4 x float> @splat_v4f32(float %x) { 284 %v = insertelement <4 x float> undef, float %x, i32 0 285 %res = shufflevector <4 x float> %v, <4 x float> undef, 286 <4 x i32> <i32 0, i32 0, i32 0, i32 0> 287 ret <4 x float> %res 288} 289 290; CHECK-LABEL: extract_v4f32: 291; NO-SIMD128-NOT: f32x4 292; SIMD128: .param v128{{$}} 293; SIMD128: .result f32{{$}} 294; SIMD128: f32x4.extract_lane $push0=, $0, 3 # encoding: [0xfd,0x0f,0x03]{{$}} 295; SIMD128: return $pop0 # 296define float @extract_v4f32(<4 x float> %v) { 297 %elem = extractelement <4 x float> %v, i32 3 298 ret float %elem 299} 300 301; CHECK-LABEL: replace_v4f32: 302; NO-SIMD128-NOT: f32x4 303; SIMD128: .param v128, f32{{$}} 304; SIMD128: .result v128{{$}} 305; SIMD128: f32x4.replace_lane $push0=, $0, 2, $1 # encoding: [0xfd,0x15,0x02]{{$}} 306; SIMD128: return $pop0 # encoding: [0x0f]{{$}} 307define <4 x float> @replace_v4f32(<4 x float> %v, float %x) { 308 %res = insertelement <4 x float> %v, float %x, i32 2 309 ret <4 x float> %res 310} 311 312; ============================================================================== 313; 2 x f64 314; ============================================================================== 315; CHECK-LABEL: const_v2f64: 316; NO-SIMD128-NOT: f64x2 317; SIMD128: .result v128{{$}} 318; SIMD128: v128.const $push0=, 0x1.60504030201p-911, 0x1.e0d0c0b0a0908p-783 319; SIMD128-SAME: # encoding: [0xfd,0x00, 320; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 321; SIMD128-SAME: 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f]{{$}} 322define <2 x double> @const_v2f64() { 323 ret <2 x double> <double 0x0706050403020100, double 0x0F0E0D0C0B0A0908> 324} 325 326; CHECK-LABEL: splat_v2f64: 327; NO-SIMD128-NOT: f64x2 328; SIMD128-VM-NOT: f64x2 329; SIMD128: .param f64{{$}} 330; SIMD128: .result v128{{$}} 331; SIMD128: f64x2.splat $push0=, $0 # encoding: [0xfd,0x08]{{$}} 332; SIMD128: return $pop0 # encoding: [0x0f]{{$}} 333define <2 x double> @splat_v2f64(double %x) { 334 %t1 = insertelement <2 x double> zeroinitializer, double %x, i3 0 335 %res = insertelement <2 x double> %t1, double %x, i32 1 336 ret <2 x double> %res 337} 338 339; CHECK-LABEL: extract_v2f64: 340; NO-SIMD128-NOT: f64x2 341; SIMD128-VM-NOT: f64x2 342; SIMD128: .param v128{{$}} 343; SIMD128: .result f64{{$}} 344; SIMD128: f64x2.extract_lane $push0=, $0, 1 # encoding: [0xfd,0x10,0x01]{{$}} 345; SIMD128: return $pop0 # 346define double @extract_v2f64(<2 x double> %v) { 347 %elem = extractelement <2 x double> %v, i32 1 348 ret double %elem 349} 350 351; CHECK-LABEL: replace_v2f64: 352; NO-SIMD128-NOT: f64x2 353; SIMD128-VM-NOT: f64x2 354; SIMD128: .param v128, f64{{$}} 355; SIMD128: .result v128{{$}} 356; SIMD128: f64x2.replace_lane $push0=, $0, 0, $1 # encoding: [0xfd,0x16,0x00]{{$}} 357; SIMD128: return $pop0 # encoding: [0x0f]{{$}} 358define <2 x double> @replace_v2f64(<2 x double> %v, double %x) { 359 %res = insertelement <2 x double> %v, double %x, i32 0 360 ret <2 x double> %res 361} 362