1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -verify-machineinstrs -mattr=+simd128 | FileCheck %s 3 4; Test loads and stores with custom alignment values. 5 6target triple = "wasm32-unknown-unknown" 7 8; ============================================================================== 9; 16 x i8 10; ============================================================================== 11 12define <16 x i8> @load_v16i8_a1(ptr %p) { 13; CHECK-LABEL: load_v16i8_a1: 14; CHECK: .functype load_v16i8_a1 (i32) -> (v128) 15; CHECK-NEXT: # %bb.0: 16; CHECK-NEXT: local.get 0 17; CHECK-NEXT: v128.load 0:p2align=0 18; CHECK-NEXT: # fallthrough-return 19 %v = load <16 x i8>, ptr %p, align 1 20 ret <16 x i8> %v 21} 22 23define <16 x i8> @load_v16i8_a4(ptr %p) { 24; CHECK-LABEL: load_v16i8_a4: 25; CHECK: .functype load_v16i8_a4 (i32) -> (v128) 26; CHECK-NEXT: # %bb.0: 27; CHECK-NEXT: local.get 0 28; CHECK-NEXT: v128.load 0:p2align=2 29; CHECK-NEXT: # fallthrough-return 30 %v = load <16 x i8>, ptr %p, align 4 31 ret <16 x i8> %v 32} 33 34; 16 is the default alignment for v128 so no attribute is needed. 35define <16 x i8> @load_v16i8_a16(ptr %p) { 36; CHECK-LABEL: load_v16i8_a16: 37; CHECK: .functype load_v16i8_a16 (i32) -> (v128) 38; CHECK-NEXT: # %bb.0: 39; CHECK-NEXT: local.get 0 40; CHECK-NEXT: v128.load 0 41; CHECK-NEXT: # fallthrough-return 42 %v = load <16 x i8>, ptr %p, align 16 43 ret <16 x i8> %v 44} 45 46; 32 is greater than the default alignment so it is ignored. 47define <16 x i8> @load_v16i8_a32(ptr %p) { 48; CHECK-LABEL: load_v16i8_a32: 49; CHECK: .functype load_v16i8_a32 (i32) -> (v128) 50; CHECK-NEXT: # %bb.0: 51; CHECK-NEXT: local.get 0 52; CHECK-NEXT: v128.load 0 53; CHECK-NEXT: # fallthrough-return 54 %v = load <16 x i8>, ptr %p, align 32 55 ret <16 x i8> %v 56} 57 58define void @store_v16i8_a1(ptr %p, <16 x i8> %v) { 59; CHECK-LABEL: store_v16i8_a1: 60; CHECK: .functype store_v16i8_a1 (i32, v128) -> () 61; CHECK-NEXT: # %bb.0: 62; CHECK-NEXT: local.get 0 63; CHECK-NEXT: local.get 1 64; CHECK-NEXT: v128.store 0:p2align=0 65; CHECK-NEXT: # fallthrough-return 66 store <16 x i8> %v, ptr %p, align 1 67 ret void 68} 69 70define void @store_v16i8_a4(ptr %p, <16 x i8> %v) { 71; CHECK-LABEL: store_v16i8_a4: 72; CHECK: .functype store_v16i8_a4 (i32, v128) -> () 73; CHECK-NEXT: # %bb.0: 74; CHECK-NEXT: local.get 0 75; CHECK-NEXT: local.get 1 76; CHECK-NEXT: v128.store 0:p2align=2 77; CHECK-NEXT: # fallthrough-return 78 store <16 x i8> %v, ptr %p, align 4 79 ret void 80} 81 82; 16 is the default alignment for v128 so no attribute is needed. 83define void @store_v16i8_a16(ptr %p, <16 x i8> %v) { 84; CHECK-LABEL: store_v16i8_a16: 85; CHECK: .functype store_v16i8_a16 (i32, v128) -> () 86; CHECK-NEXT: # %bb.0: 87; CHECK-NEXT: local.get 0 88; CHECK-NEXT: local.get 1 89; CHECK-NEXT: v128.store 0 90; CHECK-NEXT: # fallthrough-return 91 store <16 x i8> %v, ptr %p, align 16 92 ret void 93} 94 95; 32 is greater than the default alignment so it is ignored. 96define void @store_v16i8_a32(ptr %p, <16 x i8> %v) { 97; CHECK-LABEL: store_v16i8_a32: 98; CHECK: .functype store_v16i8_a32 (i32, v128) -> () 99; CHECK-NEXT: # %bb.0: 100; CHECK-NEXT: local.get 0 101; CHECK-NEXT: local.get 1 102; CHECK-NEXT: v128.store 0 103; CHECK-NEXT: # fallthrough-return 104 store <16 x i8> %v, ptr %p, align 32 105 ret void 106} 107 108; 1 is the default alignment for v128.load8_splat so no attribute is needed. 109define <16 x i8> @load_splat_v16i8_a1(ptr %p) { 110; CHECK-LABEL: load_splat_v16i8_a1: 111; CHECK: .functype load_splat_v16i8_a1 (i32) -> (v128) 112; CHECK-NEXT: # %bb.0: 113; CHECK-NEXT: local.get 0 114; CHECK-NEXT: v128.load8_splat 0 115; CHECK-NEXT: # fallthrough-return 116 %e = load i8, ptr %p, align 1 117 %v1 = insertelement <16 x i8> undef, i8 %e, i32 0 118 %v2 = shufflevector <16 x i8> %v1, <16 x i8> undef, <16 x i32> zeroinitializer 119 ret <16 x i8> %v2 120} 121 122; 2 is greater than the default alignment so it is ignored. 123define <16 x i8> @load_splat_v16i8_a2(ptr %p) { 124; CHECK-LABEL: load_splat_v16i8_a2: 125; CHECK: .functype load_splat_v16i8_a2 (i32) -> (v128) 126; CHECK-NEXT: # %bb.0: 127; CHECK-NEXT: local.get 0 128; CHECK-NEXT: v128.load8_splat 0 129; CHECK-NEXT: # fallthrough-return 130 %e = load i8, ptr %p, align 2 131 %v1 = insertelement <16 x i8> undef, i8 %e, i32 0 132 %v2 = shufflevector <16 x i8> %v1, <16 x i8> undef, <16 x i32> zeroinitializer 133 ret <16 x i8> %v2 134} 135 136; 1 is the default alignment for v128.load8_lane so no attribute is needed. 137define <16 x i8> @load_lane_i8_a1(ptr %p, <16 x i8> %v) { 138; CHECK-LABEL: load_lane_i8_a1: 139; CHECK: .functype load_lane_i8_a1 (i32, v128) -> (v128) 140; CHECK-NEXT: # %bb.0: 141; CHECK-NEXT: local.get 0 142; CHECK-NEXT: local.get 1 143; CHECK-NEXT: v128.load8_lane 0, 0 144; CHECK-NEXT: # fallthrough-return 145 %e = load i8, ptr %p, align 1 146 %v1 = insertelement <16 x i8> %v, i8 %e, i32 0 147 ret <16 x i8> %v1 148} 149 150; 2 is greater than the default alignment so it is ignored. 151define <16 x i8> @load_lane_i8_a2(ptr %p, <16 x i8> %v) { 152; CHECK-LABEL: load_lane_i8_a2: 153; CHECK: .functype load_lane_i8_a2 (i32, v128) -> (v128) 154; CHECK-NEXT: # %bb.0: 155; CHECK-NEXT: local.get 0 156; CHECK-NEXT: local.get 1 157; CHECK-NEXT: v128.load8_lane 0, 0 158; CHECK-NEXT: # fallthrough-return 159 %e = load i8, ptr %p, align 2 160 %v1 = insertelement <16 x i8> %v, i8 %e, i32 0 161 ret <16 x i8> %v1 162} 163 164; 1 is the default alignment for v128.store8_lane so no attribute is needed. 165define void @store_lane_i8_a1(<16 x i8> %v, ptr %p) { 166; CHECK-LABEL: store_lane_i8_a1: 167; CHECK: .functype store_lane_i8_a1 (v128, i32) -> () 168; CHECK-NEXT: # %bb.0: 169; CHECK-NEXT: local.get 1 170; CHECK-NEXT: local.get 0 171; CHECK-NEXT: v128.store8_lane 0, 0 172; CHECK-NEXT: # fallthrough-return 173 %x = extractelement <16 x i8> %v, i32 0 174 store i8 %x, ptr %p, align 1 175 ret void 176} 177 178; 2 is greater than the default alignment so it is ignored. 179define void @store_lane_i8_a2(<16 x i8> %v, ptr %p) { 180; CHECK-LABEL: store_lane_i8_a2: 181; CHECK: .functype store_lane_i8_a2 (v128, i32) -> () 182; CHECK-NEXT: # %bb.0: 183; CHECK-NEXT: local.get 1 184; CHECK-NEXT: local.get 0 185; CHECK-NEXT: v128.store8_lane 0, 0 186; CHECK-NEXT: # fallthrough-return 187 %x = extractelement <16 x i8> %v, i32 0 188 store i8 %x, ptr %p, align 2 189 ret void 190} 191 192; ============================================================================== 193; 8 x i16 194; ============================================================================== 195 196define <8 x i16> @load_v8i16_a1(ptr %p) { 197; CHECK-LABEL: load_v8i16_a1: 198; CHECK: .functype load_v8i16_a1 (i32) -> (v128) 199; CHECK-NEXT: # %bb.0: 200; CHECK-NEXT: local.get 0 201; CHECK-NEXT: v128.load 0:p2align=0 202; CHECK-NEXT: # fallthrough-return 203 %v = load <8 x i16>, ptr %p, align 1 204 ret <8 x i16> %v 205} 206 207define <8 x i16> @load_v8i16_a4(ptr %p) { 208; CHECK-LABEL: load_v8i16_a4: 209; CHECK: .functype load_v8i16_a4 (i32) -> (v128) 210; CHECK-NEXT: # %bb.0: 211; CHECK-NEXT: local.get 0 212; CHECK-NEXT: v128.load 0:p2align=2 213; CHECK-NEXT: # fallthrough-return 214 %v = load <8 x i16>, ptr %p, align 4 215 ret <8 x i16> %v 216} 217 218; 8 is the default alignment for v128 so no attribute is needed. 219define <8 x i16> @load_v8i16_a16(ptr %p) { 220; CHECK-LABEL: load_v8i16_a16: 221; CHECK: .functype load_v8i16_a16 (i32) -> (v128) 222; CHECK-NEXT: # %bb.0: 223; CHECK-NEXT: local.get 0 224; CHECK-NEXT: v128.load 0 225; CHECK-NEXT: # fallthrough-return 226 %v = load <8 x i16>, ptr %p, align 16 227 ret <8 x i16> %v 228} 229 230; 32 is greater than the default alignment so it is ignored. 231define <8 x i16> @load_v8i16_a32(ptr %p) { 232; CHECK-LABEL: load_v8i16_a32: 233; CHECK: .functype load_v8i16_a32 (i32) -> (v128) 234; CHECK-NEXT: # %bb.0: 235; CHECK-NEXT: local.get 0 236; CHECK-NEXT: v128.load 0 237; CHECK-NEXT: # fallthrough-return 238 %v = load <8 x i16>, ptr %p, align 32 239 ret <8 x i16> %v 240} 241 242define void @store_v8i16_a1(ptr %p, <8 x i16> %v) { 243; CHECK-LABEL: store_v8i16_a1: 244; CHECK: .functype store_v8i16_a1 (i32, v128) -> () 245; CHECK-NEXT: # %bb.0: 246; CHECK-NEXT: local.get 0 247; CHECK-NEXT: local.get 1 248; CHECK-NEXT: v128.store 0:p2align=0 249; CHECK-NEXT: # fallthrough-return 250 store <8 x i16> %v, ptr %p, align 1 251 ret void 252} 253 254define void @store_v8i16_a4(ptr %p, <8 x i16> %v) { 255; CHECK-LABEL: store_v8i16_a4: 256; CHECK: .functype store_v8i16_a4 (i32, v128) -> () 257; CHECK-NEXT: # %bb.0: 258; CHECK-NEXT: local.get 0 259; CHECK-NEXT: local.get 1 260; CHECK-NEXT: v128.store 0:p2align=2 261; CHECK-NEXT: # fallthrough-return 262 store <8 x i16> %v, ptr %p, align 4 263 ret void 264} 265 266; 16 is the default alignment for v128 so no attribute is needed. 267define void @store_v8i16_a16(ptr %p, <8 x i16> %v) { 268; CHECK-LABEL: store_v8i16_a16: 269; CHECK: .functype store_v8i16_a16 (i32, v128) -> () 270; CHECK-NEXT: # %bb.0: 271; CHECK-NEXT: local.get 0 272; CHECK-NEXT: local.get 1 273; CHECK-NEXT: v128.store 0 274; CHECK-NEXT: # fallthrough-return 275 store <8 x i16> %v, ptr %p, align 16 276 ret void 277} 278 279; 32 is greater than the default alignment so it is ignored. 280define void @store_v8i16_a32(ptr %p, <8 x i16> %v) { 281; CHECK-LABEL: store_v8i16_a32: 282; CHECK: .functype store_v8i16_a32 (i32, v128) -> () 283; CHECK-NEXT: # %bb.0: 284; CHECK-NEXT: local.get 0 285; CHECK-NEXT: local.get 1 286; CHECK-NEXT: v128.store 0 287; CHECK-NEXT: # fallthrough-return 288 store <8 x i16> %v, ptr %p, align 32 289 ret void 290} 291 292define <8 x i8> @load_ext_v8i16_a1(ptr %p) { 293; CHECK-LABEL: load_ext_v8i16_a1: 294; CHECK: .functype load_ext_v8i16_a1 (i32) -> (v128) 295; CHECK-NEXT: # %bb.0: 296; CHECK-NEXT: local.get 0 297; CHECK-NEXT: v128.load64_zero 0:p2align=0 298; CHECK-NEXT: # fallthrough-return 299 %v = load <8 x i8>, ptr %p, align 1 300 ret <8 x i8> %v 301} 302 303define <8 x i8> @load_ext_v8i16_a2(ptr %p) { 304; CHECK-LABEL: load_ext_v8i16_a2: 305; CHECK: .functype load_ext_v8i16_a2 (i32) -> (v128) 306; CHECK-NEXT: # %bb.0: 307; CHECK-NEXT: local.get 0 308; CHECK-NEXT: v128.load64_zero 0:p2align=1 309; CHECK-NEXT: # fallthrough-return 310 %v = load <8 x i8>, ptr %p, align 2 311 ret <8 x i8> %v 312} 313 314define <8 x i8> @load_ext_v8i16_a4(ptr %p) { 315; CHECK-LABEL: load_ext_v8i16_a4: 316; CHECK: .functype load_ext_v8i16_a4 (i32) -> (v128) 317; CHECK-NEXT: # %bb.0: 318; CHECK-NEXT: local.get 0 319; CHECK-NEXT: v128.load64_zero 0:p2align=2 320; CHECK-NEXT: # fallthrough-return 321 %v = load <8 x i8>, ptr %p, align 4 322 ret <8 x i8> %v 323} 324 325; 8 is the default alignment for v128 extending load so no attribute is needed. 326define <8 x i8> @load_ext_v8i16_a8(ptr %p) { 327; CHECK-LABEL: load_ext_v8i16_a8: 328; CHECK: .functype load_ext_v8i16_a8 (i32) -> (v128) 329; CHECK-NEXT: # %bb.0: 330; CHECK-NEXT: local.get 0 331; CHECK-NEXT: v128.load64_zero 0 332; CHECK-NEXT: # fallthrough-return 333 %v = load <8 x i8>, ptr %p, align 8 334 ret <8 x i8> %v 335} 336 337; 16 is greater than the default alignment so it is ignored. 338define <8 x i8> @load_ext_v8i16_a16(ptr %p) { 339; CHECK-LABEL: load_ext_v8i16_a16: 340; CHECK: .functype load_ext_v8i16_a16 (i32) -> (v128) 341; CHECK-NEXT: # %bb.0: 342; CHECK-NEXT: local.get 0 343; CHECK-NEXT: v128.load 0 344; CHECK-NEXT: # fallthrough-return 345 %v = load <8 x i8>, ptr %p, align 16 346 ret <8 x i8> %v 347} 348 349define <8 x i16> @load_sext_v8i16_a1(ptr %p) { 350; CHECK-LABEL: load_sext_v8i16_a1: 351; CHECK: .functype load_sext_v8i16_a1 (i32) -> (v128) 352; CHECK-NEXT: # %bb.0: 353; CHECK-NEXT: local.get 0 354; CHECK-NEXT: i16x8.load8x8_s 0:p2align=0 355; CHECK-NEXT: # fallthrough-return 356 %v = load <8 x i8>, ptr %p, align 1 357 %v2 = sext <8 x i8> %v to <8 x i16> 358 ret <8 x i16> %v2 359} 360 361define <8 x i16> @load_sext_v8i16_a2(ptr %p) { 362; CHECK-LABEL: load_sext_v8i16_a2: 363; CHECK: .functype load_sext_v8i16_a2 (i32) -> (v128) 364; CHECK-NEXT: # %bb.0: 365; CHECK-NEXT: local.get 0 366; CHECK-NEXT: i16x8.load8x8_s 0:p2align=1 367; CHECK-NEXT: # fallthrough-return 368 %v = load <8 x i8>, ptr %p, align 2 369 %v2 = sext <8 x i8> %v to <8 x i16> 370 ret <8 x i16> %v2 371} 372 373define <8 x i16> @load_sext_v8i16_a4(ptr %p) { 374; CHECK-LABEL: load_sext_v8i16_a4: 375; CHECK: .functype load_sext_v8i16_a4 (i32) -> (v128) 376; CHECK-NEXT: # %bb.0: 377; CHECK-NEXT: local.get 0 378; CHECK-NEXT: i16x8.load8x8_s 0:p2align=2 379; CHECK-NEXT: # fallthrough-return 380 %v = load <8 x i8>, ptr %p, align 4 381 %v2 = sext <8 x i8> %v to <8 x i16> 382 ret <8 x i16> %v2 383} 384 385; 8 is the default alignment for v128 extending load so no attribute is needed. 386define <8 x i16> @load_sext_v8i16_a8(ptr %p) { 387; CHECK-LABEL: load_sext_v8i16_a8: 388; CHECK: .functype load_sext_v8i16_a8 (i32) -> (v128) 389; CHECK-NEXT: # %bb.0: 390; CHECK-NEXT: local.get 0 391; CHECK-NEXT: i16x8.load8x8_s 0 392; CHECK-NEXT: # fallthrough-return 393 %v = load <8 x i8>, ptr %p, align 8 394 %v2 = sext <8 x i8> %v to <8 x i16> 395 ret <8 x i16> %v2 396} 397 398; 16 is greater than the default alignment so it is ignored. 399define <8 x i16> @load_sext_v8i16_a16(ptr %p) { 400; CHECK-LABEL: load_sext_v8i16_a16: 401; CHECK: .functype load_sext_v8i16_a16 (i32) -> (v128) 402; CHECK-NEXT: # %bb.0: 403; CHECK-NEXT: local.get 0 404; CHECK-NEXT: i16x8.load8x8_s 0 405; CHECK-NEXT: # fallthrough-return 406 %v = load <8 x i8>, ptr %p, align 16 407 %v2 = sext <8 x i8> %v to <8 x i16> 408 ret <8 x i16> %v2 409} 410 411define <8 x i16> @load_splat_v8i16_a1(ptr %p) { 412; CHECK-LABEL: load_splat_v8i16_a1: 413; CHECK: .functype load_splat_v8i16_a1 (i32) -> (v128) 414; CHECK-NEXT: # %bb.0: 415; CHECK-NEXT: local.get 0 416; CHECK-NEXT: v128.load16_splat 0:p2align=0 417; CHECK-NEXT: # fallthrough-return 418 %e = load i16, ptr %p, align 1 419 %v1 = insertelement <8 x i16> undef, i16 %e, i32 0 420 %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer 421 ret <8 x i16> %v2 422} 423 424; 2 is the default alignment for v128.load16_splat so no attribute is needed. 425define <8 x i16> @load_splat_v8i16_a2(ptr %p) { 426; CHECK-LABEL: load_splat_v8i16_a2: 427; CHECK: .functype load_splat_v8i16_a2 (i32) -> (v128) 428; CHECK-NEXT: # %bb.0: 429; CHECK-NEXT: local.get 0 430; CHECK-NEXT: v128.load16_splat 0 431; CHECK-NEXT: # fallthrough-return 432 %e = load i16, ptr %p, align 2 433 %v1 = insertelement <8 x i16> undef, i16 %e, i32 0 434 %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer 435 ret <8 x i16> %v2 436} 437 438; 4 is greater than the default alignment so it is ignored. 439define <8 x i16> @load_splat_v8i16_a4(ptr %p) { 440; CHECK-LABEL: load_splat_v8i16_a4: 441; CHECK: .functype load_splat_v8i16_a4 (i32) -> (v128) 442; CHECK-NEXT: # %bb.0: 443; CHECK-NEXT: local.get 0 444; CHECK-NEXT: v128.load16_splat 0 445; CHECK-NEXT: # fallthrough-return 446 %e = load i16, ptr %p, align 4 447 %v1 = insertelement <8 x i16> undef, i16 %e, i32 0 448 %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer 449 ret <8 x i16> %v2 450} 451 452define <8 x i16> @load_lane_i16_a1(ptr %p, <8 x i16> %v) { 453; CHECK-LABEL: load_lane_i16_a1: 454; CHECK: .functype load_lane_i16_a1 (i32, v128) -> (v128) 455; CHECK-NEXT: # %bb.0: 456; CHECK-NEXT: local.get 0 457; CHECK-NEXT: local.get 1 458; CHECK-NEXT: v128.load16_lane 0:p2align=0, 0 459; CHECK-NEXT: # fallthrough-return 460 %e = load i16, ptr %p, align 1 461 %v1 = insertelement <8 x i16> %v, i16 %e, i32 0 462 ret <8 x i16> %v1 463} 464 465; 2 is the default alignment for v128.load16_lane so no attribute is needed. 466define <8 x i16> @load_lane_i16_a2(ptr %p, <8 x i16> %v) { 467; CHECK-LABEL: load_lane_i16_a2: 468; CHECK: .functype load_lane_i16_a2 (i32, v128) -> (v128) 469; CHECK-NEXT: # %bb.0: 470; CHECK-NEXT: local.get 0 471; CHECK-NEXT: local.get 1 472; CHECK-NEXT: v128.load16_lane 0, 0 473; CHECK-NEXT: # fallthrough-return 474 %e = load i16, ptr %p, align 2 475 %v1 = insertelement <8 x i16> %v, i16 %e, i32 0 476 ret <8 x i16> %v1 477} 478 479; 4 is greater than the default alignment so it is ignored. 480define <8 x i16> @load_lane_i16_a4(ptr %p, <8 x i16> %v) { 481; CHECK-LABEL: load_lane_i16_a4: 482; CHECK: .functype load_lane_i16_a4 (i32, v128) -> (v128) 483; CHECK-NEXT: # %bb.0: 484; CHECK-NEXT: local.get 0 485; CHECK-NEXT: local.get 1 486; CHECK-NEXT: v128.load16_lane 0, 0 487; CHECK-NEXT: # fallthrough-return 488 %e = load i16, ptr %p, align 4 489 %v1 = insertelement <8 x i16> %v, i16 %e, i32 0 490 ret <8 x i16> %v1 491} 492 493define void @store_lane_i16_a1(<8 x i16> %v, ptr %p) { 494; CHECK-LABEL: store_lane_i16_a1: 495; CHECK: .functype store_lane_i16_a1 (v128, i32) -> () 496; CHECK-NEXT: # %bb.0: 497; CHECK-NEXT: local.get 1 498; CHECK-NEXT: local.get 0 499; CHECK-NEXT: v128.store16_lane 0:p2align=0, 0 500; CHECK-NEXT: # fallthrough-return 501 %x = extractelement <8 x i16> %v, i32 0 502 store i16 %x, ptr %p, align 1 503 ret void 504} 505 506; 2 is the default alignment for v128.store16_lane so no attribute is needed. 507define void @store_lane_i16_a2(<8 x i16> %v, ptr %p) { 508; CHECK-LABEL: store_lane_i16_a2: 509; CHECK: .functype store_lane_i16_a2 (v128, i32) -> () 510; CHECK-NEXT: # %bb.0: 511; CHECK-NEXT: local.get 1 512; CHECK-NEXT: local.get 0 513; CHECK-NEXT: v128.store16_lane 0, 0 514; CHECK-NEXT: # fallthrough-return 515 %x = extractelement <8 x i16> %v, i32 0 516 store i16 %x, ptr %p, align 2 517 ret void 518} 519 520; 4 is greater than the default alignment so it is ignored. 521define void @store_lane_i16_a4(<8 x i16> %v, ptr %p) { 522; CHECK-LABEL: store_lane_i16_a4: 523; CHECK: .functype store_lane_i16_a4 (v128, i32) -> () 524; CHECK-NEXT: # %bb.0: 525; CHECK-NEXT: local.get 1 526; CHECK-NEXT: local.get 0 527; CHECK-NEXT: v128.store16_lane 0, 0 528; CHECK-NEXT: # fallthrough-return 529 %x = extractelement <8 x i16> %v, i32 0 530 store i16 %x, ptr %p, align 4 531 ret void 532} 533 534; ============================================================================== 535; 4 x i32 536; ============================================================================== 537 538define <4 x i32> @load_v4i32_a1(ptr %p) { 539; CHECK-LABEL: load_v4i32_a1: 540; CHECK: .functype load_v4i32_a1 (i32) -> (v128) 541; CHECK-NEXT: # %bb.0: 542; CHECK-NEXT: local.get 0 543; CHECK-NEXT: v128.load 0:p2align=0 544; CHECK-NEXT: # fallthrough-return 545 %v = load <4 x i32>, ptr %p, align 1 546 ret <4 x i32> %v 547} 548 549define <4 x i32> @load_v4i32_a4(ptr %p) { 550; CHECK-LABEL: load_v4i32_a4: 551; CHECK: .functype load_v4i32_a4 (i32) -> (v128) 552; CHECK-NEXT: # %bb.0: 553; CHECK-NEXT: local.get 0 554; CHECK-NEXT: v128.load 0:p2align=2 555; CHECK-NEXT: # fallthrough-return 556 %v = load <4 x i32>, ptr %p, align 4 557 ret <4 x i32> %v 558} 559 560; 4 is the default alignment for v128 so no attribute is needed. 561define <4 x i32> @load_v4i32_a16(ptr %p) { 562; CHECK-LABEL: load_v4i32_a16: 563; CHECK: .functype load_v4i32_a16 (i32) -> (v128) 564; CHECK-NEXT: # %bb.0: 565; CHECK-NEXT: local.get 0 566; CHECK-NEXT: v128.load 0 567; CHECK-NEXT: # fallthrough-return 568 %v = load <4 x i32>, ptr %p, align 16 569 ret <4 x i32> %v 570} 571 572; 32 is greater than the default alignment so it is ignored. 573define <4 x i32> @load_v4i32_a32(ptr %p) { 574; CHECK-LABEL: load_v4i32_a32: 575; CHECK: .functype load_v4i32_a32 (i32) -> (v128) 576; CHECK-NEXT: # %bb.0: 577; CHECK-NEXT: local.get 0 578; CHECK-NEXT: v128.load 0 579; CHECK-NEXT: # fallthrough-return 580 %v = load <4 x i32>, ptr %p, align 32 581 ret <4 x i32> %v 582} 583 584define void @store_v4i32_a1(ptr %p, <4 x i32> %v) { 585; CHECK-LABEL: store_v4i32_a1: 586; CHECK: .functype store_v4i32_a1 (i32, v128) -> () 587; CHECK-NEXT: # %bb.0: 588; CHECK-NEXT: local.get 0 589; CHECK-NEXT: local.get 1 590; CHECK-NEXT: v128.store 0:p2align=0 591; CHECK-NEXT: # fallthrough-return 592 store <4 x i32> %v, ptr %p, align 1 593 ret void 594} 595 596define void @store_v4i32_a4(ptr %p, <4 x i32> %v) { 597; CHECK-LABEL: store_v4i32_a4: 598; CHECK: .functype store_v4i32_a4 (i32, v128) -> () 599; CHECK-NEXT: # %bb.0: 600; CHECK-NEXT: local.get 0 601; CHECK-NEXT: local.get 1 602; CHECK-NEXT: v128.store 0:p2align=2 603; CHECK-NEXT: # fallthrough-return 604 store <4 x i32> %v, ptr %p, align 4 605 ret void 606} 607 608; 16 is the default alignment for v128 so no attribute is needed. 609define void @store_v4i32_a16(ptr %p, <4 x i32> %v) { 610; CHECK-LABEL: store_v4i32_a16: 611; CHECK: .functype store_v4i32_a16 (i32, v128) -> () 612; CHECK-NEXT: # %bb.0: 613; CHECK-NEXT: local.get 0 614; CHECK-NEXT: local.get 1 615; CHECK-NEXT: v128.store 0 616; CHECK-NEXT: # fallthrough-return 617 store <4 x i32> %v, ptr %p, align 16 618 ret void 619} 620 621; 32 is greater than the default alignment so it is ignored. 622define void @store_v4i32_a32(ptr %p, <4 x i32> %v) { 623; CHECK-LABEL: store_v4i32_a32: 624; CHECK: .functype store_v4i32_a32 (i32, v128) -> () 625; CHECK-NEXT: # %bb.0: 626; CHECK-NEXT: local.get 0 627; CHECK-NEXT: local.get 1 628; CHECK-NEXT: v128.store 0 629; CHECK-NEXT: # fallthrough-return 630 store <4 x i32> %v, ptr %p, align 32 631 ret void 632} 633 634define <4 x i16> @load_ext_v4i32_a1(ptr %p) { 635; CHECK-LABEL: load_ext_v4i32_a1: 636; CHECK: .functype load_ext_v4i32_a1 (i32) -> (v128) 637; CHECK-NEXT: # %bb.0: 638; CHECK-NEXT: local.get 0 639; CHECK-NEXT: v128.load64_zero 0:p2align=0 640; CHECK-NEXT: # fallthrough-return 641 %v = load <4 x i16>, ptr %p, align 1 642 ret <4 x i16> %v 643} 644 645define <4 x i16> @load_ext_v4i32_a2(ptr %p) { 646; CHECK-LABEL: load_ext_v4i32_a2: 647; CHECK: .functype load_ext_v4i32_a2 (i32) -> (v128) 648; CHECK-NEXT: # %bb.0: 649; CHECK-NEXT: local.get 0 650; CHECK-NEXT: v128.load64_zero 0:p2align=1 651; CHECK-NEXT: # fallthrough-return 652 %v = load <4 x i16>, ptr %p, align 2 653 ret <4 x i16> %v 654} 655 656define <4 x i16> @load_ext_v4i32_a4(ptr %p) { 657; CHECK-LABEL: load_ext_v4i32_a4: 658; CHECK: .functype load_ext_v4i32_a4 (i32) -> (v128) 659; CHECK-NEXT: # %bb.0: 660; CHECK-NEXT: local.get 0 661; CHECK-NEXT: v128.load64_zero 0:p2align=2 662; CHECK-NEXT: # fallthrough-return 663 %v = load <4 x i16>, ptr %p, align 4 664 ret <4 x i16> %v 665} 666 667; 8 is the default alignment for v128 extending load so no attribute is needed. 668define <4 x i16> @load_ext_v4i32_a8(ptr %p) { 669; CHECK-LABEL: load_ext_v4i32_a8: 670; CHECK: .functype load_ext_v4i32_a8 (i32) -> (v128) 671; CHECK-NEXT: # %bb.0: 672; CHECK-NEXT: local.get 0 673; CHECK-NEXT: v128.load64_zero 0 674; CHECK-NEXT: # fallthrough-return 675 %v = load <4 x i16>, ptr %p, align 8 676 ret <4 x i16> %v 677} 678 679; 16 is greater than the default alignment so it is ignored. 680define <4 x i16> @load_ext_v4i32_a16(ptr %p) { 681; CHECK-LABEL: load_ext_v4i32_a16: 682; CHECK: .functype load_ext_v4i32_a16 (i32) -> (v128) 683; CHECK-NEXT: # %bb.0: 684; CHECK-NEXT: local.get 0 685; CHECK-NEXT: v128.load 0 686; CHECK-NEXT: # fallthrough-return 687 %v = load <4 x i16>, ptr %p, align 16 688 ret <4 x i16> %v 689} 690 691define <4 x i32> @load_sext_v4i32_a1(ptr %p) { 692; CHECK-LABEL: load_sext_v4i32_a1: 693; CHECK: .functype load_sext_v4i32_a1 (i32) -> (v128) 694; CHECK-NEXT: # %bb.0: 695; CHECK-NEXT: local.get 0 696; CHECK-NEXT: i32x4.load16x4_s 0:p2align=0 697; CHECK-NEXT: # fallthrough-return 698 %v = load <4 x i16>, ptr %p, align 1 699 %v2 = sext <4 x i16> %v to <4 x i32> 700 ret <4 x i32> %v2 701} 702 703define <4 x i32> @load_sext_v4i32_a2(ptr %p) { 704; CHECK-LABEL: load_sext_v4i32_a2: 705; CHECK: .functype load_sext_v4i32_a2 (i32) -> (v128) 706; CHECK-NEXT: # %bb.0: 707; CHECK-NEXT: local.get 0 708; CHECK-NEXT: i32x4.load16x4_s 0:p2align=1 709; CHECK-NEXT: # fallthrough-return 710 %v = load <4 x i16>, ptr %p, align 2 711 %v2 = sext <4 x i16> %v to <4 x i32> 712 ret <4 x i32> %v2 713} 714 715define <4 x i32> @load_sext_v4i32_a4(ptr %p) { 716; CHECK-LABEL: load_sext_v4i32_a4: 717; CHECK: .functype load_sext_v4i32_a4 (i32) -> (v128) 718; CHECK-NEXT: # %bb.0: 719; CHECK-NEXT: local.get 0 720; CHECK-NEXT: i32x4.load16x4_s 0:p2align=2 721; CHECK-NEXT: # fallthrough-return 722 %v = load <4 x i16>, ptr %p, align 4 723 %v2 = sext <4 x i16> %v to <4 x i32> 724 ret <4 x i32> %v2 725} 726 727; 8 is the default alignment for v128 extending load so no attribute is needed. 728define <4 x i32> @load_sext_v4i32_a8(ptr %p) { 729; CHECK-LABEL: load_sext_v4i32_a8: 730; CHECK: .functype load_sext_v4i32_a8 (i32) -> (v128) 731; CHECK-NEXT: # %bb.0: 732; CHECK-NEXT: local.get 0 733; CHECK-NEXT: i32x4.load16x4_s 0 734; CHECK-NEXT: # fallthrough-return 735 %v = load <4 x i16>, ptr %p, align 8 736 %v2 = sext <4 x i16> %v to <4 x i32> 737 ret <4 x i32> %v2 738} 739 740; 16 is greater than the default alignment so it is ignored. 741define <4 x i32> @load_sext_v4i32_a16(ptr %p) { 742; CHECK-LABEL: load_sext_v4i32_a16: 743; CHECK: .functype load_sext_v4i32_a16 (i32) -> (v128) 744; CHECK-NEXT: # %bb.0: 745; CHECK-NEXT: local.get 0 746; CHECK-NEXT: i32x4.load16x4_s 0 747; CHECK-NEXT: # fallthrough-return 748 %v = load <4 x i16>, ptr %p, align 16 749 %v2 = sext <4 x i16> %v to <4 x i32> 750 ret <4 x i32> %v2 751} 752 753define <4 x i32> @load_splat_v4i32_a1(ptr %addr) { 754; CHECK-LABEL: load_splat_v4i32_a1: 755; CHECK: .functype load_splat_v4i32_a1 (i32) -> (v128) 756; CHECK-NEXT: # %bb.0: 757; CHECK-NEXT: local.get 0 758; CHECK-NEXT: v128.load32_splat 0:p2align=0 759; CHECK-NEXT: # fallthrough-return 760 %e = load i32, ptr %addr, align 1 761 %v1 = insertelement <4 x i32> undef, i32 %e, i32 0 762 %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer 763 ret <4 x i32> %v2 764} 765 766define <4 x i32> @load_splat_v4i32_a2(ptr %addr) { 767; CHECK-LABEL: load_splat_v4i32_a2: 768; CHECK: .functype load_splat_v4i32_a2 (i32) -> (v128) 769; CHECK-NEXT: # %bb.0: 770; CHECK-NEXT: local.get 0 771; CHECK-NEXT: v128.load32_splat 0:p2align=1 772; CHECK-NEXT: # fallthrough-return 773 %e = load i32, ptr %addr, align 2 774 %v1 = insertelement <4 x i32> undef, i32 %e, i32 0 775 %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer 776 ret <4 x i32> %v2 777} 778 779; 4 is the default alignment for v128.load32_splat so no attribute is needed. 780define <4 x i32> @load_splat_v4i32_a4(ptr %addr) { 781; CHECK-LABEL: load_splat_v4i32_a4: 782; CHECK: .functype load_splat_v4i32_a4 (i32) -> (v128) 783; CHECK-NEXT: # %bb.0: 784; CHECK-NEXT: local.get 0 785; CHECK-NEXT: v128.load32_splat 0 786; CHECK-NEXT: # fallthrough-return 787 %e = load i32, ptr %addr, align 4 788 %v1 = insertelement <4 x i32> undef, i32 %e, i32 0 789 %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer 790 ret <4 x i32> %v2 791} 792 793; 8 is greater than the default alignment so it is ignored. 794define <4 x i32> @load_splat_v4i32_a8(ptr %addr) { 795; CHECK-LABEL: load_splat_v4i32_a8: 796; CHECK: .functype load_splat_v4i32_a8 (i32) -> (v128) 797; CHECK-NEXT: # %bb.0: 798; CHECK-NEXT: local.get 0 799; CHECK-NEXT: v128.load32_splat 0 800; CHECK-NEXT: # fallthrough-return 801 %e = load i32, ptr %addr, align 8 802 %v1 = insertelement <4 x i32> undef, i32 %e, i32 0 803 %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer 804 ret <4 x i32> %v2 805} 806 807define <4 x i32> @load_lane_i32_a1(ptr %p, <4 x i32> %v) { 808; CHECK-LABEL: load_lane_i32_a1: 809; CHECK: .functype load_lane_i32_a1 (i32, v128) -> (v128) 810; CHECK-NEXT: # %bb.0: 811; CHECK-NEXT: local.get 0 812; CHECK-NEXT: local.get 1 813; CHECK-NEXT: v128.load32_lane 0:p2align=0, 0 814; CHECK-NEXT: # fallthrough-return 815 %e = load i32, ptr %p, align 1 816 %v1 = insertelement <4 x i32> %v, i32 %e, i32 0 817 ret <4 x i32> %v1 818} 819 820define <4 x i32> @load_lane_i32_a2(ptr %p, <4 x i32> %v) { 821; CHECK-LABEL: load_lane_i32_a2: 822; CHECK: .functype load_lane_i32_a2 (i32, v128) -> (v128) 823; CHECK-NEXT: # %bb.0: 824; CHECK-NEXT: local.get 0 825; CHECK-NEXT: local.get 1 826; CHECK-NEXT: v128.load32_lane 0:p2align=1, 0 827; CHECK-NEXT: # fallthrough-return 828 %e = load i32, ptr %p, align 2 829 %v1 = insertelement <4 x i32> %v, i32 %e, i32 0 830 ret <4 x i32> %v1 831} 832 833; 4 is the default alignment for v128.load32_lane so no attribute is needed. 834define <4 x i32> @load_lane_i32_a4(ptr %p, <4 x i32> %v) { 835; CHECK-LABEL: load_lane_i32_a4: 836; CHECK: .functype load_lane_i32_a4 (i32, v128) -> (v128) 837; CHECK-NEXT: # %bb.0: 838; CHECK-NEXT: local.get 0 839; CHECK-NEXT: local.get 1 840; CHECK-NEXT: v128.load32_lane 0, 0 841; CHECK-NEXT: # fallthrough-return 842 %e = load i32, ptr %p, align 4 843 %v1 = insertelement <4 x i32> %v, i32 %e, i32 0 844 ret <4 x i32> %v1 845} 846 847; 8 is greater than the default alignment so it is ignored. 848define <4 x i32> @load_lane_i32_a8(ptr %p, <4 x i32> %v) { 849; CHECK-LABEL: load_lane_i32_a8: 850; CHECK: .functype load_lane_i32_a8 (i32, v128) -> (v128) 851; CHECK-NEXT: # %bb.0: 852; CHECK-NEXT: local.get 0 853; CHECK-NEXT: local.get 1 854; CHECK-NEXT: v128.load32_lane 0, 0 855; CHECK-NEXT: # fallthrough-return 856 %e = load i32, ptr %p, align 8 857 %v1 = insertelement <4 x i32> %v, i32 %e, i32 0 858 ret <4 x i32> %v1 859} 860 861define void @store_lane_i32_a1(<4 x i32> %v, ptr %p) { 862; CHECK-LABEL: store_lane_i32_a1: 863; CHECK: .functype store_lane_i32_a1 (v128, i32) -> () 864; CHECK-NEXT: # %bb.0: 865; CHECK-NEXT: local.get 1 866; CHECK-NEXT: local.get 0 867; CHECK-NEXT: v128.store32_lane 0:p2align=0, 0 868; CHECK-NEXT: # fallthrough-return 869 %x = extractelement <4 x i32> %v, i32 0 870 store i32 %x, ptr %p, align 1 871 ret void 872} 873 874define void @store_lane_i32_a2(<4 x i32> %v, ptr %p) { 875; CHECK-LABEL: store_lane_i32_a2: 876; CHECK: .functype store_lane_i32_a2 (v128, i32) -> () 877; CHECK-NEXT: # %bb.0: 878; CHECK-NEXT: local.get 1 879; CHECK-NEXT: local.get 0 880; CHECK-NEXT: v128.store32_lane 0:p2align=1, 0 881; CHECK-NEXT: # fallthrough-return 882 %x = extractelement <4 x i32> %v, i32 0 883 store i32 %x, ptr %p, align 2 884 ret void 885} 886 887; 4 is the default alignment for v128.store32_lane so no attribute is needed. 888define void @store_lane_i32_a4(<4 x i32> %v, ptr %p) { 889; CHECK-LABEL: store_lane_i32_a4: 890; CHECK: .functype store_lane_i32_a4 (v128, i32) -> () 891; CHECK-NEXT: # %bb.0: 892; CHECK-NEXT: local.get 1 893; CHECK-NEXT: local.get 0 894; CHECK-NEXT: v128.store32_lane 0, 0 895; CHECK-NEXT: # fallthrough-return 896 %x = extractelement <4 x i32> %v, i32 0 897 store i32 %x, ptr %p, align 4 898 ret void 899} 900 901; 8 is greater than the default alignment so it is ignored. 902define void @store_lane_i32_a8(<4 x i32> %v, ptr %p) { 903; CHECK-LABEL: store_lane_i32_a8: 904; CHECK: .functype store_lane_i32_a8 (v128, i32) -> () 905; CHECK-NEXT: # %bb.0: 906; CHECK-NEXT: local.get 1 907; CHECK-NEXT: local.get 0 908; CHECK-NEXT: v128.store32_lane 0, 0 909; CHECK-NEXT: # fallthrough-return 910 %x = extractelement <4 x i32> %v, i32 0 911 store i32 %x, ptr %p, align 8 912 ret void 913} 914 915define <4 x i32> @load_zero_i32_a1(ptr %p) { 916; CHECK-LABEL: load_zero_i32_a1: 917; CHECK: .functype load_zero_i32_a1 (i32) -> (v128) 918; CHECK-NEXT: # %bb.0: 919; CHECK-NEXT: local.get 0 920; CHECK-NEXT: v128.load32_zero 0:p2align=0 921; CHECK-NEXT: # fallthrough-return 922 %x = load i32, ptr %p, align 1 923 %v = insertelement <4 x i32> zeroinitializer, i32 %x, i32 0 924 ret <4 x i32> %v 925} 926 927define <4 x i32> @load_zero_i32_a2(ptr %p) { 928; CHECK-LABEL: load_zero_i32_a2: 929; CHECK: .functype load_zero_i32_a2 (i32) -> (v128) 930; CHECK-NEXT: # %bb.0: 931; CHECK-NEXT: local.get 0 932; CHECK-NEXT: v128.load32_zero 0:p2align=1 933; CHECK-NEXT: # fallthrough-return 934 %x = load i32, ptr %p, align 2 935 %v = insertelement <4 x i32> zeroinitializer, i32 %x, i32 0 936 ret <4 x i32> %v 937} 938 939; 4 is the default alignment for v128.load32_zero so no attribute is needed. 940define <4 x i32> @load_zero_i32_a4(ptr %p) { 941; CHECK-LABEL: load_zero_i32_a4: 942; CHECK: .functype load_zero_i32_a4 (i32) -> (v128) 943; CHECK-NEXT: # %bb.0: 944; CHECK-NEXT: local.get 0 945; CHECK-NEXT: v128.load32_zero 0 946; CHECK-NEXT: # fallthrough-return 947 %x = load i32, ptr %p, align 4 948 %v = insertelement <4 x i32> zeroinitializer, i32 %x, i32 0 949 ret <4 x i32> %v 950} 951 952; 8 is greater than the default alignment so it is ignored. 953define <4 x i32> @load_zero_i32_a8(ptr %p) { 954; CHECK-LABEL: load_zero_i32_a8: 955; CHECK: .functype load_zero_i32_a8 (i32) -> (v128) 956; CHECK-NEXT: # %bb.0: 957; CHECK-NEXT: local.get 0 958; CHECK-NEXT: v128.load32_zero 0 959; CHECK-NEXT: # fallthrough-return 960 %x = load i32, ptr %p, align 8 961 %v = insertelement <4 x i32> zeroinitializer, i32 %x, i32 0 962 ret <4 x i32> %v 963} 964 965; ============================================================================== 966; 2 x i64 967; ============================================================================== 968 969define <2 x i64> @load_v2i64_a1(ptr %p) { 970; CHECK-LABEL: load_v2i64_a1: 971; CHECK: .functype load_v2i64_a1 (i32) -> (v128) 972; CHECK-NEXT: # %bb.0: 973; CHECK-NEXT: local.get 0 974; CHECK-NEXT: v128.load 0:p2align=0 975; CHECK-NEXT: # fallthrough-return 976 %v = load <2 x i64>, ptr %p, align 1 977 ret <2 x i64> %v 978} 979 980define <2 x i64> @load_v2i64_a4(ptr %p) { 981; CHECK-LABEL: load_v2i64_a4: 982; CHECK: .functype load_v2i64_a4 (i32) -> (v128) 983; CHECK-NEXT: # %bb.0: 984; CHECK-NEXT: local.get 0 985; CHECK-NEXT: v128.load 0:p2align=2 986; CHECK-NEXT: # fallthrough-return 987 %v = load <2 x i64>, ptr %p, align 4 988 ret <2 x i64> %v 989} 990 991; 2 is the default alignment for v128 so no attribute is needed. 992define <2 x i64> @load_v2i64_a16(ptr %p) { 993; CHECK-LABEL: load_v2i64_a16: 994; CHECK: .functype load_v2i64_a16 (i32) -> (v128) 995; CHECK-NEXT: # %bb.0: 996; CHECK-NEXT: local.get 0 997; CHECK-NEXT: v128.load 0 998; CHECK-NEXT: # fallthrough-return 999 %v = load <2 x i64>, ptr %p, align 16 1000 ret <2 x i64> %v 1001} 1002 1003; 32 is greater than the default alignment so it is ignored. 1004define <2 x i64> @load_v2i64_a32(ptr %p) { 1005; CHECK-LABEL: load_v2i64_a32: 1006; CHECK: .functype load_v2i64_a32 (i32) -> (v128) 1007; CHECK-NEXT: # %bb.0: 1008; CHECK-NEXT: local.get 0 1009; CHECK-NEXT: v128.load 0 1010; CHECK-NEXT: # fallthrough-return 1011 %v = load <2 x i64>, ptr %p, align 32 1012 ret <2 x i64> %v 1013} 1014 1015define void @store_v2i64_a1(ptr %p, <2 x i64> %v) { 1016; CHECK-LABEL: store_v2i64_a1: 1017; CHECK: .functype store_v2i64_a1 (i32, v128) -> () 1018; CHECK-NEXT: # %bb.0: 1019; CHECK-NEXT: local.get 0 1020; CHECK-NEXT: local.get 1 1021; CHECK-NEXT: v128.store 0:p2align=0 1022; CHECK-NEXT: # fallthrough-return 1023 store <2 x i64> %v, ptr %p, align 1 1024 ret void 1025} 1026 1027define void @store_v2i64_a4(ptr %p, <2 x i64> %v) { 1028; CHECK-LABEL: store_v2i64_a4: 1029; CHECK: .functype store_v2i64_a4 (i32, v128) -> () 1030; CHECK-NEXT: # %bb.0: 1031; CHECK-NEXT: local.get 0 1032; CHECK-NEXT: local.get 1 1033; CHECK-NEXT: v128.store 0:p2align=2 1034; CHECK-NEXT: # fallthrough-return 1035 store <2 x i64> %v, ptr %p, align 4 1036 ret void 1037} 1038 1039; 16 is the default alignment for v128 so no attribute is needed. 1040define void @store_v2i64_a16(ptr %p, <2 x i64> %v) { 1041; CHECK-LABEL: store_v2i64_a16: 1042; CHECK: .functype store_v2i64_a16 (i32, v128) -> () 1043; CHECK-NEXT: # %bb.0: 1044; CHECK-NEXT: local.get 0 1045; CHECK-NEXT: local.get 1 1046; CHECK-NEXT: v128.store 0 1047; CHECK-NEXT: # fallthrough-return 1048 store <2 x i64> %v, ptr %p, align 16 1049 ret void 1050} 1051 1052; 32 is greater than the default alignment so it is ignored. 1053define void @store_v2i64_a32(ptr %p, <2 x i64> %v) { 1054; CHECK-LABEL: store_v2i64_a32: 1055; CHECK: .functype store_v2i64_a32 (i32, v128) -> () 1056; CHECK-NEXT: # %bb.0: 1057; CHECK-NEXT: local.get 0 1058; CHECK-NEXT: local.get 1 1059; CHECK-NEXT: v128.store 0 1060; CHECK-NEXT: # fallthrough-return 1061 store <2 x i64> %v, ptr %p, align 32 1062 ret void 1063} 1064 1065define <2 x i64> @load_splat_v2i64_a1(ptr %p) { 1066; CHECK-LABEL: load_splat_v2i64_a1: 1067; CHECK: .functype load_splat_v2i64_a1 (i32) -> (v128) 1068; CHECK-NEXT: # %bb.0: 1069; CHECK-NEXT: local.get 0 1070; CHECK-NEXT: v128.load64_splat 0:p2align=0 1071; CHECK-NEXT: # fallthrough-return 1072 %e = load i64, ptr %p, align 1 1073 %v1 = insertelement <2 x i64> undef, i64 %e, i32 0 1074 %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer 1075 ret <2 x i64> %v2 1076} 1077 1078define <2 x i64> @load_splat_v2i64_a2(ptr %p) { 1079; CHECK-LABEL: load_splat_v2i64_a2: 1080; CHECK: .functype load_splat_v2i64_a2 (i32) -> (v128) 1081; CHECK-NEXT: # %bb.0: 1082; CHECK-NEXT: local.get 0 1083; CHECK-NEXT: v128.load64_splat 0:p2align=1 1084; CHECK-NEXT: # fallthrough-return 1085 %e = load i64, ptr %p, align 2 1086 %v1 = insertelement <2 x i64> undef, i64 %e, i32 0 1087 %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer 1088 ret <2 x i64> %v2 1089} 1090 1091define <2 x i64> @load_splat_v2i64_a4(ptr %p) { 1092; CHECK-LABEL: load_splat_v2i64_a4: 1093; CHECK: .functype load_splat_v2i64_a4 (i32) -> (v128) 1094; CHECK-NEXT: # %bb.0: 1095; CHECK-NEXT: local.get 0 1096; CHECK-NEXT: v128.load64_splat 0:p2align=2 1097; CHECK-NEXT: # fallthrough-return 1098 %e = load i64, ptr %p, align 4 1099 %v1 = insertelement <2 x i64> undef, i64 %e, i32 0 1100 %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer 1101 ret <2 x i64> %v2 1102} 1103 1104; 8 is the default alignment for v128.load64_splat so no attribute is needed. 1105define <2 x i64> @load_splat_v2i64_a8(ptr %p) { 1106; CHECK-LABEL: load_splat_v2i64_a8: 1107; CHECK: .functype load_splat_v2i64_a8 (i32) -> (v128) 1108; CHECK-NEXT: # %bb.0: 1109; CHECK-NEXT: local.get 0 1110; CHECK-NEXT: v128.load64_splat 0 1111; CHECK-NEXT: # fallthrough-return 1112 %e = load i64, ptr %p, align 8 1113 %v1 = insertelement <2 x i64> undef, i64 %e, i32 0 1114 %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer 1115 ret <2 x i64> %v2 1116} 1117 1118; 16 is greater than the default alignment so it is ignored. 1119define <2 x i64> @load_splat_v2i64_a16(ptr %p) { 1120; CHECK-LABEL: load_splat_v2i64_a16: 1121; CHECK: .functype load_splat_v2i64_a16 (i32) -> (v128) 1122; CHECK-NEXT: # %bb.0: 1123; CHECK-NEXT: local.get 0 1124; CHECK-NEXT: v128.load64_splat 0 1125; CHECK-NEXT: # fallthrough-return 1126 %e = load i64, ptr %p, align 16 1127 %v1 = insertelement <2 x i64> undef, i64 %e, i32 0 1128 %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer 1129 ret <2 x i64> %v2 1130} 1131 1132define <2 x i64> @load_lane_i64_a1(ptr %p, <2 x i64> %v) { 1133; CHECK-LABEL: load_lane_i64_a1: 1134; CHECK: .functype load_lane_i64_a1 (i32, v128) -> (v128) 1135; CHECK-NEXT: # %bb.0: 1136; CHECK-NEXT: local.get 0 1137; CHECK-NEXT: local.get 1 1138; CHECK-NEXT: v128.load64_lane 0:p2align=0, 0 1139; CHECK-NEXT: # fallthrough-return 1140 %e = load i64, ptr %p, align 1 1141 %v1 = insertelement <2 x i64> %v, i64 %e, i32 0 1142 ret <2 x i64> %v1 1143} 1144 1145define <2 x i64> @load_lane_i64_a2(ptr %p, <2 x i64> %v) { 1146; CHECK-LABEL: load_lane_i64_a2: 1147; CHECK: .functype load_lane_i64_a2 (i32, v128) -> (v128) 1148; CHECK-NEXT: # %bb.0: 1149; CHECK-NEXT: local.get 0 1150; CHECK-NEXT: local.get 1 1151; CHECK-NEXT: v128.load64_lane 0:p2align=1, 0 1152; CHECK-NEXT: # fallthrough-return 1153 %e = load i64, ptr %p, align 2 1154 %v1 = insertelement <2 x i64> %v, i64 %e, i32 0 1155 ret <2 x i64> %v1 1156} 1157 1158define <2 x i64> @load_lane_i64_a4(ptr %p, <2 x i64> %v) { 1159; CHECK-LABEL: load_lane_i64_a4: 1160; CHECK: .functype load_lane_i64_a4 (i32, v128) -> (v128) 1161; CHECK-NEXT: # %bb.0: 1162; CHECK-NEXT: local.get 0 1163; CHECK-NEXT: local.get 1 1164; CHECK-NEXT: v128.load64_lane 0:p2align=2, 0 1165; CHECK-NEXT: # fallthrough-return 1166 %e = load i64, ptr %p, align 4 1167 %v1 = insertelement <2 x i64> %v, i64 %e, i32 0 1168 ret <2 x i64> %v1 1169} 1170 1171; 8 is the default alignment for v128.load64_lane so no attribute is needed. 1172define <2 x i64> @load_lane_i64_a8(ptr %p, <2 x i64> %v) { 1173; CHECK-LABEL: load_lane_i64_a8: 1174; CHECK: .functype load_lane_i64_a8 (i32, v128) -> (v128) 1175; CHECK-NEXT: # %bb.0: 1176; CHECK-NEXT: local.get 0 1177; CHECK-NEXT: local.get 1 1178; CHECK-NEXT: v128.load64_lane 0, 0 1179; CHECK-NEXT: # fallthrough-return 1180 %e = load i64, ptr %p, align 8 1181 %v1 = insertelement <2 x i64> %v, i64 %e, i32 0 1182 ret <2 x i64> %v1 1183} 1184 1185; 16 is greater than the default alignment so it is ignored. 1186define <2 x i64> @load_lane_i64_a16(ptr %p, <2 x i64> %v) { 1187; CHECK-LABEL: load_lane_i64_a16: 1188; CHECK: .functype load_lane_i64_a16 (i32, v128) -> (v128) 1189; CHECK-NEXT: # %bb.0: 1190; CHECK-NEXT: local.get 0 1191; CHECK-NEXT: local.get 1 1192; CHECK-NEXT: v128.load64_lane 0, 0 1193; CHECK-NEXT: # fallthrough-return 1194 %e = load i64, ptr %p, align 16 1195 %v1 = insertelement <2 x i64> %v, i64 %e, i32 0 1196 ret <2 x i64> %v1 1197} 1198 1199define void @store_lane_i64_a1(<2 x i64> %v, ptr %p) { 1200; CHECK-LABEL: store_lane_i64_a1: 1201; CHECK: .functype store_lane_i64_a1 (v128, i32) -> () 1202; CHECK-NEXT: # %bb.0: 1203; CHECK-NEXT: local.get 1 1204; CHECK-NEXT: local.get 0 1205; CHECK-NEXT: v128.store64_lane 0:p2align=0, 0 1206; CHECK-NEXT: # fallthrough-return 1207 %x = extractelement <2 x i64> %v, i32 0 1208 store i64 %x, ptr %p, align 1 1209 ret void 1210} 1211 1212define void @store_lane_i64_a2(<2 x i64> %v, ptr %p) { 1213; CHECK-LABEL: store_lane_i64_a2: 1214; CHECK: .functype store_lane_i64_a2 (v128, i32) -> () 1215; CHECK-NEXT: # %bb.0: 1216; CHECK-NEXT: local.get 1 1217; CHECK-NEXT: local.get 0 1218; CHECK-NEXT: v128.store64_lane 0:p2align=1, 0 1219; CHECK-NEXT: # fallthrough-return 1220 %x = extractelement <2 x i64> %v, i32 0 1221 store i64 %x, ptr %p, align 2 1222 ret void 1223} 1224 1225define void @store_lane_i64_a4(<2 x i64> %v, ptr %p) { 1226; CHECK-LABEL: store_lane_i64_a4: 1227; CHECK: .functype store_lane_i64_a4 (v128, i32) -> () 1228; CHECK-NEXT: # %bb.0: 1229; CHECK-NEXT: local.get 1 1230; CHECK-NEXT: local.get 0 1231; CHECK-NEXT: v128.store64_lane 0:p2align=2, 0 1232; CHECK-NEXT: # fallthrough-return 1233 %x = extractelement <2 x i64> %v, i32 0 1234 store i64 %x, ptr %p, align 4 1235 ret void 1236} 1237 1238; 8 is the default alignment for v128.store64_lane so no attribute is needed. 1239define void @store_lane_i64_a8(<2 x i64> %v, ptr %p) { 1240; CHECK-LABEL: store_lane_i64_a8: 1241; CHECK: .functype store_lane_i64_a8 (v128, i32) -> () 1242; CHECK-NEXT: # %bb.0: 1243; CHECK-NEXT: local.get 1 1244; CHECK-NEXT: local.get 0 1245; CHECK-NEXT: v128.store64_lane 0, 0 1246; CHECK-NEXT: # fallthrough-return 1247 %x = extractelement <2 x i64> %v, i32 0 1248 store i64 %x, ptr %p, align 8 1249 ret void 1250} 1251 1252; 16 is greater than the default alignment so it is ignored. 1253define void @store_lane_i64_a16(<2 x i64> %v, ptr %p) { 1254; CHECK-LABEL: store_lane_i64_a16: 1255; CHECK: .functype store_lane_i64_a16 (v128, i32) -> () 1256; CHECK-NEXT: # %bb.0: 1257; CHECK-NEXT: local.get 1 1258; CHECK-NEXT: local.get 0 1259; CHECK-NEXT: v128.store64_lane 0, 0 1260; CHECK-NEXT: # fallthrough-return 1261 %x = extractelement <2 x i64> %v, i32 0 1262 store i64 %x, ptr %p, align 16 1263 ret void 1264} 1265 1266define <2 x i64> @load_zero_i64_a1(ptr %p) { 1267; CHECK-LABEL: load_zero_i64_a1: 1268; CHECK: .functype load_zero_i64_a1 (i32) -> (v128) 1269; CHECK-NEXT: # %bb.0: 1270; CHECK-NEXT: local.get 0 1271; CHECK-NEXT: v128.load64_zero 0:p2align=0 1272; CHECK-NEXT: # fallthrough-return 1273 %x = load i64, ptr %p, align 1 1274 %v = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0 1275 ret <2 x i64> %v 1276} 1277 1278define <2 x i64> @load_zero_i64_a2(ptr %p) { 1279; CHECK-LABEL: load_zero_i64_a2: 1280; CHECK: .functype load_zero_i64_a2 (i32) -> (v128) 1281; CHECK-NEXT: # %bb.0: 1282; CHECK-NEXT: local.get 0 1283; CHECK-NEXT: v128.load64_zero 0:p2align=1 1284; CHECK-NEXT: # fallthrough-return 1285 %x = load i64, ptr %p, align 2 1286 %v = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0 1287 ret <2 x i64> %v 1288} 1289 1290define <2 x i64> @load_zero_i64_a4(ptr %p) { 1291; CHECK-LABEL: load_zero_i64_a4: 1292; CHECK: .functype load_zero_i64_a4 (i32) -> (v128) 1293; CHECK-NEXT: # %bb.0: 1294; CHECK-NEXT: local.get 0 1295; CHECK-NEXT: v128.load64_zero 0:p2align=2 1296; CHECK-NEXT: # fallthrough-return 1297 %x = load i64, ptr %p, align 4 1298 %v = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0 1299 ret <2 x i64> %v 1300} 1301 1302; 8 is the default alignment for v128.load64_zero so no attribute is needed. 1303define <2 x i64> @load_zero_i64_a8(ptr %p) { 1304; CHECK-LABEL: load_zero_i64_a8: 1305; CHECK: .functype load_zero_i64_a8 (i32) -> (v128) 1306; CHECK-NEXT: # %bb.0: 1307; CHECK-NEXT: local.get 0 1308; CHECK-NEXT: v128.load64_zero 0 1309; CHECK-NEXT: # fallthrough-return 1310 %x = load i64, ptr %p, align 8 1311 %v = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0 1312 ret <2 x i64> %v 1313} 1314 1315; 16 is greater than the default alignment so it is ignored. 1316define <2 x i64> @load_zero_i64_a16(ptr %p) { 1317; CHECK-LABEL: load_zero_i64_a16: 1318; CHECK: .functype load_zero_i64_a16 (i32) -> (v128) 1319; CHECK-NEXT: # %bb.0: 1320; CHECK-NEXT: local.get 0 1321; CHECK-NEXT: v128.load64_zero 0 1322; CHECK-NEXT: # fallthrough-return 1323 %x = load i64, ptr %p, align 16 1324 %v = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0 1325 ret <2 x i64> %v 1326} 1327 1328; ============================================================================== 1329; 4 x float 1330; ============================================================================== 1331 1332define <4 x float> @load_v4f32_a1(ptr %p) { 1333; CHECK-LABEL: load_v4f32_a1: 1334; CHECK: .functype load_v4f32_a1 (i32) -> (v128) 1335; CHECK-NEXT: # %bb.0: 1336; CHECK-NEXT: local.get 0 1337; CHECK-NEXT: v128.load 0:p2align=0 1338; CHECK-NEXT: # fallthrough-return 1339 %v = load <4 x float>, ptr %p, align 1 1340 ret <4 x float> %v 1341} 1342 1343define <4 x float> @load_v4f32_a4(ptr %p) { 1344; CHECK-LABEL: load_v4f32_a4: 1345; CHECK: .functype load_v4f32_a4 (i32) -> (v128) 1346; CHECK-NEXT: # %bb.0: 1347; CHECK-NEXT: local.get 0 1348; CHECK-NEXT: v128.load 0:p2align=2 1349; CHECK-NEXT: # fallthrough-return 1350 %v = load <4 x float>, ptr %p, align 4 1351 ret <4 x float> %v 1352} 1353 1354; 4 is the default alignment for v128 so no attribute is needed. 1355define <4 x float> @load_v4f32_a16(ptr %p) { 1356; CHECK-LABEL: load_v4f32_a16: 1357; CHECK: .functype load_v4f32_a16 (i32) -> (v128) 1358; CHECK-NEXT: # %bb.0: 1359; CHECK-NEXT: local.get 0 1360; CHECK-NEXT: v128.load 0 1361; CHECK-NEXT: # fallthrough-return 1362 %v = load <4 x float>, ptr %p, align 16 1363 ret <4 x float> %v 1364} 1365 1366; 32 is greater than the default alignment so it is ignored. 1367define <4 x float> @load_v4f32_a32(ptr %p) { 1368; CHECK-LABEL: load_v4f32_a32: 1369; CHECK: .functype load_v4f32_a32 (i32) -> (v128) 1370; CHECK-NEXT: # %bb.0: 1371; CHECK-NEXT: local.get 0 1372; CHECK-NEXT: v128.load 0 1373; CHECK-NEXT: # fallthrough-return 1374 %v = load <4 x float>, ptr %p, align 32 1375 ret <4 x float> %v 1376} 1377 1378define void @store_v4f32_a1(ptr %p, <4 x float> %v) { 1379; CHECK-LABEL: store_v4f32_a1: 1380; CHECK: .functype store_v4f32_a1 (i32, v128) -> () 1381; CHECK-NEXT: # %bb.0: 1382; CHECK-NEXT: local.get 0 1383; CHECK-NEXT: local.get 1 1384; CHECK-NEXT: v128.store 0:p2align=0 1385; CHECK-NEXT: # fallthrough-return 1386 store <4 x float> %v, ptr %p, align 1 1387 ret void 1388} 1389 1390define void @store_v4f32_a4(ptr %p, <4 x float> %v) { 1391; CHECK-LABEL: store_v4f32_a4: 1392; CHECK: .functype store_v4f32_a4 (i32, v128) -> () 1393; CHECK-NEXT: # %bb.0: 1394; CHECK-NEXT: local.get 0 1395; CHECK-NEXT: local.get 1 1396; CHECK-NEXT: v128.store 0:p2align=2 1397; CHECK-NEXT: # fallthrough-return 1398 store <4 x float> %v, ptr %p, align 4 1399 ret void 1400} 1401 1402; 16 is the default alignment for v128 so no attribute is needed. 1403define void @store_v4f32_a16(ptr %p, <4 x float> %v) { 1404; CHECK-LABEL: store_v4f32_a16: 1405; CHECK: .functype store_v4f32_a16 (i32, v128) -> () 1406; CHECK-NEXT: # %bb.0: 1407; CHECK-NEXT: local.get 0 1408; CHECK-NEXT: local.get 1 1409; CHECK-NEXT: v128.store 0 1410; CHECK-NEXT: # fallthrough-return 1411 store <4 x float> %v, ptr %p, align 16 1412 ret void 1413} 1414 1415; 32 is greater than the default alignment so it is ignored. 1416define void @store_v4f32_a32(ptr %p, <4 x float> %v) { 1417; CHECK-LABEL: store_v4f32_a32: 1418; CHECK: .functype store_v4f32_a32 (i32, v128) -> () 1419; CHECK-NEXT: # %bb.0: 1420; CHECK-NEXT: local.get 0 1421; CHECK-NEXT: local.get 1 1422; CHECK-NEXT: v128.store 0 1423; CHECK-NEXT: # fallthrough-return 1424 store <4 x float> %v, ptr %p, align 32 1425 ret void 1426} 1427 1428; ============================================================================== 1429; 2 x double 1430; ============================================================================== 1431 1432define <2 x double> @load_v2f64_a1(ptr %p) { 1433; CHECK-LABEL: load_v2f64_a1: 1434; CHECK: .functype load_v2f64_a1 (i32) -> (v128) 1435; CHECK-NEXT: # %bb.0: 1436; CHECK-NEXT: local.get 0 1437; CHECK-NEXT: v128.load 0:p2align=0 1438; CHECK-NEXT: # fallthrough-return 1439 %v = load <2 x double>, ptr %p, align 1 1440 ret <2 x double> %v 1441} 1442 1443define <2 x double> @load_v2f64_a4(ptr %p) { 1444; CHECK-LABEL: load_v2f64_a4: 1445; CHECK: .functype load_v2f64_a4 (i32) -> (v128) 1446; CHECK-NEXT: # %bb.0: 1447; CHECK-NEXT: local.get 0 1448; CHECK-NEXT: v128.load 0:p2align=2 1449; CHECK-NEXT: # fallthrough-return 1450 %v = load <2 x double>, ptr %p, align 4 1451 ret <2 x double> %v 1452} 1453 1454; 2 is the default alignment for v128 so no attribute is needed. 1455define <2 x double> @load_v2f64_a16(ptr %p) { 1456; CHECK-LABEL: load_v2f64_a16: 1457; CHECK: .functype load_v2f64_a16 (i32) -> (v128) 1458; CHECK-NEXT: # %bb.0: 1459; CHECK-NEXT: local.get 0 1460; CHECK-NEXT: v128.load 0 1461; CHECK-NEXT: # fallthrough-return 1462 %v = load <2 x double>, ptr %p, align 16 1463 ret <2 x double> %v 1464} 1465 1466; 32 is greater than the default alignment so it is ignored. 1467define <2 x double> @load_v2f64_a32(ptr %p) { 1468; CHECK-LABEL: load_v2f64_a32: 1469; CHECK: .functype load_v2f64_a32 (i32) -> (v128) 1470; CHECK-NEXT: # %bb.0: 1471; CHECK-NEXT: local.get 0 1472; CHECK-NEXT: v128.load 0 1473; CHECK-NEXT: # fallthrough-return 1474 %v = load <2 x double>, ptr %p, align 32 1475 ret <2 x double> %v 1476} 1477 1478define void @store_v2f64_a1(ptr %p, <2 x double> %v) { 1479; CHECK-LABEL: store_v2f64_a1: 1480; CHECK: .functype store_v2f64_a1 (i32, v128) -> () 1481; CHECK-NEXT: # %bb.0: 1482; CHECK-NEXT: local.get 0 1483; CHECK-NEXT: local.get 1 1484; CHECK-NEXT: v128.store 0:p2align=0 1485; CHECK-NEXT: # fallthrough-return 1486 store <2 x double> %v, ptr %p, align 1 1487 ret void 1488} 1489 1490define void @store_v2f64_a4(ptr %p, <2 x double> %v) { 1491; CHECK-LABEL: store_v2f64_a4: 1492; CHECK: .functype store_v2f64_a4 (i32, v128) -> () 1493; CHECK-NEXT: # %bb.0: 1494; CHECK-NEXT: local.get 0 1495; CHECK-NEXT: local.get 1 1496; CHECK-NEXT: v128.store 0:p2align=2 1497; CHECK-NEXT: # fallthrough-return 1498 store <2 x double> %v, ptr %p, align 4 1499 ret void 1500} 1501 1502; 16 is the default alignment for v128 so no attribute is needed. 1503define void @store_v2f64_a16(ptr %p, <2 x double> %v) { 1504; CHECK-LABEL: store_v2f64_a16: 1505; CHECK: .functype store_v2f64_a16 (i32, v128) -> () 1506; CHECK-NEXT: # %bb.0: 1507; CHECK-NEXT: local.get 0 1508; CHECK-NEXT: local.get 1 1509; CHECK-NEXT: v128.store 0 1510; CHECK-NEXT: # fallthrough-return 1511 store <2 x double> %v, ptr %p, align 16 1512 ret void 1513} 1514 1515; 32 is greater than the default alignment so it is ignored. 1516define void @store_v2f64_a32(ptr %p, <2 x double> %v) { 1517; CHECK-LABEL: store_v2f64_a32: 1518; CHECK: .functype store_v2f64_a32 (i32, v128) -> () 1519; CHECK-NEXT: # %bb.0: 1520; CHECK-NEXT: local.get 0 1521; CHECK-NEXT: local.get 1 1522; CHECK-NEXT: v128.store 0 1523; CHECK-NEXT: # fallthrough-return 1524 store <2 x double> %v, ptr %p, align 32 1525 ret void 1526} 1527