[llvm] r372655 - [WebAssembly] vNxM.load_splat instructions

Thomas Lively via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 23 13:42:12 PDT 2019


Author: tlively
Date: Mon Sep 23 13:42:12 2019
New Revision: 372655

URL: http://llvm.org/viewvc/llvm-project?rev=372655&view=rev
Log:
[WebAssembly] vNxM.load_splat instructions

Summary:
Adds the new load_splat instructions as specified at
https://github.com/WebAssembly/simd/blob/master/proposals/simd/SIMD.md#load-and-splat.

DAGISel does not allow matching multiple copies of the same load in a
single pattern, so we use a new node in WebAssemblyISD to wrap loads
that should be splatted.

Depends on D67783.

Reviewers: aheejin

Subscribers: dschuff, sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D67784

Modified:
    llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
    llvm/trunk/test/CodeGen/WebAssembly/simd-offset.ll
    llvm/trunk/test/MC/WebAssembly/simd-encodings.s

Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h?rev=372655&r1=372654&r2=372655&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h Mon Sep 23 13:42:12 2019
@@ -191,6 +191,8 @@ inline unsigned GetDefaultP2AlignAny(uns
   case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I32_S:
   case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I64:
   case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I64_S:
+  case WebAssembly::LOAD_SPLAT_v8x16:
+  case WebAssembly::LOAD_SPLAT_v8x16_S:
     return 0;
   case WebAssembly::LOAD16_S_I32:
   case WebAssembly::LOAD16_S_I32_S:
@@ -240,6 +242,8 @@ inline unsigned GetDefaultP2AlignAny(uns
   case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I32_S:
   case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I64:
   case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I64_S:
+  case WebAssembly::LOAD_SPLAT_v16x8:
+  case WebAssembly::LOAD_SPLAT_v16x8_S:
     return 1;
   case WebAssembly::LOAD_I32:
   case WebAssembly::LOAD_I32_S:
@@ -295,6 +299,8 @@ inline unsigned GetDefaultP2AlignAny(uns
   case WebAssembly::ATOMIC_NOTIFY_S:
   case WebAssembly::ATOMIC_WAIT_I32:
   case WebAssembly::ATOMIC_WAIT_I32_S:
+  case WebAssembly::LOAD_SPLAT_v32x4:
+  case WebAssembly::LOAD_SPLAT_v32x4_S:
     return 2;
   case WebAssembly::LOAD_I64:
   case WebAssembly::LOAD_I64_S:
@@ -324,6 +330,8 @@ inline unsigned GetDefaultP2AlignAny(uns
   case WebAssembly::ATOMIC_RMW_CMPXCHG_I64_S:
   case WebAssembly::ATOMIC_WAIT_I64:
   case WebAssembly::ATOMIC_WAIT_I64_S:
+  case WebAssembly::LOAD_SPLAT_v64x2:
+  case WebAssembly::LOAD_SPLAT_v64x2_S:
     return 3;
   case WebAssembly::LOAD_v16i8:
   case WebAssembly::LOAD_v16i8_S:

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def?rev=372655&r1=372654&r2=372655&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def Mon Sep 23 13:42:12 2019
@@ -29,6 +29,7 @@ HANDLE_NODETYPE(SHUFFLE)
 HANDLE_NODETYPE(VEC_SHL)
 HANDLE_NODETYPE(VEC_SHR_S)
 HANDLE_NODETYPE(VEC_SHR_U)
+HANDLE_NODETYPE(LOAD_SPLAT)
 HANDLE_NODETYPE(THROW)
 HANDLE_NODETYPE(MEMORY_COPY)
 HANDLE_NODETYPE(MEMORY_FILL)

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp?rev=372655&r1=372654&r2=372655&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp Mon Sep 23 13:42:12 2019
@@ -1358,7 +1358,16 @@ SDValue WebAssemblyTargetLowering::Lower
     }
   }
   // Use a splat for the initial vector
-  SDValue Result = DAG.getSplatBuildVector(VecT, DL, SplatValue);
+  SDValue Result;
+  // Possibly a load_splat
+  LoadSDNode *SplattedLoad;
+  if (Subtarget->hasUnimplementedSIMD128() &&
+      (SplattedLoad = dyn_cast<LoadSDNode>(SplatValue)) &&
+      SplattedLoad->getMemoryVT() == VecT.getVectorElementType()) {
+    Result = DAG.getNode(WebAssemblyISD::LOAD_SPLAT, DL, VecT, SplatValue);
+  } else {
+    Result = DAG.getSplatBuildVector(VecT, DL, SplatValue);
+  }
   // Add replace_lane instructions for other values
   for (size_t I = 0; I < Lanes; ++I) {
     const SDValue &Lane = Op->getOperand(I);

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td?rev=372655&r1=372654&r2=372655&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td Mon Sep 23 13:42:12 2019
@@ -60,6 +60,54 @@ def : LoadPatOffsetOnly<vec_t, load, !ca
 def : LoadPatGlobalAddrOffOnly<vec_t, load, !cast<NI>("LOAD_"#vec_t)>;
 }
 
+// vNxM.load_splat
+multiclass SIMDLoadSplat<string vec, bits<32> simdop> {
+  let mayLoad = 1, UseNamedOperandTable = 1,
+      Predicates = [HasUnimplementedSIMD128] in
+  defm LOAD_SPLAT_#vec :
+    SIMD_I<(outs V128:$dst), (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
+           (outs), (ins P2Align:$p2align, offset32_op:$off), [],
+           vec#".load_splat\t$dst, ${off}(${addr})$p2align",
+           vec#".load_splat\t$off$p2align", simdop>;
+}
+
+defm "" : SIMDLoadSplat<"v8x16", 194>;
+defm "" : SIMDLoadSplat<"v16x8", 195>;
+defm "" : SIMDLoadSplat<"v32x4", 196>;
+defm "" : SIMDLoadSplat<"v64x2", 197>;
+
+def wasm_load_splat_t : SDTypeProfile<1, 1, []>;
+def wasm_load_splat : SDNode<"WebAssemblyISD::LOAD_SPLAT", wasm_load_splat_t>;
+
+foreach args = [["v16i8", "i32", "extloadi8"], ["v8i16", "i32", "extloadi16"],
+                ["v4i32", "i32", "load"], ["v2i64", "i64", "load"],
+                ["v4f32", "f32", "load"], ["v2f64", "f64", "load"]] in
+def load_splat_#args[0] :
+  PatFrag<(ops node:$addr), (wasm_load_splat
+            (!cast<ValueType>(args[1]) (!cast<PatFrag>(args[2]) node:$addr)))>;
+
+let Predicates = [HasUnimplementedSIMD128] in
+foreach args = [["v16i8", "v8x16"], ["v8i16", "v16x8"], ["v4i32", "v32x4"],
+                ["v2i64", "v64x2"], ["v4f32", "v32x4"], ["v2f64", "v64x2"]] in {
+def : LoadPatNoOffset<!cast<ValueType>(args[0]),
+                      !cast<PatFrag>("load_splat_"#args[0]),
+                      !cast<NI>("LOAD_SPLAT_"#args[1])>;
+def : LoadPatImmOff<!cast<ValueType>(args[0]),
+                    !cast<PatFrag>("load_splat_"#args[0]),
+                    regPlusImm,
+                    !cast<NI>("LOAD_SPLAT_"#args[1])>;
+def : LoadPatImmOff<!cast<ValueType>(args[0]),
+                    !cast<PatFrag>("load_splat_"#args[0]),
+                    or_is_add,
+                    !cast<NI>("LOAD_SPLAT_"#args[1])>;
+def : LoadPatOffsetOnly<!cast<ValueType>(args[0]),
+                        !cast<PatFrag>("load_splat_"#args[0]),
+                        !cast<NI>("LOAD_SPLAT_"#args[1])>;
+def : LoadPatGlobalAddrOffOnly<!cast<ValueType>(args[0]),
+                               !cast<PatFrag>("load_splat_"#args[0]),
+                               !cast<NI>("LOAD_SPLAT_"#args[1])>;
+}
+
 // Store: v128.store
 multiclass SIMDStore<ValueType vec_t> {
   let mayStore = 1, UseNamedOperandTable = 1 in

Modified: llvm/trunk/test/CodeGen/WebAssembly/simd-offset.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/simd-offset.ll?rev=372655&r1=372654&r2=372655&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/simd-offset.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/simd-offset.ll Mon Sep 23 13:42:12 2019
@@ -20,6 +20,19 @@ define <16 x i8> @load_v16i8(<16 x i8>*
   ret <16 x i8> %v
 }
 
+; CHECK-LABEL: load_splat_v16i8:
+; SIMD128-VM-NOT: v8x16.load_splat
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v16i8 (i32) -> (v128){{$}}
+; SIMD128-NEXT: v8x16.load_splat $push[[R:[0-9]+]]=, 0($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <16 x i8> @load_splat_v16i8(i8* %p) {
+  %e = load i8, i8* %p
+  %v1 = insertelement <16 x i8> undef, i8 %e, i32 0
+  %v2 = shufflevector <16 x i8> %v1, <16 x i8> undef, <16 x i32> zeroinitializer
+  ret <16 x i8> %v2
+}
+
 ; CHECK-LABEL: load_v16i8_with_folded_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v16i8_with_folded_offset (i32) -> (v128){{$}}
@@ -33,6 +46,21 @@ define <16 x i8> @load_v16i8_with_folded
   ret <16 x i8> %v
 }
 
+; CHECK-LABEL: load_splat_v16i8_with_folded_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v16i8_with_folded_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: v8x16.load_splat $push[[R:[0-9]+]]=, 16($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <16 x i8> @load_splat_v16i8_with_folded_offset(i8* %p) {
+  %q = ptrtoint i8* %p to i32
+  %r = add nuw i32 %q, 16
+  %s = inttoptr i32 %r to i8*
+  %e = load i8, i8* %s
+  %v1 = insertelement <16 x i8> undef, i8 %e, i32 0
+  %v2 = shufflevector <16 x i8> %v1, <16 x i8> undef, <16 x i32> zeroinitializer
+  ret <16 x i8> %v2
+}
+
 ; CHECK-LABEL: load_v16i8_with_folded_gep_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v16i8_with_folded_gep_offset (i32) -> (v128){{$}}
@@ -44,6 +72,19 @@ define <16 x i8> @load_v16i8_with_folded
   ret <16 x i8> %v
 }
 
+; CHECK-LABEL: load_splat_v16i8_with_folded_gep_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v16i8_with_folded_gep_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: v8x16.load_splat $push[[R:[0-9]+]]=, 1($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <16 x i8> @load_splat_v16i8_with_folded_gep_offset(i8* %p) {
+  %s = getelementptr inbounds i8, i8* %p, i32 1
+  %e = load i8, i8* %s
+  %v1 = insertelement <16 x i8> undef, i8 %e, i32 0
+  %v2 = shufflevector <16 x i8> %v1, <16 x i8> undef, <16 x i32> zeroinitializer
+  ret <16 x i8> %v2
+}
+
 ; CHECK-LABEL: load_v16i8_with_unfolded_gep_negative_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v16i8_with_unfolded_gep_negative_offset (i32) -> (v128){{$}}
@@ -57,6 +98,21 @@ define <16 x i8> @load_v16i8_with_unfold
   ret <16 x i8> %v
 }
 
+; CHECK-LABEL: load_splat_v16i8_with_unfolded_gep_negative_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v16i8_with_unfolded_gep_negative_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, -1{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v8x16.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <16 x i8> @load_splat_v16i8_with_unfolded_gep_negative_offset(i8* %p) {
+  %s = getelementptr inbounds i8, i8* %p, i32 -1
+  %e = load i8, i8* %s
+  %v1 = insertelement <16 x i8> undef, i8 %e, i32 0
+  %v2 = shufflevector <16 x i8> %v1, <16 x i8> undef, <16 x i32> zeroinitializer
+  ret <16 x i8> %v2
+}
+
 ; CHECK-LABEL: load_v16i8_with_unfolded_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v16i8_with_unfolded_offset (i32) -> (v128){{$}}
@@ -72,6 +128,23 @@ define <16 x i8> @load_v16i8_with_unfold
   ret <16 x i8> %v
 }
 
+; CHECK-LABEL: load_splat_v16i8_with_unfolded_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v16i8_with_unfolded_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 16{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v8x16.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <16 x i8> @load_splat_v16i8_with_unfolded_offset(i8* %p) {
+  %q = ptrtoint i8* %p to i32
+  %r = add nsw i32 %q, 16
+  %s = inttoptr i32 %r to i8*
+  %e = load i8, i8* %s
+  %v1 = insertelement <16 x i8> undef, i8 %e, i32 0
+  %v2 = shufflevector <16 x i8> %v1, <16 x i8> undef, <16 x i32> zeroinitializer
+  ret <16 x i8> %v2
+}
+
 ; CHECK-LABEL: load_v16i8_with_unfolded_gep_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v16i8_with_unfolded_gep_offset (i32) -> (v128){{$}}
@@ -85,6 +158,21 @@ define <16 x i8> @load_v16i8_with_unfold
   ret <16 x i8> %v
 }
 
+; CHECK-LABEL: load_splat_v16i8_with_unfolded_gep_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v16i8_with_unfolded_gep_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 1{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v8x16.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <16 x i8> @load_splat_v16i8_with_unfolded_gep_offset(i8* %p) {
+  %s = getelementptr i8, i8* %p, i32 1
+  %e = load i8, i8* %s
+  %v1 = insertelement <16 x i8> undef, i8 %e, i32 0
+  %v2 = shufflevector <16 x i8> %v1, <16 x i8> undef, <16 x i32> zeroinitializer
+  ret <16 x i8> %v2
+}
+
 ; CHECK-LABEL: load_v16i8_from_numeric_address:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v16i8_from_numeric_address () -> (v128){{$}}
@@ -97,6 +185,20 @@ define <16 x i8> @load_v16i8_from_numeri
   ret <16 x i8> %v
 }
 
+; CHECK-LABEL: load_splat_v16i8_from_numeric_address:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v16i8_from_numeric_address () -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
+; SIMD128-NEXT: v8x16.load_splat $push[[R:[0-9]+]]=, 32($pop[[L0]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <16 x i8> @load_splat_v16i8_from_numeric_address() {
+  %s = inttoptr i32 32 to i8*
+  %e = load i8, i8* %s
+  %v1 = insertelement <16 x i8> undef, i8 %e, i32 0
+  %v2 = shufflevector <16 x i8> %v1, <16 x i8> undef, <16 x i32> zeroinitializer
+  ret <16 x i8> %v2
+}
+
 ; CHECK-LABEL: load_v16i8_from_global_address:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v16i8_from_global_address () -> (v128){{$}}
@@ -109,6 +211,20 @@ define <16 x i8> @load_v16i8_from_global
   ret <16 x i8> %v
 }
 
+; CHECK-LABEL: load_splat_v16i8_from_global_address:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v16i8_from_global_address () -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
+; SIMD128-NEXT: v8x16.load_splat $push[[R:[0-9]+]]=, gv_i8($pop[[L0]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+ at gv_i8 = global i8 42
+define <16 x i8> @load_splat_v16i8_from_global_address() {
+  %e = load i8, i8* @gv_i8
+  %v1 = insertelement <16 x i8> undef, i8 %e, i32 0
+  %v2 = shufflevector <16 x i8> %v1, <16 x i8> undef, <16 x i32> zeroinitializer
+  ret <16 x i8> %v2
+}
+
 ; CHECK-LABEL: store_v16i8:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype store_v16i8 (v128, i32) -> (){{$}}
@@ -210,6 +326,18 @@ define <8 x i16> @load_v8i16(<8 x i16>*
   ret <8 x i16> %v
 }
 
+; CHECK-LABEL: load_splat_v8i16:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v8i16 (i32) -> (v128){{$}}
+; SIMD128-NEXT: v16x8.load_splat $push[[R:[0-9]+]]=, 0($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <8 x i16> @load_splat_v8i16(i16* %p) {
+  %e = load i16, i16* %p
+  %v1 = insertelement <8 x i16> undef, i16 %e, i32 0
+  %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer
+  ret <8 x i16> %v2
+}
+
 ; CHECK-LABEL: load_v8i16_with_folded_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v8i16_with_folded_offset (i32) -> (v128){{$}}
@@ -223,6 +351,21 @@ define <8 x i16> @load_v8i16_with_folded
   ret <8 x i16> %v
 }
 
+; CHECK-LABEL: load_splat_v8i16_with_folded_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v8i16_with_folded_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: v16x8.load_splat $push[[R:[0-9]+]]=, 16($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <8 x i16> @load_splat_v8i16_with_folded_offset(i16* %p) {
+  %q = ptrtoint i16* %p to i32
+  %r = add nuw i32 %q, 16
+  %s = inttoptr i32 %r to i16*
+  %e = load i16, i16* %s
+  %v1 = insertelement <8 x i16> undef, i16 %e, i32 0
+  %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer
+  ret <8 x i16> %v2
+}
+
 ; CHECK-LABEL: load_v8i16_with_folded_gep_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v8i16_with_folded_gep_offset (i32) -> (v128){{$}}
@@ -234,6 +377,19 @@ define <8 x i16> @load_v8i16_with_folded
   ret <8 x i16> %v
 }
 
+; CHECK-LABEL: load_splat_v8i16_with_folded_gep_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v8i16_with_folded_gep_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: v16x8.load_splat $push[[R:[0-9]+]]=, 2($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <8 x i16> @load_splat_v8i16_with_folded_gep_offset(i16* %p) {
+  %s = getelementptr inbounds i16, i16* %p, i32 1
+  %e = load i16, i16* %s
+  %v1 = insertelement <8 x i16> undef, i16 %e, i32 0
+  %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer
+  ret <8 x i16> %v2
+}
+
 ; CHECK-LABEL: load_v8i16_with_unfolded_gep_negative_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v8i16_with_unfolded_gep_negative_offset (i32) -> (v128){{$}}
@@ -247,6 +403,21 @@ define <8 x i16> @load_v8i16_with_unfold
   ret <8 x i16> %v
 }
 
+; CHECK-LABEL: load_splat_v8i16_with_unfolded_gep_negative_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v8i16_with_unfolded_gep_negative_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, -2{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v16x8.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <8 x i16> @load_splat_v8i16_with_unfolded_gep_negative_offset(i16* %p) {
+  %s = getelementptr inbounds i16, i16* %p, i32 -1
+  %e = load i16, i16* %s
+  %v1 = insertelement <8 x i16> undef, i16 %e, i32 0
+  %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer
+  ret <8 x i16> %v2
+}
+
 ; CHECK-LABEL: load_v8i16_with_unfolded_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v8i16_with_unfolded_offset (i32) -> (v128){{$}}
@@ -262,6 +433,23 @@ define <8 x i16> @load_v8i16_with_unfold
   ret <8 x i16> %v
 }
 
+; CHECK-LABEL: load_splat_v8i16_with_unfolded_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v8i16_with_unfolded_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 16{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v16x8.load_splat $push[[L0:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[L0]]{{$}}
+define <8 x i16> @load_splat_v8i16_with_unfolded_offset(i16* %p) {
+  %q = ptrtoint i16* %p to i32
+  %r = add nsw i32 %q, 16
+  %s = inttoptr i32 %r to i16*
+  %e = load i16, i16* %s
+  %v1 = insertelement <8 x i16> undef, i16 %e, i32 0
+  %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer
+  ret <8 x i16> %v2
+}
+
 ; CHECK-LABEL: load_v8i16_with_unfolded_gep_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v8i16_with_unfolded_gep_offset (i32) -> (v128){{$}}
@@ -275,6 +463,21 @@ define <8 x i16> @load_v8i16_with_unfold
   ret <8 x i16> %v
 }
 
+; CHECK-LABEL: load_splat_v8i16_with_unfolded_gep_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v8i16_with_unfolded_gep_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 2{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v16x8.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <8 x i16> @load_splat_v8i16_with_unfolded_gep_offset(i16* %p) {
+  %s = getelementptr i16, i16* %p, i32 1
+  %e = load i16, i16* %s
+  %v1 = insertelement <8 x i16> undef, i16 %e, i32 0
+  %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer
+  ret <8 x i16> %v2
+}
+
 ; CHECK-LABEL: load_v8i16_from_numeric_address:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v8i16_from_numeric_address () -> (v128){{$}}
@@ -287,6 +490,20 @@ define <8 x i16> @load_v8i16_from_numeri
   ret <8 x i16> %v
 }
 
+; CHECK-LABEL: load_splat_v8i16_from_numeric_address:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v8i16_from_numeric_address () -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
+; SIMD128-NEXT: v16x8.load_splat $push[[R:[0-9]+]]=, 32($pop[[L0]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <8 x i16> @load_splat_v8i16_from_numeric_address() {
+  %s = inttoptr i32 32 to i16*
+  %e = load i16, i16* %s
+  %v1 = insertelement <8 x i16> undef, i16 %e, i32 0
+  %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer
+  ret <8 x i16> %v2
+}
+
 ; CHECK-LABEL: load_v8i16_from_global_address:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v8i16_from_global_address () -> (v128){{$}}
@@ -299,6 +516,20 @@ define <8 x i16> @load_v8i16_from_global
   ret <8 x i16> %v
 }
 
+; CHECK-LABEL: load_splat_v8i16_from_global_address:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v8i16_from_global_address () -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
+; SIMD128-NEXT: v16x8.load_splat $push[[R:[0-9]+]]=, gv_i16($pop[[L0]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+ at gv_i16 = global i16 42
+define <8 x i16> @load_splat_v8i16_from_global_address() {
+  %e = load i16, i16* @gv_i16
+  %v1 = insertelement <8 x i16> undef, i16 %e, i32 0
+  %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer
+  ret <8 x i16> %v2
+}
+
 ; CHECK-LABEL: store_v8i16:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype store_v8i16 (v128, i32) -> (){{$}}
@@ -400,6 +631,17 @@ define <4 x i32> @load_v4i32(<4 x i32>*
   ret <4 x i32> %v
 }
 
+; CHECK-LABEL: load_splat_v4i32:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4i32 (i32) -> (v128){{$}}
+; SIMD128-NEXT: v32x4.load_splat
+define <4 x i32> @load_splat_v4i32(i32* %addr) {
+  %e = load i32, i32* %addr, align 4
+  %v1 = insertelement <4 x i32> undef, i32 %e, i32 0
+  %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer
+  ret <4 x i32> %v2
+}
+
 ; CHECK-LABEL: load_v4i32_with_folded_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v4i32_with_folded_offset (i32) -> (v128){{$}}
@@ -413,6 +655,21 @@ define <4 x i32> @load_v4i32_with_folded
   ret <4 x i32> %v
 }
 
+; CHECK-LABEL: load_splat_v4i32_with_folded_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4i32_with_folded_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 16($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <4 x i32> @load_splat_v4i32_with_folded_offset(i32* %p) {
+  %q = ptrtoint i32* %p to i32
+  %r = add nuw i32 %q, 16
+  %s = inttoptr i32 %r to i32*
+  %e = load i32, i32* %s
+  %v1 = insertelement <4 x i32> undef, i32 %e, i32 0
+  %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer
+  ret <4 x i32> %v2
+}
+
 ; CHECK-LABEL: load_v4i32_with_folded_gep_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v4i32_with_folded_gep_offset (i32) -> (v128){{$}}
@@ -424,6 +681,19 @@ define <4 x i32> @load_v4i32_with_folded
   ret <4 x i32> %v
 }
 
+; CHECK-LABEL: load_splat_v4i32_with_folded_gep_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4i32_with_folded_gep_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 4($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <4 x i32> @load_splat_v4i32_with_folded_gep_offset(i32* %p) {
+  %s = getelementptr inbounds i32, i32* %p, i32 1
+  %e = load i32, i32* %s
+  %v1 = insertelement <4 x i32> undef, i32 %e, i32 0
+  %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer
+  ret <4 x i32> %v2
+}
+
 ; CHECK-LABEL: load_v4i32_with_unfolded_gep_negative_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v4i32_with_unfolded_gep_negative_offset (i32) -> (v128){{$}}
@@ -437,6 +707,21 @@ define <4 x i32> @load_v4i32_with_unfold
   ret <4 x i32> %v
 }
 
+; CHECK-LABEL: load_splat_v4i32_with_unfolded_gep_negative_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4i32_with_unfolded_gep_negative_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, -4{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <4 x i32> @load_splat_v4i32_with_unfolded_gep_negative_offset(i32* %p) {
+  %s = getelementptr inbounds i32, i32* %p, i32 -1
+  %e = load i32, i32* %s
+  %v1 = insertelement <4 x i32> undef, i32 %e, i32 0
+  %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer
+  ret <4 x i32> %v2
+}
+
 ; CHECK-LABEL: load_v4i32_with_unfolded_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v4i32_with_unfolded_offset (i32) -> (v128){{$}}
@@ -452,6 +737,23 @@ define <4 x i32> @load_v4i32_with_unfold
   ret <4 x i32> %v
 }
 
+; CHECK-LABEL: load_splat_v4i32_with_unfolded_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4i32_with_unfolded_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 16{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <4 x i32> @load_splat_v4i32_with_unfolded_offset(i32* %p) {
+  %q = ptrtoint i32* %p to i32
+  %r = add nsw i32 %q, 16
+  %s = inttoptr i32 %r to i32*
+  %e = load i32, i32* %s
+  %v1 = insertelement <4 x i32> undef, i32 %e, i32 0
+  %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer
+  ret <4 x i32> %v2
+}
+
 ; CHECK-LABEL: load_v4i32_with_unfolded_gep_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v4i32_with_unfolded_gep_offset (i32) -> (v128){{$}}
@@ -465,6 +767,21 @@ define <4 x i32> @load_v4i32_with_unfold
   ret <4 x i32> %v
 }
 
+; CHECK-LABEL: load_splat_v4i32_with_unfolded_gep_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4i32_with_unfolded_gep_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 4{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <4 x i32> @load_splat_v4i32_with_unfolded_gep_offset(i32* %p) {
+  %s = getelementptr i32, i32* %p, i32 1
+  %e = load i32, i32* %s
+  %v1 = insertelement <4 x i32> undef, i32 %e, i32 0
+  %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer
+  ret <4 x i32> %v2
+}
+
 ; CHECK-LABEL: load_v4i32_from_numeric_address:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v4i32_from_numeric_address () -> (v128){{$}}
@@ -477,6 +794,20 @@ define <4 x i32> @load_v4i32_from_numeri
   ret <4 x i32> %v
 }
 
+; CHECK-LABEL: load_splat_v4i32_from_numeric_address:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4i32_from_numeric_address () -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
+; SIMD128-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 32($pop[[L0]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <4 x i32> @load_splat_v4i32_from_numeric_address() {
+  %s = inttoptr i32 32 to i32*
+  %e = load i32, i32* %s
+  %v1 = insertelement <4 x i32> undef, i32 %e, i32 0
+  %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer
+  ret <4 x i32> %v2
+}
+
 ; CHECK-LABEL: load_v4i32_from_global_address:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v4i32_from_global_address () -> (v128){{$}}
@@ -489,6 +820,20 @@ define <4 x i32> @load_v4i32_from_global
   ret <4 x i32> %v
 }
 
+; CHECK-LABEL: load_splat_v4i32_from_global_address:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4i32_from_global_address () -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
+; SIMD128-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, gv_i32($pop[[L0]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+ at gv_i32 = global i32 42
+define <4 x i32> @load_splat_v4i32_from_global_address() {
+  %e = load i32, i32* @gv_i32
+  %v1 = insertelement <4 x i32> undef, i32 %e, i32 0
+  %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer
+  ret <4 x i32> %v2
+}
+
 ; CHECK-LABEL: store_v4i32:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype store_v4i32 (v128, i32) -> (){{$}}
@@ -591,6 +936,19 @@ define <2 x i64> @load_v2i64(<2 x i64>*
   ret <2 x i64> %v
 }
 
+; CHECK-LABEL: load_splat_v2i64:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2i64 (i32) -> (v128){{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 0($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x i64> @load_splat_v2i64(i64* %p) {
+  %e = load i64, i64* %p
+  %v1 = insertelement <2 x i64> undef, i64 %e, i32 0
+  %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer
+  ret <2 x i64> %v2
+}
+
 ; CHECK-LABEL: load_v2i64_with_folded_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128
@@ -605,6 +963,22 @@ define <2 x i64> @load_v2i64_with_folded
   ret <2 x i64> %v
 }
 
+; CHECK-LABEL: load_splat_v2i64_with_folded_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2i64_with_folded_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 16($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x i64> @load_splat_v2i64_with_folded_offset(i64* %p) {
+  %q = ptrtoint i64* %p to i32
+  %r = add nuw i32 %q, 16
+  %s = inttoptr i32 %r to i64*
+  %e = load i64, i64* %s
+  %v1 = insertelement <2 x i64> undef, i64 %e, i32 0
+  %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer
+  ret <2 x i64> %v2
+}
+
 ; CHECK-LABEL: load_v2i64_with_folded_gep_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128
@@ -617,6 +991,20 @@ define <2 x i64> @load_v2i64_with_folded
   ret <2 x i64> %v
 }
 
+; CHECK-LABEL: load_splat_v2i64_with_folded_gep_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2i64_with_folded_gep_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 8($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x i64> @load_splat_v2i64_with_folded_gep_offset(i64* %p) {
+  %s = getelementptr inbounds i64, i64* %p, i32 1
+  %e = load i64, i64* %s
+  %v1 = insertelement <2 x i64> undef, i64 %e, i32 0
+  %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer
+  ret <2 x i64> %v2
+}
+
 ; CHECK-LABEL: load_v2i64_with_unfolded_gep_negative_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128
@@ -631,6 +1019,22 @@ define <2 x i64> @load_v2i64_with_unfold
   ret <2 x i64> %v
 }
 
+; CHECK-LABEL: load_splat_v2i64_with_unfolded_gep_negative_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2i64_with_unfolded_gep_negative_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, -8{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x i64> @load_splat_v2i64_with_unfolded_gep_negative_offset(i64* %p) {
+  %s = getelementptr inbounds i64, i64* %p, i32 -1
+  %e = load i64, i64* %s
+  %v1 = insertelement <2 x i64> undef, i64 %e, i32 0
+  %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer
+  ret <2 x i64> %v2
+}
+
 ; CHECK-LABEL: load_v2i64_with_unfolded_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128
@@ -647,6 +1051,24 @@ define <2 x i64> @load_v2i64_with_unfold
   ret <2 x i64> %v
 }
 
+; CHECK-LABEL: load_splat_v2i64_with_unfolded_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2i64_with_unfolded_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 16{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x i64> @load_splat_v2i64_with_unfolded_offset(i64* %p) {
+  %q = ptrtoint i64* %p to i32
+  %r = add nsw i32 %q, 16
+  %s = inttoptr i32 %r to i64*
+  %e = load i64, i64* %s
+  %v1 = insertelement <2 x i64> undef, i64 %e, i32 0
+  %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer
+  ret <2 x i64> %v2
+}
+
 ; CHECK-LABEL: load_v2i64_with_unfolded_gep_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128
@@ -661,6 +1083,22 @@ define <2 x i64> @load_v2i64_with_unfold
   ret <2 x i64> %v
 }
 
+; CHECK-LABEL: load_splat_v2i64_with_unfolded_gep_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2i64_with_unfolded_gep_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 8{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x i64> @load_splat_v2i64_with_unfolded_gep_offset(i64* %p) {
+  %s = getelementptr i64, i64* %p, i32 1
+  %e = load i64, i64* %s
+  %v1 = insertelement <2 x i64> undef, i64 %e, i32 0
+  %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer
+  ret <2 x i64> %v2
+}
+
 ; CHECK-LABEL: load_v2i64_from_numeric_address:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128
@@ -674,6 +1112,21 @@ define <2 x i64> @load_v2i64_from_numeri
   ret <2 x i64> %v
 }
 
+; CHECK-LABEL: load_splat_v2i64_from_numeric_address:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2i64_from_numeric_address () -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 32($pop[[L0]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x i64> @load_splat_v2i64_from_numeric_address() {
+  %s = inttoptr i32 32 to i64*
+  %e = load i64, i64* %s
+  %v1 = insertelement <2 x i64> undef, i64 %e, i32 0
+  %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer
+  ret <2 x i64> %v2
+}
+
 ; CHECK-LABEL: load_v2i64_from_global_address:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128
@@ -687,6 +1140,21 @@ define <2 x i64> @load_v2i64_from_global
   ret <2 x i64> %v
 }
 
+; CHECK-LABEL: load_splat_v2i64_from_global_address:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2i64_from_global_address () -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, gv_i64($pop[[L0]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+ at gv_i64 = global i64 42
+define <2 x i64> @load_splat_v2i64_from_global_address() {
+  %e = load i64, i64* @gv_i64
+  %v1 = insertelement <2 x i64> undef, i64 %e, i32 0
+  %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer
+  ret <2 x i64> %v2
+}
+
 ; CHECK-LABEL: store_v2i64:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128
@@ -796,6 +1264,18 @@ define <4 x float> @load_v4f32(<4 x floa
   ret <4 x float> %v
 }
 
+; CHECK-LABEL: load_splat_v4f32:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4f32 (i32) -> (v128){{$}}
+; SIMD128-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 0($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <4 x float> @load_splat_v4f32(float* %p) {
+  %e = load float, float* %p
+  %v1 = insertelement <4 x float> undef, float %e, i32 0
+  %v2 = shufflevector <4 x float> %v1, <4 x float> undef, <4 x i32> zeroinitializer
+  ret <4 x float> %v2
+}
+
 ; CHECK-LABEL: load_v4f32_with_folded_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v4f32_with_folded_offset (i32) -> (v128){{$}}
@@ -809,6 +1289,21 @@ define <4 x float> @load_v4f32_with_fold
   ret <4 x float> %v
 }
 
+; CHECK-LABEL: load_splat_v4f32_with_folded_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4f32_with_folded_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 16($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <4 x float> @load_splat_v4f32_with_folded_offset(float* %p) {
+  %q = ptrtoint float* %p to i32
+  %r = add nuw i32 %q, 16
+  %s = inttoptr i32 %r to float*
+  %e = load float, float* %s
+  %v1 = insertelement <4 x float> undef, float %e, i32 0
+  %v2 = shufflevector <4 x float> %v1, <4 x float> undef, <4 x i32> zeroinitializer
+  ret <4 x float> %v2
+}
+
 ; CHECK-LABEL: load_v4f32_with_folded_gep_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v4f32_with_folded_gep_offset (i32) -> (v128){{$}}
@@ -820,6 +1315,19 @@ define <4 x float> @load_v4f32_with_fold
   ret <4 x float> %v
 }
 
+; CHECK-LABEL: load_splat_v4f32_with_folded_gep_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4f32_with_folded_gep_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 4($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <4 x float> @load_splat_v4f32_with_folded_gep_offset(float* %p) {
+  %s = getelementptr inbounds float, float* %p, i32 1
+  %e = load float, float* %s
+  %v1 = insertelement <4 x float> undef, float %e, i32 0
+  %v2 = shufflevector <4 x float> %v1, <4 x float> undef, <4 x i32> zeroinitializer
+  ret <4 x float> %v2
+}
+
 ; CHECK-LABEL: load_v4f32_with_unfolded_gep_negative_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v4f32_with_unfolded_gep_negative_offset (i32) -> (v128){{$}}
@@ -833,6 +1341,21 @@ define <4 x float> @load_v4f32_with_unfo
   ret <4 x float> %v
 }
 
+; CHECK-LABEL: load_splat_v4f32_with_unfolded_gep_negative_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4f32_with_unfolded_gep_negative_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, -4{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <4 x float> @load_splat_v4f32_with_unfolded_gep_negative_offset(float* %p) {
+  %s = getelementptr inbounds float, float* %p, i32 -1
+  %e = load float, float* %s
+  %v1 = insertelement <4 x float> undef, float %e, i32 0
+  %v2 = shufflevector <4 x float> %v1, <4 x float> undef, <4 x i32> zeroinitializer
+  ret <4 x float> %v2
+}
+
 ; CHECK-LABEL: load_v4f32_with_unfolded_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v4f32_with_unfolded_offset (i32) -> (v128){{$}}
@@ -848,6 +1371,23 @@ define <4 x float> @load_v4f32_with_unfo
   ret <4 x float> %v
 }
 
+; CHECK-LABEL: load_splat_v4f32_with_unfolded_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4f32_with_unfolded_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 16{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <4 x float> @load_splat_v4f32_with_unfolded_offset(float* %p) {
+  %q = ptrtoint float* %p to i32
+  %r = add nsw i32 %q, 16
+  %s = inttoptr i32 %r to float*
+  %e = load float, float* %s
+  %v1 = insertelement <4 x float> undef, float %e, i32 0
+  %v2 = shufflevector <4 x float> %v1, <4 x float> undef, <4 x i32> zeroinitializer
+  ret <4 x float> %v2
+}
+
 ; CHECK-LABEL: load_v4f32_with_unfolded_gep_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v4f32_with_unfolded_gep_offset (i32) -> (v128){{$}}
@@ -861,6 +1401,21 @@ define <4 x float> @load_v4f32_with_unfo
   ret <4 x float> %v
 }
 
+; CHECK-LABEL: load_splat_v4f32_with_unfolded_gep_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4f32_with_unfolded_gep_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 4{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <4 x float> @load_splat_v4f32_with_unfolded_gep_offset(float* %p) {
+  %s = getelementptr float, float* %p, i32 1
+  %e = load float, float* %s
+  %v1 = insertelement <4 x float> undef, float %e, i32 0
+  %v2 = shufflevector <4 x float> %v1, <4 x float> undef, <4 x i32> zeroinitializer
+  ret <4 x float> %v2
+}
+
 ; CHECK-LABEL: load_v4f32_from_numeric_address:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v4f32_from_numeric_address () -> (v128){{$}}
@@ -873,6 +1428,20 @@ define <4 x float> @load_v4f32_from_nume
   ret <4 x float> %v
 }
 
+; CHECK-LABEL: load_splat_v4f32_from_numeric_address:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4f32_from_numeric_address () -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
+; SIMD128-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, 32($pop[[L0]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <4 x float> @load_splat_v4f32_from_numeric_address() {
+  %s = inttoptr i32 32 to float*
+  %e = load float, float* %s
+  %v1 = insertelement <4 x float> undef, float %e, i32 0
+  %v2 = shufflevector <4 x float> %v1, <4 x float> undef, <4 x i32> zeroinitializer
+  ret <4 x float> %v2
+}
+
 ; CHECK-LABEL: load_v4f32_from_global_address:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype load_v4f32_from_global_address () -> (v128){{$}}
@@ -885,6 +1454,20 @@ define <4 x float> @load_v4f32_from_glob
   ret <4 x float> %v
 }
 
+; CHECK-LABEL: load_splat_v4f32_from_global_address:
+; NO-SIMD128-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v4f32_from_global_address () -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
+; SIMD128-NEXT: v32x4.load_splat $push[[R:[0-9]+]]=, gv_f32($pop[[L0]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+ at gv_f32 = global float 42.
+define <4 x float> @load_splat_v4f32_from_global_address() {
+  %e = load float, float* @gv_f32
+  %v1 = insertelement <4 x float> undef, float %e, i32 0
+  %v2 = shufflevector <4 x float> %v1, <4 x float> undef, <4 x i32> zeroinitializer
+  ret <4 x float> %v2
+}
+
 ; CHECK-LABEL: store_v4f32:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-NEXT: .functype store_v4f32 (v128, i32) -> (){{$}}
@@ -987,6 +1570,19 @@ define <2 x double> @load_v2f64(<2 x dou
   ret <2 x double> %v
 }
 
+; CHECK-LABEL: load_splat_v2f64:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2f64 (i32) -> (v128){{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 0($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x double> @load_splat_v2f64(double* %p) {
+  %e = load double, double* %p
+  %v1 = insertelement <2 x double> undef, double %e, i32 0
+  %v2 = shufflevector <2 x double> %v1, <2 x double> undef, <2 x i32> zeroinitializer
+  ret <2 x double> %v2
+}
+
 ; CHECK-LABEL: load_v2f64_with_folded_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128
@@ -1001,6 +1597,22 @@ define <2 x double> @load_v2f64_with_fol
   ret <2 x double> %v
 }
 
+; CHECK-LABEL: load_splat_v2f64_with_folded_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2f64_with_folded_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 16($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x double> @load_splat_v2f64_with_folded_offset(double* %p) {
+  %q = ptrtoint double* %p to i32
+  %r = add nuw i32 %q, 16
+  %s = inttoptr i32 %r to double*
+  %e = load double, double* %s
+  %v1 = insertelement <2 x double> undef, double %e, i32 0
+  %v2 = shufflevector <2 x double> %v1, <2 x double> undef, <2 x i32> zeroinitializer
+  ret <2 x double> %v2
+}
+
 ; CHECK-LABEL: load_v2f64_with_folded_gep_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128
@@ -1013,6 +1625,20 @@ define <2 x double> @load_v2f64_with_fol
   ret <2 x double> %v
 }
 
+; CHECK-LABEL: load_splat_v2f64_with_folded_gep_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2f64_with_folded_gep_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 8($0){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x double> @load_splat_v2f64_with_folded_gep_offset(double* %p) {
+  %s = getelementptr inbounds double, double* %p, i32 1
+  %e = load double, double* %s
+  %v1 = insertelement <2 x double> undef, double %e, i32 0
+  %v2 = shufflevector <2 x double> %v1, <2 x double> undef, <2 x i32> zeroinitializer
+  ret <2 x double> %v2
+}
+
 ; CHECK-LABEL: load_v2f64_with_unfolded_gep_negative_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128
@@ -1027,6 +1653,22 @@ define <2 x double> @load_v2f64_with_unf
   ret <2 x double> %v
 }
 
+; CHECK-LABEL: load_splat_v2f64_with_unfolded_gep_negative_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2f64_with_unfolded_gep_negative_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, -8{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x double> @load_splat_v2f64_with_unfolded_gep_negative_offset(double* %p) {
+  %s = getelementptr inbounds double, double* %p, i32 -1
+  %e = load double, double* %s
+  %v1 = insertelement <2 x double> undef, double %e, i32 0
+  %v2 = shufflevector <2 x double> %v1, <2 x double> undef, <2 x i32> zeroinitializer
+  ret <2 x double> %v2
+}
+
 ; CHECK-LABEL: load_v2f64_with_unfolded_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128
@@ -1043,6 +1685,24 @@ define <2 x double> @load_v2f64_with_unf
   ret <2 x double> %v
 }
 
+; CHECK-LABEL: load_splat_v2f64_with_unfolded_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2f64_with_unfolded_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 16{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x double> @load_splat_v2f64_with_unfolded_offset(double* %p) {
+  %q = ptrtoint double* %p to i32
+  %r = add nsw i32 %q, 16
+  %s = inttoptr i32 %r to double*
+  %e = load double, double* %s
+  %v1 = insertelement <2 x double> undef, double %e, i32 0
+  %v2 = shufflevector <2 x double> %v1, <2 x double> undef, <2 x i32> zeroinitializer
+  ret <2 x double> %v2
+}
+
 ; CHECK-LABEL: load_v2f64_with_unfolded_gep_offset:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128
@@ -1057,6 +1717,22 @@ define <2 x double> @load_v2f64_with_unf
   ret <2 x double> %v
 }
 
+; CHECK-LABEL: load_splat_v2f64_with_unfolded_gep_offset:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2f64_with_unfolded_gep_offset (i32) -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 8{{$}}
+; SIMD128-NEXT: i32.add $push[[L1:[0-9]+]]=, $0, $pop[[L0]]{{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 0($pop[[L1]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x double> @load_splat_v2f64_with_unfolded_gep_offset(double* %p) {
+  %s = getelementptr double, double* %p, i32 1
+  %e = load double, double* %s
+  %v1 = insertelement <2 x double> undef, double %e, i32 0
+  %v2 = shufflevector <2 x double> %v1, <2 x double> undef, <2 x i32> zeroinitializer
+  ret <2 x double> %v2
+}
+
 ; CHECK-LABEL: load_v2f64_from_numeric_address:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128
@@ -1070,6 +1746,21 @@ define <2 x double> @load_v2f64_from_num
   ret <2 x double> %v
 }
 
+; CHECK-LABEL: load_splat_v2f64_from_numeric_address:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2f64_from_numeric_address () -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, 32($pop[[L0]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x double> @load_splat_v2f64_from_numeric_address() {
+  %s = inttoptr i32 32 to double*
+  %e = load double, double* %s
+  %v1 = insertelement <2 x double> undef, double %e, i32 0
+  %v2 = shufflevector <2 x double> %v1, <2 x double> undef, <2 x i32> zeroinitializer
+  ret <2 x double> %v2
+}
+
 ; CHECK-LABEL: load_v2f64_from_global_address:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128
@@ -1083,6 +1774,21 @@ define <2 x double> @load_v2f64_from_glo
   ret <2 x double> %v
 }
 
+; CHECK-LABEL: load_splat_v2f64_from_global_address:
+; NO-SIMD128-NOT: v128
+; SIMD128-VM-NOT: v128
+; SIMD128-NEXT: .functype load_splat_v2f64_from_global_address () -> (v128){{$}}
+; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
+; SIMD128-NEXT: v64x2.load_splat $push[[R:[0-9]+]]=, gv_f64($pop[[L0]]){{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+ at gv_f64 = global double 42.
+define <2 x double> @load_splat_v2f64_from_global_address() {
+  %e = load double, double* @gv_f64
+  %v1 = insertelement <2 x double> undef, double %e, i32 0
+  %v2 = shufflevector <2 x double> %v1, <2 x double> undef, <2 x i32> zeroinitializer
+  ret <2 x double> %v2
+}
+
 ; CHECK-LABEL: store_v2f64:
 ; NO-SIMD128-NOT: v128
 ; SIMD128-VM-NOT: v128

Modified: llvm/trunk/test/MC/WebAssembly/simd-encodings.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/simd-encodings.s?rev=372655&r1=372654&r2=372655&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/simd-encodings.s (original)
+++ llvm/trunk/test/MC/WebAssembly/simd-encodings.s Mon Sep 23 13:42:12 2019
@@ -463,6 +463,18 @@ main:
     # CHECK: f64x2.convert_i64x2_u # encoding: [0xfd,0xb2,0x01]
     f64x2.convert_i64x2_u
 
+    # CHECK: v8x16.load_splat 48 # encoding: [0xfd,0xc2,0x01,0x00,0x30]
+    v8x16.load_splat 48
+
+    # CHECK: v16x8.load_splat 48 # encoding: [0xfd,0xc3,0x01,0x01,0x30]
+    v16x8.load_splat 48
+
+    # CHECK: v32x4.load_splat 48 # encoding: [0xfd,0xc4,0x01,0x02,0x30]
+    v32x4.load_splat 48
+
+    # CHECK: v64x2.load_splat 48 # encoding: [0xfd,0xc5,0x01,0x03,0x30]
+    v64x2.load_splat 48
+
     # CHECK: i8x16.narrow_i16x8_s # encoding: [0xfd,0xc6,0x01]
     i8x16.narrow_i16x8_s
 




More information about the llvm-commits mailing list