1; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -wasm-enable-unimplemented-simd -mattr=+simd128,+sign-ext | FileCheck %s --check-prefixes CHECK,SIMD128 2; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128,+sign-ext | FileCheck %s --check-prefixes CHECK,SIMD128-VM 3; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=-simd128,+sign-ext | 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-NEXT: .result v128{{$}} 16; SIMD128-NEXT: v128.const $push[[R:[0-9]+]]=, 17; SIMD128-SAME: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 18; SIMD128-NEXT: return $pop[[R]]{{$}} 19define <16 x i8> @const_v16i8() { 20 ret <16 x i8> <i8 00, i8 01, i8 02, i8 03, i8 04, i8 05, i8 06, i8 07, 21 i8 08, i8 09, i8 10, i8 11, i8 12, i8 13, i8 14, i8 15> 22} 23 24; CHECK-LABEL: splat_v16i8: 25; NO-SIMD128-NOT: i8x16 26; SIMD128-NEXT: .param i32{{$}} 27; SIMD128-NEXT: .result v128{{$}} 28; SIMD128-NEXT: i8x16.splat $push[[R:[0-9]+]]=, $0{{$}} 29; SIMD128-NEXT: return $pop[[R]]{{$}} 30define <16 x i8> @splat_v16i8(i8 %x) { 31 %v = insertelement <16 x i8> undef, i8 %x, i32 0 32 %res = shufflevector <16 x i8> %v, <16 x i8> undef, 33 <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, 34 i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 35 ret <16 x i8> %res 36} 37 38; CHECK-LABEL: const_splat_v16i8: 39; SIMD128: i8x16.splat 40define <16 x i8> @const_splat_v16i8() { 41 ret <16 x i8> <i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, 42 i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42> 43} 44 45; CHECK-LABEL: extract_v16i8_s: 46; NO-SIMD128-NOT: i8x16 47; SIMD128-NEXT: .param v128{{$}} 48; SIMD128-NEXT: .result i32{{$}} 49; SIMD128-NEXT: i8x16.extract_lane_s $push[[R:[0-9]+]]=, $0, 13{{$}} 50; SIMD128-NEXT: return $pop[[R]]{{$}} 51define i32 @extract_v16i8_s(<16 x i8> %v) { 52 %elem = extractelement <16 x i8> %v, i8 13 53 %a = sext i8 %elem to i32 54 ret i32 %a 55} 56 57; CHECK-LABEL: extract_v16i8_u: 58; NO-SIMD128-NOT: i8x16 59; SIMD128-NEXT: .param v128{{$}} 60; SIMD128-NEXT: .result i32{{$}} 61; SIMD128-NEXT: i8x16.extract_lane_u $push[[R:[0-9]+]]=, $0, 13{{$}} 62; SIMD128-NEXT: return $pop[[R]]{{$}} 63define i32 @extract_v16i8_u(<16 x i8> %v) { 64 %elem = extractelement <16 x i8> %v, i8 13 65 %a = zext i8 %elem to i32 66 ret i32 %a 67} 68 69; CHECK-LABEL: extract_v16i8: 70; NO-SIMD128-NOT: i8x16 71; SIMD128-NEXT: .param v128{{$}} 72; SIMD128-NEXT: .result i32{{$}} 73; SIMD128-NEXT: i8x16.extract_lane_u $push[[R:[0-9]+]]=, $0, 13{{$}} 74; SIMD128-NEXT: return $pop[[R]]{{$}} 75define i8 @extract_v16i8(<16 x i8> %v) { 76 %elem = extractelement <16 x i8> %v, i8 13 77 ret i8 %elem 78} 79 80; CHECK-LABEL: replace_v16i8: 81; NO-SIMD128-NOT: i8x16 82; SIMD128-NEXT: .param v128, i32{{$}} 83; SIMD128-NEXT: .result v128{{$}} 84; SIMD128-NEXT: i8x16.replace_lane $push[[R:[0-9]+]]=, $0, 11, $1{{$}} 85; SIMD128-NEXT: return $pop[[R]]{{$}} 86define <16 x i8> @replace_v16i8(<16 x i8> %v, i8 %x) { 87 %res = insertelement <16 x i8> %v, i8 %x, i32 11 88 ret <16 x i8> %res 89} 90 91; CHECK-LABEL: shuffle_v16i8: 92; NO-SIMD128-NOT: v8x16 93; SIMD128-NEXT: .param v128, v128{{$}} 94; SIMD128-NEXT: .result v128{{$}} 95; SIMD128-NEXT: v8x16.shuffle $push[[R:[0-9]+]]=, $0, $1, 96; SIMD128-SAME: 0, 17, 2, 19, 4, 21, 6, 23, 8, 25, 10, 27, 12, 29, 14, 31{{$}} 97; SIMD128-NEXT: return $pop[[R]]{{$}} 98define <16 x i8> @shuffle_v16i8(<16 x i8> %x, <16 x i8> %y) { 99 %res = shufflevector <16 x i8> %x, <16 x i8> %y, 100 <16 x i32> <i32 0, i32 17, i32 2, i32 19, i32 4, i32 21, i32 6, i32 23, 101 i32 8, i32 25, i32 10, i32 27, i32 12, i32 29, i32 14, i32 31> 102 ret <16 x i8> %res 103} 104 105; CHECK-LABEL: build_v16i8: 106; NO-SIMD128-NOT: i8x16 107; SIMD128-NEXT: .param i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32{{$}} 108; SIMD128-NEXT: .result v128{{$}} 109; SIMD128-NEXT: i8x16.splat $push[[L0:[0-9]+]]=, $0{{$}} 110; SIMD128-NEXT: i8x16.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 1, $1{{$}} 111; SIMD128-NEXT: i8x16.replace_lane $push[[L2:[0-9]+]]=, $pop[[L1]], 2, $2{{$}} 112; SIMD128-NEXT: i8x16.replace_lane $push[[L3:[0-9]+]]=, $pop[[L2]], 3, $3{{$}} 113; SIMD128-NEXT: i8x16.replace_lane $push[[L4:[0-9]+]]=, $pop[[L3]], 4, $4{{$}} 114; SIMD128-NEXT: i8x16.replace_lane $push[[L5:[0-9]+]]=, $pop[[L4]], 5, $5{{$}} 115; SIMD128-NEXT: i8x16.replace_lane $push[[L6:[0-9]+]]=, $pop[[L5]], 6, $6{{$}} 116; SIMD128-NEXT: i8x16.replace_lane $push[[L7:[0-9]+]]=, $pop[[L6]], 7, $7{{$}} 117; SIMD128-NEXT: i8x16.replace_lane $push[[L8:[0-9]+]]=, $pop[[L7]], 8, $8{{$}} 118; SIMD128-NEXT: i8x16.replace_lane $push[[L9:[0-9]+]]=, $pop[[L8]], 9, $9{{$}} 119; SIMD128-NEXT: i8x16.replace_lane $push[[L10:[0-9]+]]=, $pop[[L9]], 10, $10{{$}} 120; SIMD128-NEXT: i8x16.replace_lane $push[[L11:[0-9]+]]=, $pop[[L10]], 11, $11{{$}} 121; SIMD128-NEXT: i8x16.replace_lane $push[[L12:[0-9]+]]=, $pop[[L11]], 12, $12{{$}} 122; SIMD128-NEXT: i8x16.replace_lane $push[[L13:[0-9]+]]=, $pop[[L12]], 13, $13{{$}} 123; SIMD128-NEXT: i8x16.replace_lane $push[[L14:[0-9]+]]=, $pop[[L13]], 14, $14{{$}} 124; SIMD128-NEXT: i8x16.replace_lane $push[[R:[0-9]+]]=, $pop[[L14]], 15, $15{{$}} 125; SIMD128-NEXT: return $pop[[R]]{{$}} 126define <16 x i8> @build_v16i8(i8 %x0, i8 %x1, i8 %x2, i8 %x3, 127 i8 %x4, i8 %x5, i8 %x6, i8 %x7, 128 i8 %x8, i8 %x9, i8 %x10, i8 %x11, 129 i8 %x12, i8 %x13, i8 %x14, i8 %x15) { 130 %t0 = insertelement <16 x i8> undef, i8 %x0, i32 0 131 %t1 = insertelement <16 x i8> %t0, i8 %x1, i32 1 132 %t2 = insertelement <16 x i8> %t1, i8 %x2, i32 2 133 %t3 = insertelement <16 x i8> %t2, i8 %x3, i32 3 134 %t4 = insertelement <16 x i8> %t3, i8 %x4, i32 4 135 %t5 = insertelement <16 x i8> %t4, i8 %x5, i32 5 136 %t6 = insertelement <16 x i8> %t5, i8 %x6, i32 6 137 %t7 = insertelement <16 x i8> %t6, i8 %x7, i32 7 138 %t8 = insertelement <16 x i8> %t7, i8 %x8, i32 8 139 %t9 = insertelement <16 x i8> %t8, i8 %x9, i32 9 140 %t10 = insertelement <16 x i8> %t9, i8 %x10, i32 10 141 %t11 = insertelement <16 x i8> %t10, i8 %x11, i32 11 142 %t12 = insertelement <16 x i8> %t11, i8 %x12, i32 12 143 %t13 = insertelement <16 x i8> %t12, i8 %x13, i32 13 144 %t14 = insertelement <16 x i8> %t13, i8 %x14, i32 14 145 %res = insertelement <16 x i8> %t14, i8 %x15, i32 15 146 ret <16 x i8> %res 147} 148 149; ============================================================================== 150; 8 x i16 151; ============================================================================== 152; CHECK-LABEL: const_v8i16: 153; NO-SIMD128-NOT: i16x8 154; SIMD128-NEXT: .result v128{{$}} 155; SIMD128-NEXT: v128.const $push[[R:[0-9]+]]=, 256, 770, 1284, 1798, 2312, 2826, 3340, 3854{{$}} 156; SIMD128-NEXT: return $pop[[R]]{{$}} 157define <8 x i16> @const_v8i16() { 158 ret <8 x i16> <i16 256, i16 770, i16 1284, i16 1798, 159 i16 2312, i16 2826, i16 3340, i16 3854> 160} 161 162; CHECK-LABEL: splat_v8i16: 163; NO-SIMD128-NOT: i16x8 164; SIMD128-NEXT: .param i32{{$}} 165; SIMD128-NEXT: .result v128{{$}} 166; SIMD128-NEXT: i16x8.splat $push[[R:[0-9]+]]=, $0{{$}} 167; SIMD128-NEXT: return $pop[[R]]{{$}} 168define <8 x i16> @splat_v8i16(i16 %x) { 169 %v = insertelement <8 x i16> undef, i16 %x, i32 0 170 %res = shufflevector <8 x i16> %v, <8 x i16> undef, 171 <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 172 ret <8 x i16> %res 173} 174 175; CHECK-LABEL: const_splat_v8i16: 176; SIMD128: i16x8.splat 177define <8 x i16> @const_splat_v8i16() { 178 ret <8 x i16> <i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42> 179} 180 181; CHECK-LABEL: extract_v8i16_s: 182; NO-SIMD128-NOT: i16x8 183; SIMD128-NEXT: .param v128{{$}} 184; SIMD128-NEXT: .result i32{{$}} 185; SIMD128-NEXT: i16x8.extract_lane_s $push[[R:[0-9]+]]=, $0, 5{{$}} 186; SIMD128-NEXT: return $pop[[R]]{{$}} 187define i32 @extract_v8i16_s(<8 x i16> %v) { 188 %elem = extractelement <8 x i16> %v, i16 5 189 %a = sext i16 %elem to i32 190 ret i32 %a 191} 192 193; CHECK-LABEL: extract_v8i16_u: 194; NO-SIMD128-NOT: i16x8 195; SIMD128-NEXT: .param v128{{$}} 196; SIMD128-NEXT: .result i32{{$}} 197; SIMD128-NEXT: i16x8.extract_lane_u $push[[R:[0-9]+]]=, $0, 5{{$}} 198; SIMD128-NEXT: return $pop[[R]]{{$}} 199define i32 @extract_v8i16_u(<8 x i16> %v) { 200 %elem = extractelement <8 x i16> %v, i16 5 201 %a = zext i16 %elem to i32 202 ret i32 %a 203} 204 205; CHECK-LABEL: extract_v8i16: 206; NO-SIMD128-NOT: i16x8 207; SIMD128-NEXT: .param v128{{$}} 208; SIMD128-NEXT: .result i32{{$}} 209; SIMD128-NEXT: i16x8.extract_lane_u $push[[R:[0-9]+]]=, $0, 5{{$}} 210; SIMD128-NEXT: return $pop[[R]]{{$}} 211define i16 @extract_v8i16(<8 x i16> %v) { 212 %elem = extractelement <8 x i16> %v, i16 5 213 ret i16 %elem 214} 215 216; CHECK-LABEL: replace_v8i16: 217; NO-SIMD128-NOT: i16x8 218; SIMD128-NEXT: .param v128, i32{{$}} 219; SIMD128-NEXT: .result v128{{$}} 220; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $0, 7, $1{{$}} 221; SIMD128-NEXT: return $pop[[R]]{{$}} 222define <8 x i16> @replace_v8i16(<8 x i16> %v, i16 %x) { 223 %res = insertelement <8 x i16> %v, i16 %x, i32 7 224 ret <8 x i16> %res 225} 226 227; CHECK-LABEL: shuffle_v8i16: 228; NO-SIMD128-NOT: v8x16 229; SIMD128-NEXT: .param v128, v128{{$}} 230; SIMD128-NEXT: .result v128{{$}} 231; SIMD128-NEXT: v8x16.shuffle $push[[R:[0-9]+]]=, $0, $1, 232; SIMD128-SAME: 0, 1, 18, 19, 4, 5, 22, 23, 8, 9, 26, 27, 12, 13, 30, 31{{$}} 233; SIMD128-NEXT: return $pop[[R]]{{$}} 234define <8 x i16> @shuffle_v8i16(<8 x i16> %x, <8 x i16> %y) { 235 %res = shufflevector <8 x i16> %x, <8 x i16> %y, 236 <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15> 237 ret <8 x i16> %res 238} 239 240; CHECK-LABEL: build_v8i16: 241; NO-SIMD128-NOT: i16x8 242; SIMD128-NEXT: .param i32, i32, i32, i32, i32, i32, i32, i32{{$}} 243; SIMD128-NEXT: .result v128{{$}} 244; SIMD128-NEXT: i16x8.splat $push[[L0:[0-9]+]]=, $0{{$}} 245; SIMD128-NEXT: i16x8.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 1, $1{{$}} 246; SIMD128-NEXT: i16x8.replace_lane $push[[L2:[0-9]+]]=, $pop[[L1]], 2, $2{{$}} 247; SIMD128-NEXT: i16x8.replace_lane $push[[L3:[0-9]+]]=, $pop[[L2]], 3, $3{{$}} 248; SIMD128-NEXT: i16x8.replace_lane $push[[L4:[0-9]+]]=, $pop[[L3]], 4, $4{{$}} 249; SIMD128-NEXT: i16x8.replace_lane $push[[L5:[0-9]+]]=, $pop[[L4]], 5, $5{{$}} 250; SIMD128-NEXT: i16x8.replace_lane $push[[L6:[0-9]+]]=, $pop[[L5]], 6, $6{{$}} 251; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $pop[[L6]], 7, $7{{$}} 252; SIMD128-NEXT: return $pop[[R]]{{$}} 253define <8 x i16> @build_v8i16(i16 %x0, i16 %x1, i16 %x2, i16 %x3, 254 i16 %x4, i16 %x5, i16 %x6, i16 %x7) { 255 %t0 = insertelement <8 x i16> undef, i16 %x0, i32 0 256 %t1 = insertelement <8 x i16> %t0, i16 %x1, i32 1 257 %t2 = insertelement <8 x i16> %t1, i16 %x2, i32 2 258 %t3 = insertelement <8 x i16> %t2, i16 %x3, i32 3 259 %t4 = insertelement <8 x i16> %t3, i16 %x4, i32 4 260 %t5 = insertelement <8 x i16> %t4, i16 %x5, i32 5 261 %t6 = insertelement <8 x i16> %t5, i16 %x6, i32 6 262 %res = insertelement <8 x i16> %t6, i16 %x7, i32 7 263 ret <8 x i16> %res 264} 265 266; ============================================================================== 267; 4 x i32 268; ============================================================================== 269; CHECK-LABEL: const_v4i32: 270; NO-SIMD128-NOT: i32x4 271; SIMD128-NEXT: .result v128{{$}} 272; SIMD128-NEXT: v128.const $push[[R:[0-9]+]]=, 50462976, 117835012, 185207048, 252579084{{$}} 273; SIMD128-NEXT: return $pop[[R]]{{$}} 274define <4 x i32> @const_v4i32() { 275 ret <4 x i32> <i32 50462976, i32 117835012, i32 185207048, i32 252579084> 276} 277 278; CHECK-LABEL: splat_v4i32: 279; NO-SIMD128-NOT: i32x4 280; SIMD128-NEXT: .param i32{{$}} 281; SIMD128-NEXT: .result v128{{$}} 282; SIMD128-NEXT: i32x4.splat $push[[R:[0-9]+]]=, $0{{$}} 283; SIMD128-NEXT: return $pop[[R]]{{$}} 284define <4 x i32> @splat_v4i32(i32 %x) { 285 %v = insertelement <4 x i32> undef, i32 %x, i32 0 286 %res = shufflevector <4 x i32> %v, <4 x i32> undef, 287 <4 x i32> <i32 0, i32 0, i32 0, i32 0> 288 ret <4 x i32> %res 289} 290 291; CHECK-LABEL: const_splat_v4i32: 292; SIMD128: i32x4.splat 293define <4 x i32> @const_splat_v4i32() { 294 ret <4 x i32> <i32 42, i32 42, i32 42, i32 42> 295} 296 297; CHECK-LABEL: extract_v4i32: 298; NO-SIMD128-NOT: i32x4 299; SIMD128-NEXT: .param v128{{$}} 300; SIMD128-NEXT: .result i32{{$}} 301; SIMD128-NEXT: i32x4.extract_lane $push[[R:[0-9]+]]=, $0, 3{{$}} 302; SIMD128-NEXT: return $pop[[R]]{{$}} 303define i32 @extract_v4i32(<4 x i32> %v) { 304 %elem = extractelement <4 x i32> %v, i32 3 305 ret i32 %elem 306} 307 308; CHECK-LABEL: replace_v4i32: 309; NO-SIMD128-NOT: i32x4 310; SIMD128-NEXT: .param v128, i32{{$}} 311; SIMD128-NEXT: .result v128{{$}} 312; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $0, 2, $1{{$}} 313; SIMD128-NEXT: return $pop[[R]]{{$}} 314define <4 x i32> @replace_v4i32(<4 x i32> %v, i32 %x) { 315 %res = insertelement <4 x i32> %v, i32 %x, i32 2 316 ret <4 x i32> %res 317} 318 319; CHECK-LABEL: shuffle_v4i32: 320; NO-SIMD128-NOT: v8x16 321; SIMD128-NEXT: .param v128, v128{{$}} 322; SIMD128-NEXT: .result v128{{$}} 323; SIMD128-NEXT: v8x16.shuffle $push[[R:[0-9]+]]=, $0, $1, 324; SIMD128-SAME: 0, 1, 2, 3, 20, 21, 22, 23, 8, 9, 10, 11, 28, 29, 30, 31{{$}} 325; SIMD128-NEXT: return $pop[[R]]{{$}} 326define <4 x i32> @shuffle_v4i32(<4 x i32> %x, <4 x i32> %y) { 327 %res = shufflevector <4 x i32> %x, <4 x i32> %y, 328 <4 x i32> <i32 0, i32 5, i32 2, i32 7> 329 ret <4 x i32> %res 330} 331 332; CHECK-LABEL: build_v4i32: 333; NO-SIMD128-NOT: i32x4 334; SIMD128-NEXT: .param i32, i32, i32, i32{{$}} 335; SIMD128-NEXT: .result v128{{$}} 336; SIMD128-NEXT: i32x4.splat $push[[L0:[0-9]+]]=, $0{{$}} 337; SIMD128-NEXT: i32x4.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 1, $1{{$}} 338; SIMD128-NEXT: i32x4.replace_lane $push[[L2:[0-9]+]]=, $pop[[L1]], 2, $2{{$}} 339; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L2]], 3, $3{{$}} 340; SIMD128-NEXT: return $pop[[R]]{{$}} 341define <4 x i32> @build_v4i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) { 342 %t0 = insertelement <4 x i32> undef, i32 %x0, i32 0 343 %t1 = insertelement <4 x i32> %t0, i32 %x1, i32 1 344 %t2 = insertelement <4 x i32> %t1, i32 %x2, i32 2 345 %res = insertelement <4 x i32> %t2, i32 %x3, i32 3 346 ret <4 x i32> %res 347} 348 349; ============================================================================== 350; 2 x i64 351; ============================================================================== 352; CHECK-LABEL: const_v2i64: 353; NO-SIMD128-NOT: i64x2 354; SIMD128-VM-NOT: i64x2 355; SIMD128-NEXT: .result v128{{$}} 356; SIMD128-NEXT: v128.const $push[[R:[0-9]+]]=, 506097522914230528, 1084818905618843912{{$}} 357; SIMD128-NEXT: return $pop[[R]]{{$}} 358define <2 x i64> @const_v2i64() { 359 ret <2 x i64> <i64 506097522914230528, i64 1084818905618843912> 360} 361 362; CHECK-LABEL: splat_v2i64: 363; NO-SIMD128-NOT: i64x2 364; SIMD128-VM-NOT: i64x2 365; SIMD128-NEXT: .param i64{{$}} 366; SIMD128-NEXT: .result v128{{$}} 367; SIMD128-NEXT: i64x2.splat $push[[R:[0-9]+]]=, $0{{$}} 368; SIMD128-NEXT: return $pop[[R]]{{$}} 369define <2 x i64> @splat_v2i64(i64 %x) { 370 %t1 = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0 371 %res = insertelement <2 x i64> %t1, i64 %x, i32 1 372 ret <2 x i64> %res 373} 374 375; CHECK-LABEL: const_splat_v2i64: 376; SIMD128: i64x2.splat 377define <2 x i64> @const_splat_v2i64() { 378 ret <2 x i64> <i64 42, i64 42> 379} 380 381; CHECK-LABEL: extract_v2i64: 382; NO-SIMD128-NOT: i64x2 383; SIMD128-VM-NOT: i64x2 384; SIMD128-NEXT: .param v128{{$}} 385; SIMD128-NEXT: .result i64{{$}} 386; SIMD128-NEXT: i64x2.extract_lane $push[[R:[0-9]+]]=, $0, 1{{$}} 387; SIMD128-NEXT: return $pop[[R]]{{$}} 388define i64 @extract_v2i64(<2 x i64> %v) { 389 %elem = extractelement <2 x i64> %v, i64 1 390 ret i64 %elem 391} 392 393; CHECK-LABEL: replace_v2i64: 394; NO-SIMD128-NOT: i64x2 395; SIMD128-VM-NOT: i64x2 396; SIMD128-NEXT: .param v128, i64{{$}} 397; SIMD128-NEXT: .result v128{{$}} 398; SIMD128-NEXT: i64x2.replace_lane $push[[R:[0-9]+]]=, $0, 0, $1{{$}} 399; SIMD128-NEXT: return $pop[[R]]{{$}} 400define <2 x i64> @replace_v2i64(<2 x i64> %v, i64 %x) { 401 %res = insertelement <2 x i64> %v, i64 %x, i32 0 402 ret <2 x i64> %res 403} 404 405; CHECK-LABEL: shuffle_v2i64: 406; NO-SIMD128-NOT: v8x16 407; SIMD128-NEXT: .param v128, v128{{$}} 408; SIMD128-NEXT: .result v128{{$}} 409; SIMD128-NEXT: v8x16.shuffle $push[[R:[0-9]+]]=, $0, $1, 410; SIMD128-SAME: 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31{{$}} 411; SIMD128-NEXT: return $pop[[R]]{{$}} 412define <2 x i64> @shuffle_v2i64(<2 x i64> %x, <2 x i64> %y) { 413 %res = shufflevector <2 x i64> %x, <2 x i64> %y, <2 x i32> <i32 0, i32 3> 414 ret <2 x i64> %res 415} 416 417; CHECK-LABEL: build_v2i64: 418; NO-SIMD128-NOT: i64x2 419; SIMD128-VM-NOT: i64x2 420; SIMD128-NEXT: .param i64, i64{{$}} 421; SIMD128-NEXT: .result v128{{$}} 422; SIMD128-NEXT: i64x2.splat $push[[L0:[0-9]+]]=, $0{{$}} 423; SIMD128-NEXT: i64x2.replace_lane $push[[R:[0-9]+]]=, $pop[[L0]], 1, $1{{$}} 424; SIMD128-NEXT: return $pop[[R]]{{$}} 425define <2 x i64> @build_v2i64(i64 %x0, i64 %x1) { 426 %t0 = insertelement <2 x i64> undef, i64 %x0, i32 0 427 %res = insertelement <2 x i64> %t0, i64 %x1, i32 1 428 ret <2 x i64> %res 429} 430 431; ============================================================================== 432; 4 x f32 433; ============================================================================== 434; CHECK-LABEL: const_v4f32: 435; NO-SIMD128-NOT: f32x4 436; SIMD128-NEXT: .result v128{{$}} 437; SIMD128-NEXT: v128.const $push[[R:[0-9]+]]=, 438; SIMD128-SAME: 0x1.0402p-121, 0x1.0c0a08p-113, 0x1.14121p-105, 0x1.1c1a18p-97{{$}} 439; SIMD128-NEXT: return $pop[[R]]{{$}} 440define <4 x float> @const_v4f32() { 441 ret <4 x float> <float 0x3860402000000000, float 0x38e0c0a080000000, 442 float 0x3961412100000000, float 0x39e1c1a180000000> 443} 444 445; CHECK-LABEL: splat_v4f32: 446; NO-SIMD128-NOT: f32x4 447; SIMD128-NEXT: .param f32{{$}} 448; SIMD128-NEXT: .result v128{{$}} 449; SIMD128-NEXT: f32x4.splat $push[[R:[0-9]+]]=, $0{{$}} 450; SIMD128-NEXT: return $pop[[R]]{{$}} 451define <4 x float> @splat_v4f32(float %x) { 452 %v = insertelement <4 x float> undef, float %x, i32 0 453 %res = shufflevector <4 x float> %v, <4 x float> undef, 454 <4 x i32> <i32 0, i32 0, i32 0, i32 0> 455 ret <4 x float> %res 456} 457 458; CHECK-LABEL: const_splat_v4f32 459; SIMD128: f32x4.splat 460define <4 x float> @const_splat_v4f32() { 461 ret <4 x float> <float 42., float 42., float 42., float 42.> 462} 463 464; CHECK-LABEL: extract_v4f32: 465; NO-SIMD128-NOT: f32x4 466; SIMD128-NEXT: .param v128{{$}} 467; SIMD128-NEXT: .result f32{{$}} 468; SIMD128-NEXT: f32x4.extract_lane $push[[R:[0-9]+]]=, $0, 3{{$}} 469; SIMD128-NEXT: return $pop[[R]]{{$}} 470define float @extract_v4f32(<4 x float> %v) { 471 %elem = extractelement <4 x float> %v, i32 3 472 ret float %elem 473} 474 475; CHECK-LABEL: replace_v4f32: 476; NO-SIMD128-NOT: f32x4 477; SIMD128-NEXT: .param v128, f32{{$}} 478; SIMD128-NEXT: .result v128{{$}} 479; SIMD128-NEXT: f32x4.replace_lane $push[[R:[0-9]+]]=, $0, 2, $1{{$}} 480; SIMD128-NEXT: return $pop[[R]]{{$}} 481define <4 x float> @replace_v4f32(<4 x float> %v, float %x) { 482 %res = insertelement <4 x float> %v, float %x, i32 2 483 ret <4 x float> %res 484} 485 486; CHECK-LABEL: shuffle_v4f32: 487; NO-SIMD128-NOT: v8x16 488; SIMD128-NEXT: .param v128, v128{{$}} 489; SIMD128-NEXT: .result v128{{$}} 490; SIMD128-NEXT: v8x16.shuffle $push[[R:[0-9]+]]=, $0, $1, 491; SIMD128-SAME: 0, 1, 2, 3, 20, 21, 22, 23, 8, 9, 10, 11, 28, 29, 30, 31{{$}} 492; SIMD128-NEXT: return $pop[[R]]{{$}} 493define <4 x float> @shuffle_v4f32(<4 x float> %x, <4 x float> %y) { 494 %res = shufflevector <4 x float> %x, <4 x float> %y, 495 <4 x i32> <i32 0, i32 5, i32 2, i32 7> 496 ret <4 x float> %res 497} 498 499; CHECK-LABEL: build_v4f32: 500; NO-SIMD128-NOT: f32x4 501; SIMD128-NEXT: .param f32, f32, f32, f32{{$}} 502; SIMD128-NEXT: .result v128{{$}} 503; SIMD128-NEXT: f32x4.splat $push[[L0:[0-9]+]]=, $0{{$}} 504; SIMD128-NEXT: f32x4.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 1, $1{{$}} 505; SIMD128-NEXT: f32x4.replace_lane $push[[L2:[0-9]+]]=, $pop[[L1]], 2, $2{{$}} 506; SIMD128-NEXT: f32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L2]], 3, $3{{$}} 507; SIMD128-NEXT: return $pop[[R]]{{$}} 508define <4 x float> @build_v4f32(float %x0, float %x1, float %x2, float %x3) { 509 %t0 = insertelement <4 x float> undef, float %x0, i32 0 510 %t1 = insertelement <4 x float> %t0, float %x1, i32 1 511 %t2 = insertelement <4 x float> %t1, float %x2, i32 2 512 %res = insertelement <4 x float> %t2, float %x3, i32 3 513 ret <4 x float> %res 514} 515 516; ============================================================================== 517; 2 x f64 518; ============================================================================== 519; CHECK-LABEL: const_v2f64: 520; NO-SIMD128-NOT: f64x2 521; SIMD128-NEXT: .result v128{{$}} 522; SIMD128-NEXT: v128.const $push[[R:[0-9]+]]=, 0x1.60504030201p-911, 0x1.e0d0c0b0a0908p-783{{$}} 523; SIMD128-NEXT: return $pop[[R]]{{$}} 524define <2 x double> @const_v2f64() { 525 ret <2 x double> <double 0x0706050403020100, double 0x0F0E0D0C0B0A0908> 526} 527 528; CHECK-LABEL: splat_v2f64: 529; NO-SIMD128-NOT: f64x2 530; SIMD128-VM-NOT: f64x2 531; SIMD128-NEXT: .param f64{{$}} 532; SIMD128-NEXT: .result v128{{$}} 533; SIMD128-NEXT: f64x2.splat $push[[R:[0-9]+]]=, $0{{$}} 534; SIMD128-NEXT: return $pop[[R]]{{$}} 535define <2 x double> @splat_v2f64(double %x) { 536 %t1 = insertelement <2 x double> zeroinitializer, double %x, i3 0 537 %res = insertelement <2 x double> %t1, double %x, i32 1 538 ret <2 x double> %res 539} 540 541; CHECK-LABEL: const_splat_v2f64: 542; SIMD128: f64x2.splat 543define <2 x double> @const_splat_v2f64() { 544 ret <2 x double> <double 42., double 42.> 545} 546 547; CHECK-LABEL: extract_v2f64: 548; NO-SIMD128-NOT: f64x2 549; SIMD128-VM-NOT: f64x2 550; SIMD128-NEXT: .param v128{{$}} 551; SIMD128-NEXT: .result f64{{$}} 552; SIMD128-NEXT: f64x2.extract_lane $push[[R:[0-9]+]]=, $0, 1{{$}} 553; SIMD128-NEXT: return $pop[[R]]{{$}} 554define double @extract_v2f64(<2 x double> %v) { 555 %elem = extractelement <2 x double> %v, i32 1 556 ret double %elem 557} 558 559; CHECK-LABEL: replace_v2f64: 560; NO-SIMD128-NOT: f64x2 561; SIMD128-VM-NOT: f64x2 562; SIMD128-NEXT: .param v128, f64{{$}} 563; SIMD128-NEXT: .result v128{{$}} 564; SIMD128-NEXT: f64x2.replace_lane $push[[R:[0-9]+]]=, $0, 0, $1{{$}} 565; SIMD128-NEXT: return $pop[[R]]{{$}} 566define <2 x double> @replace_v2f64(<2 x double> %v, double %x) { 567 %res = insertelement <2 x double> %v, double %x, i32 0 568 ret <2 x double> %res 569} 570 571; CHECK-LABEL: shuffle_v2f64: 572; NO-SIMD128-NOT: v8x16 573; SIMD128-NEXT: .param v128, v128{{$}} 574; SIMD128-NEXT: .result v128{{$}} 575; SIMD128-NEXT: v8x16.shuffle $push[[R:[0-9]+]]=, $0, $1, 576; SIMD128-SAME: 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31{{$}} 577; SIMD128-NEXT: return $pop[[R]]{{$}} 578define <2 x double> @shuffle_v2f64(<2 x double> %x, <2 x double> %y) { 579 %res = shufflevector <2 x double> %x, <2 x double> %y, 580 <2 x i32> <i32 0, i32 3> 581 ret <2 x double> %res 582} 583 584; CHECK-LABEL: build_v2f64: 585; NO-SIMD128-NOT: f64x2 586; SIMD128-VM-NOT: f64x2 587; SIMD128-NEXT: .param f64, f64{{$}} 588; SIMD128-NEXT: .result v128{{$}} 589; SIMD128-NEXT: f64x2.splat $push[[L0:[0-9]+]]=, $0{{$}} 590; SIMD128-NEXT: f64x2.replace_lane $push[[R:[0-9]+]]=, $pop[[L0]], 1, $1{{$}} 591; SIMD128-NEXT: return $pop[[R]]{{$}} 592define <2 x double> @build_v2f64(double %x0, double %x1) { 593 %t0 = insertelement <2 x double> undef, double %x0, i32 0 594 %res = insertelement <2 x double> %t0, double %x1, i32 1 595 ret <2 x double> %res 596} 597