1; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+unimplemented-simd128 | FileCheck %s 2 3; Test loads and stores with custom alignment values. 4 5target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 6target triple = "wasm32-unknown-unknown" 7 8; ============================================================================== 9; 16 x i8 10; ============================================================================== 11 12; CHECK-LABEL: load_v16i8_a1: 13; CHECK-NEXT: .functype load_v16i8_a1 (i32) -> (v128){{$}} 14; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}} 15; CHECK-NEXT: return $pop[[R]]{{$}} 16define <16 x i8> @load_v16i8_a1(<16 x i8> *%p) { 17 %v = load <16 x i8>, <16 x i8>* %p, align 1 18 ret <16 x i8> %v 19} 20 21; CHECK-LABEL: load_v16i8_a4: 22; CHECK-NEXT: .functype load_v16i8_a4 (i32) -> (v128){{$}} 23; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}} 24; CHECK-NEXT: return $pop[[R]]{{$}} 25define <16 x i8> @load_v16i8_a4(<16 x i8> *%p) { 26 %v = load <16 x i8>, <16 x i8>* %p, align 4 27 ret <16 x i8> %v 28} 29 30; 16 is the default alignment for v128 so no attribute is needed. 31 32; CHECK-LABEL: load_v16i8_a16: 33; CHECK-NEXT: .functype load_v16i8_a16 (i32) -> (v128){{$}} 34; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}} 35; CHECK-NEXT: return $pop[[R]]{{$}} 36define <16 x i8> @load_v16i8_a16(<16 x i8> *%p) { 37 %v = load <16 x i8>, <16 x i8>* %p, align 16 38 ret <16 x i8> %v 39} 40 41; 32 is greater than the default alignment so it is ignored. 42 43; CHECK-LABEL: load_v16i8_a32: 44; CHECK-NEXT: .functype load_v16i8_a32 (i32) -> (v128){{$}} 45; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}} 46; CHECK-NEXT: return $pop[[R]]{{$}} 47define <16 x i8> @load_v16i8_a32(<16 x i8> *%p) { 48 %v = load <16 x i8>, <16 x i8>* %p, align 32 49 ret <16 x i8> %v 50} 51 52; CHECK-LABEL: store_v16i8_a1: 53; CHECK-NEXT: .functype store_v16i8_a1 (i32, v128) -> (){{$}} 54; CHECK-NEXT: v128.store 0($0):p2align=0, $1{{$}} 55; CHECK-NEXT: return{{$}} 56define void @store_v16i8_a1(<16 x i8> *%p, <16 x i8> %v) { 57 store <16 x i8> %v, <16 x i8>* %p, align 1 58 ret void 59} 60 61; CHECK-LABEL: store_v16i8_a4: 62; CHECK-NEXT: .functype store_v16i8_a4 (i32, v128) -> (){{$}} 63; CHECK-NEXT: v128.store 0($0):p2align=2, $1{{$}} 64; CHECK-NEXT: return{{$}} 65define void @store_v16i8_a4(<16 x i8> *%p, <16 x i8> %v) { 66 store <16 x i8> %v, <16 x i8>* %p, align 4 67 ret void 68} 69 70; 16 is the default alignment for v128 so no attribute is needed. 71 72; CHECK-LABEL: store_v16i8_a16: 73; CHECK-NEXT: .functype store_v16i8_a16 (i32, v128) -> (){{$}} 74; CHECK-NEXT: v128.store 0($0), $1{{$}} 75; CHECK-NEXT: return{{$}} 76define void @store_v16i8_a16(<16 x i8> *%p, <16 x i8> %v) { 77 store <16 x i8> %v, <16 x i8>* %p, align 16 78 ret void 79} 80 81; 32 is greater than the default alignment so it is ignored. 82 83; CHECK-LABEL: store_v16i8_a32: 84; CHECK-NEXT: .functype store_v16i8_a32 (i32, v128) -> (){{$}} 85; CHECK-NEXT: v128.store 0($0), $1{{$}} 86; CHECK-NEXT: return{{$}} 87define void @store_v16i8_a32(<16 x i8> *%p, <16 x i8> %v) { 88 store <16 x i8> %v, <16 x i8>* %p, align 32 89 ret void 90} 91 92; 1 is the default alignment for v8x16.load_splat so no attribute is needed. 93 94; CHECK-LABEL: load_splat_v16i8_a1: 95; CHECK-NEXT: .functype load_splat_v16i8_a1 (i32) -> (v128){{$}} 96; CHECK-NEXT: v8x16.load_splat $push[[R:[0-9]+]]=, 0($0){{$}} 97; CHECK-NEXT: return $pop[[R]]{{$}} 98define <16 x i8> @load_splat_v16i8_a1(i8* %p) { 99 %e = load i8, i8* %p, align 1 100 %v1 = insertelement <16 x i8> undef, i8 %e, i32 0 101 %v2 = shufflevector <16 x i8> %v1, <16 x i8> undef, <16 x i32> zeroinitializer 102 ret <16 x i8> %v2 103} 104 105; 2 is greater than the default alignment so it is ignored. 106 107; CHECK-LABEL: load_splat_v16i8_a2: 108; CHECK-NEXT: .functype load_splat_v16i8_a2 (i32) -> (v128){{$}} 109; CHECK-NEXT: v8x16.load_splat $push[[R:[0-9]+]]=, 0($0){{$}} 110; CHECK-NEXT: return $pop[[R]]{{$}} 111define <16 x i8> @load_splat_v16i8_a2(i8* %p) { 112 %e = load i8, i8* %p, align 2 113 %v1 = insertelement <16 x i8> undef, i8 %e, i32 0 114 %v2 = shufflevector <16 x i8> %v1, <16 x i8> undef, <16 x i32> zeroinitializer 115 ret <16 x i8> %v2 116} 117 118; ============================================================================== 119; 8 x i16 120; ============================================================================== 121 122; CHECK-LABEL: load_v8i16_a1: 123; CHECK-NEXT: .functype load_v8i16_a1 (i32) -> (v128){{$}} 124; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}} 125; CHECK-NEXT: return $pop[[R]]{{$}} 126define <8 x i16> @load_v8i16_a1(<8 x i16> *%p) { 127 %v = load <8 x i16>, <8 x i16>* %p, align 1 128 ret <8 x i16> %v 129} 130 131; CHECK-LABEL: load_v8i16_a4: 132; CHECK-NEXT: .functype load_v8i16_a4 (i32) -> (v128){{$}} 133; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}} 134; CHECK-NEXT: return $pop[[R]]{{$}} 135define <8 x i16> @load_v8i16_a4(<8 x i16> *%p) { 136 %v = load <8 x i16>, <8 x i16>* %p, align 4 137 ret <8 x i16> %v 138} 139 140; 8 is the default alignment for v128 so no attribute is needed. 141 142; CHECK-LABEL: load_v8i16_a16: 143; CHECK-NEXT: .functype load_v8i16_a16 (i32) -> (v128){{$}} 144; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}} 145; CHECK-NEXT: return $pop[[R]]{{$}} 146define <8 x i16> @load_v8i16_a16(<8 x i16> *%p) { 147 %v = load <8 x i16>, <8 x i16>* %p, align 16 148 ret <8 x i16> %v 149} 150 151; 32 is greater than the default alignment so it is ignored. 152 153; CHECK-LABEL: load_v8i16_a32: 154; CHECK-NEXT: .functype load_v8i16_a32 (i32) -> (v128){{$}} 155; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}} 156; CHECK-NEXT: return $pop[[R]]{{$}} 157define <8 x i16> @load_v8i16_a32(<8 x i16> *%p) { 158 %v = load <8 x i16>, <8 x i16>* %p, align 32 159 ret <8 x i16> %v 160} 161 162; CHECK-LABEL: store_v8i16_a1: 163; CHECK-NEXT: .functype store_v8i16_a1 (i32, v128) -> (){{$}} 164; CHECK-NEXT: v128.store 0($0):p2align=0, $1{{$}} 165; CHECK-NEXT: return{{$}} 166define void @store_v8i16_a1(<8 x i16> *%p, <8 x i16> %v) { 167 store <8 x i16> %v, <8 x i16>* %p, align 1 168 ret void 169} 170 171; CHECK-LABEL: store_v8i16_a4: 172; CHECK-NEXT: .functype store_v8i16_a4 (i32, v128) -> (){{$}} 173; CHECK-NEXT: v128.store 0($0):p2align=2, $1{{$}} 174; CHECK-NEXT: return{{$}} 175define void @store_v8i16_a4(<8 x i16> *%p, <8 x i16> %v) { 176 store <8 x i16> %v, <8 x i16>* %p, align 4 177 ret void 178} 179 180; 16 is the default alignment for v128 so no attribute is needed. 181 182; CHECK-LABEL: store_v8i16_a16: 183; CHECK-NEXT: .functype store_v8i16_a16 (i32, v128) -> (){{$}} 184; CHECK-NEXT: v128.store 0($0), $1{{$}} 185; CHECK-NEXT: return{{$}} 186define void @store_v8i16_a16(<8 x i16> *%p, <8 x i16> %v) { 187 store <8 x i16> %v, <8 x i16>* %p, align 16 188 ret void 189} 190 191; 32 is greater than the default alignment so it is ignored. 192 193; CHECK-LABEL: store_v8i16_a32: 194; CHECK-NEXT: .functype store_v8i16_a32 (i32, v128) -> (){{$}} 195; CHECK-NEXT: v128.store 0($0), $1{{$}} 196; CHECK-NEXT: return{{$}} 197define void @store_v8i16_a32(<8 x i16> *%p, <8 x i16> %v) { 198 store <8 x i16> %v, <8 x i16>* %p, align 32 199 ret void 200} 201 202; CHECK-LABEL: load_ext_v8i16_a1: 203; CHECK-NEXT: .functype load_ext_v8i16_a1 (i32) -> (v128){{$}} 204; CHECK-NEXT: i16x8.load8x8_u $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}} 205; CHECK-NEXT: return $pop[[R]]{{$}} 206define <8 x i8> @load_ext_v8i16_a1(<8 x i8>* %p) { 207 %v = load <8 x i8>, <8 x i8>* %p, align 1 208 ret <8 x i8> %v 209} 210 211; CHECK-LABEL: load_ext_v8i16_a2: 212; CHECK-NEXT: .functype load_ext_v8i16_a2 (i32) -> (v128){{$}} 213; CHECK-NEXT: i16x8.load8x8_u $push[[R:[0-9]+]]=, 0($0):p2align=1{{$}} 214; CHECK-NEXT: return $pop[[R]]{{$}} 215define <8 x i8> @load_ext_v8i16_a2(<8 x i8>* %p) { 216 %v = load <8 x i8>, <8 x i8>* %p, align 2 217 ret <8 x i8> %v 218} 219 220; CHECK-LABEL: load_ext_v8i16_a4: 221; CHECK-NEXT: .functype load_ext_v8i16_a4 (i32) -> (v128){{$}} 222; CHECK-NEXT: i16x8.load8x8_u $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}} 223; CHECK-NEXT: return $pop[[R]]{{$}} 224define <8 x i8> @load_ext_v8i16_a4(<8 x i8>* %p) { 225 %v = load <8 x i8>, <8 x i8>* %p, align 4 226 ret <8 x i8> %v 227} 228 229; 8 is the default alignment for v128 extending load so no attribute is needed. 230 231; CHECK-LABEL: load_ext_v8i16_a8: 232; CHECK-NEXT: .functype load_ext_v8i16_a8 (i32) -> (v128){{$}} 233; CHECK-NEXT: i16x8.load8x8_u $push[[R:[0-9]+]]=, 0($0){{$}} 234; CHECK-NEXT: return $pop[[R]]{{$}} 235define <8 x i8> @load_ext_v8i16_a8(<8 x i8>* %p) { 236 %v = load <8 x i8>, <8 x i8>* %p, align 8 237 ret <8 x i8> %v 238} 239 240; 16 is greater than the default alignment so it is ignored. 241 242; CHECK-LABEL: load_ext_v8i16_a16: 243; CHECK-NEXT: .functype load_ext_v8i16_a16 (i32) -> (v128){{$}} 244; CHECK-NEXT: i16x8.load8x8_u $push[[R:[0-9]+]]=, 0($0){{$}} 245; CHECK-NEXT: return $pop[[R]]{{$}} 246define <8 x i8> @load_ext_v8i16_a16(<8 x i8>* %p) { 247 %v = load <8 x i8>, <8 x i8>* %p, align 16 248 ret <8 x i8> %v 249} 250 251; CHECK-LABEL: load_sext_v8i16_a1: 252; CHECK-NEXT: .functype load_sext_v8i16_a1 (i32) -> (v128){{$}} 253; CHECK-NEXT: i16x8.load8x8_s $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}} 254; CHECK-NEXT: return $pop[[R]]{{$}} 255define <8 x i16> @load_sext_v8i16_a1(<8 x i8>* %p) { 256 %v = load <8 x i8>, <8 x i8>* %p, align 1 257 %v2 = sext <8 x i8> %v to <8 x i16> 258 ret <8 x i16> %v2 259} 260 261; CHECK-LABEL: load_sext_v8i16_a2: 262; CHECK-NEXT: .functype load_sext_v8i16_a2 (i32) -> (v128){{$}} 263; CHECK-NEXT: i16x8.load8x8_s $push[[R:[0-9]+]]=, 0($0):p2align=1{{$}} 264; CHECK-NEXT: return $pop[[R]]{{$}} 265define <8 x i16> @load_sext_v8i16_a2(<8 x i8>* %p) { 266 %v = load <8 x i8>, <8 x i8>* %p, align 2 267 %v2 = sext <8 x i8> %v to <8 x i16> 268 ret <8 x i16> %v2 269} 270 271; CHECK-LABEL: load_sext_v8i16_a4: 272; CHECK-NEXT: .functype load_sext_v8i16_a4 (i32) -> (v128){{$}} 273; CHECK-NEXT: i16x8.load8x8_s $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}} 274; CHECK-NEXT: return $pop[[R]]{{$}} 275define <8 x i16> @load_sext_v8i16_a4(<8 x i8>* %p) { 276 %v = load <8 x i8>, <8 x i8>* %p, align 4 277 %v2 = sext <8 x i8> %v to <8 x i16> 278 ret <8 x i16> %v2 279} 280 281; 8 is the default alignment for v128 extending load so no attribute is needed. 282 283; CHECK-LABEL: load_sext_v8i16_a8: 284; CHECK-NEXT: .functype load_sext_v8i16_a8 (i32) -> (v128){{$}} 285; CHECK-NEXT: i16x8.load8x8_s $push[[R:[0-9]+]]=, 0($0){{$}} 286; CHECK-NEXT: return $pop[[R]]{{$}} 287define <8 x i16> @load_sext_v8i16_a8(<8 x i8>* %p) { 288 %v = load <8 x i8>, <8 x i8>* %p, align 8 289 %v2 = sext <8 x i8> %v to <8 x i16> 290 ret <8 x i16> %v2 291} 292 293; 16 is greater than the default alignment so it is ignored. 294 295; CHECK-LABEL: load_sext_v8i16_a16: 296; CHECK-NEXT: .functype load_sext_v8i16_a16 (i32) -> (v128){{$}} 297; CHECK-NEXT: i16x8.load8x8_s $push[[R:[0-9]+]]=, 0($0){{$}} 298; CHECK-NEXT: return $pop[[R]]{{$}} 299define <8 x i16> @load_sext_v8i16_a16(<8 x i8>* %p) { 300 %v = load <8 x i8>, <8 x i8>* %p, align 16 301 %v2 = sext <8 x i8> %v to <8 x i16> 302 ret <8 x i16> %v2 303} 304 305; CHECK-LABEL: load_splat_v8i16_a1: 306; CHECK-NEXT: .functype load_splat_v8i16_a1 (i32) -> (v128){{$}} 307; CHECK-NEXT: v16x8.load_splat $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}} 308; CHECK-NEXT: return $pop[[R]]{{$}} 309define <8 x i16> @load_splat_v8i16_a1(i16* %p) { 310 %e = load i16, i16* %p, align 1 311 %v1 = insertelement <8 x i16> undef, i16 %e, i32 0 312 %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer 313 ret <8 x i16> %v2 314} 315 316; 2 is the default alignment for v16x8.load_splat so no attribute is needed. 317 318; CHECK-LABEL: load_splat_v8i16_a2: 319; CHECK-NEXT: .functype load_splat_v8i16_a2 (i32) -> (v128){{$}} 320; CHECK-NEXT: v16x8.load_splat $push[[R:[0-9]+]]=, 0($0){{$}} 321; CHECK-NEXT: return $pop[[R]]{{$}} 322define <8 x i16> @load_splat_v8i16_a2(i16* %p) { 323 %e = load i16, i16* %p, align 2 324 %v1 = insertelement <8 x i16> undef, i16 %e, i32 0 325 %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer 326 ret <8 x i16> %v2 327} 328 329; 4 is greater than the default alignment so it is ignored. 330 331; CHECK-LABEL: load_splat_v8i16_a4: 332; CHECK-NEXT: .functype load_splat_v8i16_a4 (i32) -> (v128){{$}} 333; CHECK-NEXT: v16x8.load_splat $push[[R:[0-9]+]]=, 0($0){{$}} 334; CHECK-NEXT: return $pop[[R]]{{$}} 335define <8 x i16> @load_splat_v8i16_a4(i16* %p) { 336 %e = load i16, i16* %p, align 4 337 %v1 = insertelement <8 x i16> undef, i16 %e, i32 0 338 %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer 339 ret <8 x i16> %v2 340} 341 342; ============================================================================== 343; 4 x i32 344; ============================================================================== 345 346; CHECK-LABEL: load_v4i32_a1: 347; CHECK-NEXT: .functype load_v4i32_a1 (i32) -> (v128){{$}} 348; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}} 349; CHECK-NEXT: return $pop[[R]]{{$}} 350define <4 x i32> @load_v4i32_a1(<4 x i32> *%p) { 351 %v = load <4 x i32>, <4 x i32>* %p, align 1 352 ret <4 x i32> %v 353} 354 355; CHECK-LABEL: load_v4i32_a4: 356; CHECK-NEXT: .functype load_v4i32_a4 (i32) -> (v128){{$}} 357; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}} 358; CHECK-NEXT: return $pop[[R]]{{$}} 359define <4 x i32> @load_v4i32_a4(<4 x i32> *%p) { 360 %v = load <4 x i32>, <4 x i32>* %p, align 4 361 ret <4 x i32> %v 362} 363 364; 4 is the default alignment for v128 so no attribute is needed. 365 366; CHECK-LABEL: load_v4i32_a16: 367; CHECK-NEXT: .functype load_v4i32_a16 (i32) -> (v128){{$}} 368; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}} 369; CHECK-NEXT: return $pop[[R]]{{$}} 370define <4 x i32> @load_v4i32_a16(<4 x i32> *%p) { 371 %v = load <4 x i32>, <4 x i32>* %p, align 16 372 ret <4 x i32> %v 373} 374 375; 32 is greater than the default alignment so it is ignored. 376 377; CHECK-LABEL: load_v4i32_a32: 378; CHECK-NEXT: .functype load_v4i32_a32 (i32) -> (v128){{$}} 379; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}} 380; CHECK-NEXT: return $pop[[R]]{{$}} 381define <4 x i32> @load_v4i32_a32(<4 x i32> *%p) { 382 %v = load <4 x i32>, <4 x i32>* %p, align 32 383 ret <4 x i32> %v 384} 385 386; CHECK-LABEL: store_v4i32_a1: 387; CHECK-NEXT: .functype store_v4i32_a1 (i32, v128) -> (){{$}} 388; CHECK-NEXT: v128.store 0($0):p2align=0, $1{{$}} 389; CHECK-NEXT: return{{$}} 390define void @store_v4i32_a1(<4 x i32> *%p, <4 x i32> %v) { 391 store <4 x i32> %v, <4 x i32>* %p, align 1 392 ret void 393} 394 395; CHECK-LABEL: store_v4i32_a4: 396; CHECK-NEXT: .functype store_v4i32_a4 (i32, v128) -> (){{$}} 397; CHECK-NEXT: v128.store 0($0):p2align=2, $1{{$}} 398; CHECK-NEXT: return{{$}} 399define void @store_v4i32_a4(<4 x i32> *%p, <4 x i32> %v) { 400 store <4 x i32> %v, <4 x i32>* %p, align 4 401 ret void 402} 403 404; 16 is the default alignment for v128 so no attribute is needed. 405 406; CHECK-LABEL: store_v4i32_a16: 407; CHECK-NEXT: .functype store_v4i32_a16 (i32, v128) -> (){{$}} 408; CHECK-NEXT: v128.store 0($0), $1{{$}} 409; CHECK-NEXT: return{{$}} 410define void @store_v4i32_a16(<4 x i32> *%p, <4 x i32> %v) { 411 store <4 x i32> %v, <4 x i32>* %p, align 16 412 ret void 413} 414 415; 32 is greater than the default alignment so it is ignored. 416 417; CHECK-LABEL: store_v4i32_a32: 418; CHECK-NEXT: .functype store_v4i32_a32 (i32, v128) -> (){{$}} 419; CHECK-NEXT: v128.store 0($0), $1{{$}} 420; CHECK-NEXT: return{{$}} 421define void @store_v4i32_a32(<4 x i32> *%p, <4 x i32> %v) { 422 store <4 x i32> %v, <4 x i32>* %p, align 32 423 ret void 424} 425 426; CHECK-LABEL: load_ext_v4i32_a1: 427; CHECK-NEXT: .functype load_ext_v4i32_a1 (i32) -> (v128){{$}} 428; CHECK-NEXT: i32x4.load16x4_u $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}} 429; CHECK-NEXT: return $pop[[R]]{{$}} 430define <4 x i16> @load_ext_v4i32_a1(<4 x i16>* %p) { 431 %v = load <4 x i16>, <4 x i16>* %p, align 1 432 ret <4 x i16> %v 433} 434 435; CHECK-LABEL: load_ext_v4i32_a2: 436; CHECK-NEXT: .functype load_ext_v4i32_a2 (i32) -> (v128){{$}} 437; CHECK-NEXT: i32x4.load16x4_u $push[[R:[0-9]+]]=, 0($0):p2align=1{{$}} 438; CHECK-NEXT: return $pop[[R]]{{$}} 439define <4 x i16> @load_ext_v4i32_a2(<4 x i16>* %p) { 440 %v = load <4 x i16>, <4 x i16>* %p, align 2 441 ret <4 x i16> %v 442} 443 444; CHECK-LABEL: load_ext_v4i32_a4: 445; CHECK-NEXT: .functype load_ext_v4i32_a4 (i32) -> (v128){{$}} 446; CHECK-NEXT: i32x4.load16x4_u $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}} 447; CHECK-NEXT: return $pop[[R]]{{$}} 448define <4 x i16> @load_ext_v4i32_a4(<4 x i16>* %p) { 449 %v = load <4 x i16>, <4 x i16>* %p, align 4 450 ret <4 x i16> %v 451} 452 453; 8 is the default alignment for v128 extending load so no attribute is needed. 454 455; CHECK-LABEL: load_ext_v4i32_a8: 456; CHECK-NEXT: .functype load_ext_v4i32_a8 (i32) -> (v128){{$}} 457; CHECK-NEXT: i32x4.load16x4_u $push[[R:[0-9]+]]=, 0($0){{$}} 458; CHECK-NEXT: return $pop[[R]]{{$}} 459define <4 x i16> @load_ext_v4i32_a8(<4 x i16>* %p) { 460 %v = load <4 x i16>, <4 x i16>* %p, align 8 461 ret <4 x i16> %v 462} 463 464; 16 is greater than the default alignment so it is ignored. 465 466; CHECK-LABEL: load_ext_v4i32_a16: 467; CHECK-NEXT: .functype load_ext_v4i32_a16 (i32) -> (v128){{$}} 468; CHECK-NEXT: i32x4.load16x4_u $push[[R:[0-9]+]]=, 0($0){{$}} 469; CHECK-NEXT: return $pop[[R]]{{$}} 470define <4 x i16> @load_ext_v4i32_a16(<4 x i16>* %p) { 471 %v = load <4 x i16>, <4 x i16>* %p, align 16 472 ret <4 x i16> %v 473} 474 475; CHECK-LABEL: load_sext_v4i32_a1: 476; CHECK-NEXT: .functype load_sext_v4i32_a1 (i32) -> (v128){{$}} 477; CHECK-NEXT: i32x4.load16x4_s $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}} 478; CHECK-NEXT: return $pop[[R]]{{$}} 479define <4 x i32> @load_sext_v4i32_a1(<4 x i16>* %p) { 480 %v = load <4 x i16>, <4 x i16>* %p, align 1 481 %v2 = sext <4 x i16> %v to <4 x i32> 482 ret <4 x i32> %v2 483} 484 485; CHECK-LABEL: load_sext_v4i32_a2: 486; CHECK-NEXT: .functype load_sext_v4i32_a2 (i32) -> (v128){{$}} 487; CHECK-NEXT: i32x4.load16x4_s $push[[R:[0-9]+]]=, 0($0):p2align=1{{$}} 488; CHECK-NEXT: return $pop[[R]]{{$}} 489define <4 x i32> @load_sext_v4i32_a2(<4 x i16>* %p) { 490 %v = load <4 x i16>, <4 x i16>* %p, align 2 491 %v2 = sext <4 x i16> %v to <4 x i32> 492 ret <4 x i32> %v2 493} 494 495; CHECK-LABEL: load_sext_v4i32_a4: 496; CHECK-NEXT: .functype load_sext_v4i32_a4 (i32) -> (v128){{$}} 497; CHECK-NEXT: i32x4.load16x4_s $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}} 498; CHECK-NEXT: return $pop[[R]]{{$}} 499define <4 x i32> @load_sext_v4i32_a4(<4 x i16>* %p) { 500 %v = load <4 x i16>, <4 x i16>* %p, align 4 501 %v2 = sext <4 x i16> %v to <4 x i32> 502 ret <4 x i32> %v2 503} 504 505; 8 is the default alignment for v128 extending load so no attribute is needed. 506 507; CHECK-LABEL: load_sext_v4i32_a8: 508; CHECK-NEXT: .functype load_sext_v4i32_a8 (i32) -> (v128){{$}} 509; CHECK-NEXT: i32x4.load16x4_s $push[[R:[0-9]+]]=, 0($0){{$}} 510; CHECK-NEXT: return $pop[[R]]{{$}} 511define <4 x i32> @load_sext_v4i32_a8(<4 x i16>* %p) { 512 %v = load <4 x i16>, <4 x i16>* %p, align 8 513 %v2 = sext <4 x i16> %v to <4 x i32> 514 ret <4 x i32> %v2 515} 516 517; 16 is greater than the default alignment so it is ignored. 518 519; CHECK-LABEL: load_sext_v4i32_a16: 520; CHECK-NEXT: .functype load_sext_v4i32_a16 (i32) -> (v128){{$}} 521; CHECK-NEXT: i32x4.load16x4_s $push[[R:[0-9]+]]=, 0($0){{$}} 522; CHECK-NEXT: return $pop[[R]]{{$}} 523define <4 x i32> @load_sext_v4i32_a16(<4 x i16>* %p) { 524 %v = load <4 x i16>, <4 x i16>* %p, align 16 525 %v2 = sext <4 x i16> %v to <4 x i32> 526 ret <4 x i32> %v2 527} 528 529; CHECK-LABEL: load_splat_v4i32_a1: 530; CHECK-NEXT: .functype load_splat_v4i32_a1 (i32) -> (v128){{$}} 531; CHECK-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}} 532; CHECK-NEXT: return $pop[[R]]{{$}} 533define <4 x i32> @load_splat_v4i32_a1(i32* %addr) { 534 %e = load i32, i32* %addr, align 1 535 %v1 = insertelement <4 x i32> undef, i32 %e, i32 0 536 %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer 537 ret <4 x i32> %v2 538} 539 540; CHECK-LABEL: load_splat_v4i32_a2: 541; CHECK-NEXT: .functype load_splat_v4i32_a2 (i32) -> (v128){{$}} 542; CHECK-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 0($0):p2align=1{{$}} 543; CHECK-NEXT: return $pop[[R]]{{$}} 544define <4 x i32> @load_splat_v4i32_a2(i32* %addr) { 545 %e = load i32, i32* %addr, align 2 546 %v1 = insertelement <4 x i32> undef, i32 %e, i32 0 547 %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer 548 ret <4 x i32> %v2 549} 550 551; 4 is the default alignment for v32x4.load_splat so no attribute is needed. 552 553; CHECK-LABEL: load_splat_v4i32_a4: 554; CHECK-NEXT: .functype load_splat_v4i32_a4 (i32) -> (v128){{$}} 555; CHECK-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 0($0){{$}} 556; CHECK-NEXT: return $pop[[R]]{{$}} 557define <4 x i32> @load_splat_v4i32_a4(i32* %addr) { 558 %e = load i32, i32* %addr, align 4 559 %v1 = insertelement <4 x i32> undef, i32 %e, i32 0 560 %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer 561 ret <4 x i32> %v2 562} 563 564; 8 is greater than the default alignment so it is ignored. 565 566; CHECK-LABEL: load_splat_v4i32_a8: 567; CHECK-NEXT: .functype load_splat_v4i32_a8 (i32) -> (v128){{$}} 568; CHECK-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 0($0){{$}} 569; CHECK-NEXT: return $pop[[R]]{{$}} 570define <4 x i32> @load_splat_v4i32_a8(i32* %addr) { 571 %e = load i32, i32* %addr, align 8 572 %v1 = insertelement <4 x i32> undef, i32 %e, i32 0 573 %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer 574 ret <4 x i32> %v2 575} 576 577; ============================================================================== 578; 2 x i64 579; ============================================================================== 580 581; CHECK-LABEL: load_v2i64_a1: 582; CHECK-NEXT: .functype load_v2i64_a1 (i32) -> (v128){{$}} 583; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}} 584; CHECK-NEXT: return $pop[[R]]{{$}} 585define <2 x i64> @load_v2i64_a1(<2 x i64> *%p) { 586 %v = load <2 x i64>, <2 x i64>* %p, align 1 587 ret <2 x i64> %v 588} 589 590; CHECK-LABEL: load_v2i64_a4: 591; CHECK-NEXT: .functype load_v2i64_a4 (i32) -> (v128){{$}} 592; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}} 593; CHECK-NEXT: return $pop[[R]]{{$}} 594define <2 x i64> @load_v2i64_a4(<2 x i64> *%p) { 595 %v = load <2 x i64>, <2 x i64>* %p, align 4 596 ret <2 x i64> %v 597} 598 599; 2 is the default alignment for v128 so no attribute is needed. 600 601; CHECK-LABEL: load_v2i64_a16: 602; CHECK-NEXT: .functype load_v2i64_a16 (i32) -> (v128){{$}} 603; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}} 604; CHECK-NEXT: return $pop[[R]]{{$}} 605define <2 x i64> @load_v2i64_a16(<2 x i64> *%p) { 606 %v = load <2 x i64>, <2 x i64>* %p, align 16 607 ret <2 x i64> %v 608} 609 610; 32 is greater than the default alignment so it is ignored. 611 612; CHECK-LABEL: load_v2i64_a32: 613; CHECK-NEXT: .functype load_v2i64_a32 (i32) -> (v128){{$}} 614; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}} 615; CHECK-NEXT: return $pop[[R]]{{$}} 616define <2 x i64> @load_v2i64_a32(<2 x i64> *%p) { 617 %v = load <2 x i64>, <2 x i64>* %p, align 32 618 ret <2 x i64> %v 619} 620 621; CHECK-LABEL: store_v2i64_a1: 622; CHECK-NEXT: .functype store_v2i64_a1 (i32, v128) -> (){{$}} 623; CHECK-NEXT: v128.store 0($0):p2align=0, $1{{$}} 624; CHECK-NEXT: return{{$}} 625define void @store_v2i64_a1(<2 x i64> *%p, <2 x i64> %v) { 626 store <2 x i64> %v, <2 x i64>* %p, align 1 627 ret void 628} 629 630; CHECK-LABEL: store_v2i64_a4: 631; CHECK-NEXT: .functype store_v2i64_a4 (i32, v128) -> (){{$}} 632; CHECK-NEXT: v128.store 0($0):p2align=2, $1{{$}} 633; CHECK-NEXT: return{{$}} 634define void @store_v2i64_a4(<2 x i64> *%p, <2 x i64> %v) { 635 store <2 x i64> %v, <2 x i64>* %p, align 4 636 ret void 637} 638 639; 16 is the default alignment for v128 so no attribute is needed. 640 641; CHECK-LABEL: store_v2i64_a16: 642; CHECK-NEXT: .functype store_v2i64_a16 (i32, v128) -> (){{$}} 643; CHECK-NEXT: v128.store 0($0), $1{{$}} 644; CHECK-NEXT: return{{$}} 645define void @store_v2i64_a16(<2 x i64> *%p, <2 x i64> %v) { 646 store <2 x i64> %v, <2 x i64>* %p, align 16 647 ret void 648} 649 650; 32 is greater than the default alignment so it is ignored. 651 652; CHECK-LABEL: store_v2i64_a32: 653; CHECK-NEXT: .functype store_v2i64_a32 (i32, v128) -> (){{$}} 654; CHECK-NEXT: v128.store 0($0), $1{{$}} 655; CHECK-NEXT: return{{$}} 656define void @store_v2i64_a32(<2 x i64> *%p, <2 x i64> %v) { 657 store <2 x i64> %v, <2 x i64>* %p, align 32 658 ret void 659} 660 661; CHECK-LABEL: load_splat_v2i64_a1: 662; CHECK-NEXT: .functype load_splat_v2i64_a1 (i32) -> (v128){{$}} 663; CHECK-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}} 664; CHECK-NEXT: return $pop[[R]]{{$}} 665define <2 x i64> @load_splat_v2i64_a1(i64* %p) { 666 %e = load i64, i64* %p, align 1 667 %v1 = insertelement <2 x i64> undef, i64 %e, i32 0 668 %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer 669 ret <2 x i64> %v2 670} 671 672; CHECK-LABEL: load_splat_v2i64_a2: 673; CHECK-NEXT: .functype load_splat_v2i64_a2 (i32) -> (v128){{$}} 674; CHECK-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 0($0):p2align=1{{$}} 675; CHECK-NEXT: return $pop[[R]]{{$}} 676define <2 x i64> @load_splat_v2i64_a2(i64* %p) { 677 %e = load i64, i64* %p, align 2 678 %v1 = insertelement <2 x i64> undef, i64 %e, i32 0 679 %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer 680 ret <2 x i64> %v2 681} 682 683; CHECK-LABEL: load_splat_v2i64_a4: 684; CHECK-NEXT: .functype load_splat_v2i64_a4 (i32) -> (v128){{$}} 685; CHECK-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}} 686; CHECK-NEXT: return $pop[[R]]{{$}} 687define <2 x i64> @load_splat_v2i64_a4(i64* %p) { 688 %e = load i64, i64* %p, align 4 689 %v1 = insertelement <2 x i64> undef, i64 %e, i32 0 690 %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer 691 ret <2 x i64> %v2 692} 693 694; 8 is the default alignment for v64x2.load_splat so no attribute is needed. 695 696; CHECK-LABEL: load_splat_v2i64_a8: 697; CHECK-NEXT: .functype load_splat_v2i64_a8 (i32) -> (v128){{$}} 698; CHECK-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 0($0){{$}} 699; CHECK-NEXT: return $pop[[R]]{{$}} 700define <2 x i64> @load_splat_v2i64_a8(i64* %p) { 701 %e = load i64, i64* %p, align 8 702 %v1 = insertelement <2 x i64> undef, i64 %e, i32 0 703 %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer 704 ret <2 x i64> %v2 705} 706 707; 16 is greater than the default alignment so it is ignored. 708 709; CHECK-LABEL: load_splat_v2i64_a16: 710; CHECK-NEXT: .functype load_splat_v2i64_a16 (i32) -> (v128){{$}} 711; CHECK-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 0($0){{$}} 712; CHECK-NEXT: return $pop[[R]]{{$}} 713define <2 x i64> @load_splat_v2i64_a16(i64* %p) { 714 %e = load i64, i64* %p, align 16 715 %v1 = insertelement <2 x i64> undef, i64 %e, i32 0 716 %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer 717 ret <2 x i64> %v2 718} 719 720; ============================================================================== 721; 4 x float 722; ============================================================================== 723 724; CHECK-LABEL: load_v4f32_a1: 725; CHECK-NEXT: .functype load_v4f32_a1 (i32) -> (v128){{$}} 726; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}} 727; CHECK-NEXT: return $pop[[R]]{{$}} 728define <4 x float> @load_v4f32_a1(<4 x float> *%p) { 729 %v = load <4 x float>, <4 x float>* %p, align 1 730 ret <4 x float> %v 731} 732 733; CHECK-LABEL: load_v4f32_a4: 734; CHECK-NEXT: .functype load_v4f32_a4 (i32) -> (v128){{$}} 735; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}} 736; CHECK-NEXT: return $pop[[R]]{{$}} 737define <4 x float> @load_v4f32_a4(<4 x float> *%p) { 738 %v = load <4 x float>, <4 x float>* %p, align 4 739 ret <4 x float> %v 740} 741 742; 4 is the default alignment for v128 so no attribute is needed. 743 744; CHECK-LABEL: load_v4f32_a16: 745; CHECK-NEXT: .functype load_v4f32_a16 (i32) -> (v128){{$}} 746; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}} 747; CHECK-NEXT: return $pop[[R]]{{$}} 748define <4 x float> @load_v4f32_a16(<4 x float> *%p) { 749 %v = load <4 x float>, <4 x float>* %p, align 16 750 ret <4 x float> %v 751} 752 753; 32 is greater than the default alignment so it is ignored. 754 755; CHECK-LABEL: load_v4f32_a32: 756; CHECK-NEXT: .functype load_v4f32_a32 (i32) -> (v128){{$}} 757; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}} 758; CHECK-NEXT: return $pop[[R]]{{$}} 759define <4 x float> @load_v4f32_a32(<4 x float> *%p) { 760 %v = load <4 x float>, <4 x float>* %p, align 32 761 ret <4 x float> %v 762} 763 764; CHECK-LABEL: store_v4f32_a1: 765; CHECK-NEXT: .functype store_v4f32_a1 (i32, v128) -> (){{$}} 766; CHECK-NEXT: v128.store 0($0):p2align=0, $1{{$}} 767; CHECK-NEXT: return{{$}} 768define void @store_v4f32_a1(<4 x float> *%p, <4 x float> %v) { 769 store <4 x float> %v, <4 x float>* %p, align 1 770 ret void 771} 772 773; CHECK-LABEL: store_v4f32_a4: 774; CHECK-NEXT: .functype store_v4f32_a4 (i32, v128) -> (){{$}} 775; CHECK-NEXT: v128.store 0($0):p2align=2, $1{{$}} 776; CHECK-NEXT: return{{$}} 777define void @store_v4f32_a4(<4 x float> *%p, <4 x float> %v) { 778 store <4 x float> %v, <4 x float>* %p, align 4 779 ret void 780} 781 782; 16 is the default alignment for v128 so no attribute is needed. 783 784; CHECK-LABEL: store_v4f32_a16: 785; CHECK-NEXT: .functype store_v4f32_a16 (i32, v128) -> (){{$}} 786; CHECK-NEXT: v128.store 0($0), $1{{$}} 787; CHECK-NEXT: return{{$}} 788define void @store_v4f32_a16(<4 x float> *%p, <4 x float> %v) { 789 store <4 x float> %v, <4 x float>* %p, align 16 790 ret void 791} 792 793; 32 is greater than the default alignment so it is ignored. 794 795; CHECK-LABEL: store_v4f32_a32: 796; CHECK-NEXT: .functype store_v4f32_a32 (i32, v128) -> (){{$}} 797; CHECK-NEXT: v128.store 0($0), $1{{$}} 798; CHECK-NEXT: return{{$}} 799define void @store_v4f32_a32(<4 x float> *%p, <4 x float> %v) { 800 store <4 x float> %v, <4 x float>* %p, align 32 801 ret void 802} 803 804; ============================================================================== 805; 2 x double 806; ============================================================================== 807 808; CHECK-LABEL: load_v2f64_a1: 809; CHECK-NEXT: .functype load_v2f64_a1 (i32) -> (v128){{$}} 810; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}} 811; CHECK-NEXT: return $pop[[R]]{{$}} 812define <2 x double> @load_v2f64_a1(<2 x double> *%p) { 813 %v = load <2 x double>, <2 x double>* %p, align 1 814 ret <2 x double> %v 815} 816 817; CHECK-LABEL: load_v2f64_a4: 818; CHECK-NEXT: .functype load_v2f64_a4 (i32) -> (v128){{$}} 819; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}} 820; CHECK-NEXT: return $pop[[R]]{{$}} 821define <2 x double> @load_v2f64_a4(<2 x double> *%p) { 822 %v = load <2 x double>, <2 x double>* %p, align 4 823 ret <2 x double> %v 824} 825 826; 2 is the default alignment for v128 so no attribute is needed. 827 828; CHECK-LABEL: load_v2f64_a16: 829; CHECK-NEXT: .functype load_v2f64_a16 (i32) -> (v128){{$}} 830; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}} 831; CHECK-NEXT: return $pop[[R]]{{$}} 832define <2 x double> @load_v2f64_a16(<2 x double> *%p) { 833 %v = load <2 x double>, <2 x double>* %p, align 16 834 ret <2 x double> %v 835} 836 837; 32 is greater than the default alignment so it is ignored. 838 839; CHECK-LABEL: load_v2f64_a32: 840; CHECK-NEXT: .functype load_v2f64_a32 (i32) -> (v128){{$}} 841; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}} 842; CHECK-NEXT: return $pop[[R]]{{$}} 843define <2 x double> @load_v2f64_a32(<2 x double> *%p) { 844 %v = load <2 x double>, <2 x double>* %p, align 32 845 ret <2 x double> %v 846} 847 848; CHECK-LABEL: store_v2f64_a1: 849; CHECK-NEXT: .functype store_v2f64_a1 (i32, v128) -> (){{$}} 850; CHECK-NEXT: v128.store 0($0):p2align=0, $1{{$}} 851; CHECK-NEXT: return{{$}} 852define void @store_v2f64_a1(<2 x double> *%p, <2 x double> %v) { 853 store <2 x double> %v, <2 x double>* %p, align 1 854 ret void 855} 856 857; CHECK-LABEL: store_v2f64_a4: 858; CHECK-NEXT: .functype store_v2f64_a4 (i32, v128) -> (){{$}} 859; CHECK-NEXT: v128.store 0($0):p2align=2, $1{{$}} 860; CHECK-NEXT: return{{$}} 861define void @store_v2f64_a4(<2 x double> *%p, <2 x double> %v) { 862 store <2 x double> %v, <2 x double>* %p, align 4 863 ret void 864} 865 866; 16 is the default alignment for v128 so no attribute is needed. 867 868; CHECK-LABEL: store_v2f64_a16: 869; CHECK-NEXT: .functype store_v2f64_a16 (i32, v128) -> (){{$}} 870; CHECK-NEXT: v128.store 0($0), $1{{$}} 871; CHECK-NEXT: return{{$}} 872define void @store_v2f64_a16(<2 x double> *%p, <2 x double> %v) { 873 store <2 x double> %v, <2 x double>* %p, align 16 874 ret void 875} 876 877; 32 is greater than the default alignment so it is ignored. 878 879; CHECK-LABEL: store_v2f64_a32: 880; CHECK-NEXT: .functype store_v2f64_a32 (i32, v128) -> (){{$}} 881; CHECK-NEXT: v128.store 0($0), $1{{$}} 882; CHECK-NEXT: return{{$}} 883define void @store_v2f64_a32(<2 x double> *%p, <2 x double> %v) { 884 store <2 x double> %v, <2 x double>* %p, align 32 885 ret void 886} 887