blob: f317edca549de660eda9d52c893eb1b51754a9e7 [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -verify-machineinstrs -mattr=+simd128 | FileCheck %s
; Test SIMD loads and stores
target triple = "wasm32-unknown-unknown"
; ==============================================================================
; 16 x i8
; ==============================================================================
define <16 x i8> @load_v16i8(ptr %p) {
; CHECK-LABEL: load_v16i8:
; CHECK: .functype load_v16i8 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%v = load <16 x i8>, ptr %p
ret <16 x i8> %v
}
define <16 x i8> @load_splat_v16i8(ptr %p) {
; CHECK-LABEL: load_splat_v16i8:
; CHECK: .functype load_splat_v16i8 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load8_splat 0
; CHECK-NEXT: # fallthrough-return
%e = load i8, ptr %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
}
define <16 x i8> @load_v16i8_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_v16i8_with_folded_offset:
; CHECK: .functype load_v16i8_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <16 x i8>, ptr %s
ret <16 x i8> %v
}
define <16 x i8> @load_splat_v16i8_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_splat_v16i8_with_folded_offset:
; CHECK: .functype load_splat_v16i8_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load8_splat 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%e = load i8, ptr %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
}
define <16 x i8> @load_v16i8_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_v16i8_with_folded_gep_offset:
; CHECK: .functype load_v16i8_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load 16
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <16 x i8>, ptr %p, i32 1
%v = load <16 x i8>, ptr %s
ret <16 x i8> %v
}
define <16 x i8> @load_splat_v16i8_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_splat_v16i8_with_folded_gep_offset:
; CHECK: .functype load_splat_v16i8_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load8_splat 1
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds i8, ptr %p, i32 1
%e = load i8, ptr %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
}
define <16 x i8> @load_v16i8_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_v16i8_with_unfolded_gep_negative_offset:
; CHECK: .functype load_v16i8_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <16 x i8>, ptr %p, i32 -1
%v = load <16 x i8>, ptr %s
ret <16 x i8> %v
}
define <16 x i8> @load_splat_v16i8_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_splat_v16i8_with_unfolded_gep_negative_offset:
; CHECK: .functype load_splat_v16i8_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -1
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load8_splat 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds i8, ptr %p, i32 -1
%e = load i8, ptr %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
}
define <16 x i8> @load_v16i8_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_v16i8_with_unfolded_offset:
; CHECK: .functype load_v16i8_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <16 x i8>, ptr %s
ret <16 x i8> %v
}
define <16 x i8> @load_splat_v16i8_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_splat_v16i8_with_unfolded_offset:
; CHECK: .functype load_splat_v16i8_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load8_splat 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%e = load i8, ptr %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
}
define <16 x i8> @load_v16i8_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_v16i8_with_unfolded_gep_offset:
; CHECK: .functype load_v16i8_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <16 x i8>, ptr %p, i32 1
%v = load <16 x i8>, ptr %s
ret <16 x i8> %v
}
define <16 x i8> @load_splat_v16i8_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_splat_v16i8_with_unfolded_gep_offset:
; CHECK: .functype load_splat_v16i8_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load8_splat 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr i8, ptr %p, i32 1
%e = load i8, ptr %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
}
define <16 x i8> @load_v16i8_from_numeric_address() {
; CHECK-LABEL: load_v16i8_from_numeric_address:
; CHECK: .functype load_v16i8_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%v = load <16 x i8>, ptr %s
ret <16 x i8> %v
}
define <16 x i8> @load_splat_v16i8_from_numeric_address() {
; CHECK-LABEL: load_splat_v16i8_from_numeric_address:
; CHECK: .functype load_splat_v16i8_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load8_splat 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%e = load i8, ptr %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
}
@gv_v16i8 = global <16 x i8> <i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42>
define <16 x i8> @load_v16i8_from_global_address() {
; CHECK-LABEL: load_v16i8_from_global_address:
; CHECK: .functype load_v16i8_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load gv_v16i8
; CHECK-NEXT: # fallthrough-return
%v = load <16 x i8>, ptr @gv_v16i8
ret <16 x i8> %v
}
@gv_i8 = global i8 42
define <16 x i8> @load_splat_v16i8_from_global_address() {
; CHECK-LABEL: load_splat_v16i8_from_global_address:
; CHECK: .functype load_splat_v16i8_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load8_splat gv_i8
; CHECK-NEXT: # fallthrough-return
%e = load i8, ptr @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
}
define void @store_v16i8(<16 x i8> %v, ptr %p) {
; CHECK-LABEL: store_v16i8:
; CHECK: .functype store_v16i8 (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 0
; CHECK-NEXT: # fallthrough-return
store <16 x i8> %v , ptr %p
ret void
}
define void @store_v16i8_with_folded_offset(<16 x i8> %v, ptr %p) {
; CHECK-LABEL: store_v16i8_with_folded_offset:
; CHECK: .functype store_v16i8_with_folded_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
store <16 x i8> %v , ptr %s
ret void
}
define void @store_v16i8_with_folded_gep_offset(<16 x i8> %v, ptr %p) {
; CHECK-LABEL: store_v16i8_with_folded_gep_offset:
; CHECK: .functype store_v16i8_with_folded_gep_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 16
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <16 x i8>, ptr %p, i32 1
store <16 x i8> %v , ptr %s
ret void
}
define void @store_v16i8_with_unfolded_gep_negative_offset(<16 x i8> %v, ptr %p) {
; CHECK-LABEL: store_v16i8_with_unfolded_gep_negative_offset:
; CHECK: .functype store_v16i8_with_unfolded_gep_negative_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const -16
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <16 x i8>, ptr %p, i32 -1
store <16 x i8> %v , ptr %s
ret void
}
define void @store_v16i8_with_unfolded_offset(<16 x i8> %v, ptr %p) {
; CHECK-LABEL: store_v16i8_with_unfolded_offset:
; CHECK: .functype store_v16i8_with_unfolded_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
store <16 x i8> %v , ptr %s
ret void
}
define void @store_v16i8_with_unfolded_gep_offset(<16 x i8> %v, ptr %p) {
; CHECK-LABEL: store_v16i8_with_unfolded_gep_offset:
; CHECK: .functype store_v16i8_with_unfolded_gep_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <16 x i8>, ptr %p, i32 1
store <16 x i8> %v , ptr %s
ret void
}
define void @store_v16i8_to_numeric_address(<16 x i8> %v) {
; CHECK-LABEL: store_v16i8_to_numeric_address:
; CHECK: .functype store_v16i8_to_numeric_address (v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
store <16 x i8> %v , ptr %s
ret void
}
define void @store_v16i8_to_global_address(<16 x i8> %v) {
; CHECK-LABEL: store_v16i8_to_global_address:
; CHECK: .functype store_v16i8_to_global_address (v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store gv_v16i8
; CHECK-NEXT: # fallthrough-return
store <16 x i8> %v , ptr @gv_v16i8
ret void
}
; ==============================================================================
; 8 x i16
; ==============================================================================
define <8 x i16> @load_v8i16(ptr %p) {
; CHECK-LABEL: load_v8i16:
; CHECK: .functype load_v8i16 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%v = load <8 x i16>, ptr %p
ret <8 x i16> %v
}
define <8 x i16> @load_splat_v8i16(ptr %p) {
; CHECK-LABEL: load_splat_v8i16:
; CHECK: .functype load_splat_v8i16 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load16_splat 0
; CHECK-NEXT: # fallthrough-return
%e = load i16, ptr %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
}
define <8 x i16> @load_sext_v8i16(ptr %p) {
; CHECK-LABEL: load_sext_v8i16:
; CHECK: .functype load_sext_v8i16 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i16x8.load8x8_s 0
; CHECK-NEXT: # fallthrough-return
%v = load <8 x i8>, ptr %p
%v2 = sext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i16> @load_zext_v8i16(ptr %p) {
; CHECK-LABEL: load_zext_v8i16:
; CHECK: .functype load_zext_v8i16 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i16x8.load8x8_u 0
; CHECK-NEXT: # fallthrough-return
%v = load <8 x i8>, ptr %p
%v2 = zext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i8> @load_ext_v8i16(ptr %p) {
; CHECK-LABEL: load_ext_v8i16:
; CHECK: .functype load_ext_v8i16 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load64_zero 0
; CHECK-NEXT: # fallthrough-return
%v = load <8 x i8>, ptr %p
ret <8 x i8> %v
}
define <8 x i16> @load_v8i16_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_v8i16_with_folded_offset:
; CHECK: .functype load_v8i16_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <8 x i16>, ptr %s
ret <8 x i16> %v
}
define <8 x i16> @load_splat_v8i16_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_splat_v8i16_with_folded_offset:
; CHECK: .functype load_splat_v8i16_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load16_splat 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%e = load i16, ptr %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
}
define <8 x i16> @load_sext_v8i16_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_sext_v8i16_with_folded_offset:
; CHECK: .functype load_sext_v8i16_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i16x8.load8x8_s 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <8 x i8>, ptr %s
%v2 = sext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i16> @load_zext_v8i16_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_zext_v8i16_with_folded_offset:
; CHECK: .functype load_zext_v8i16_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i16x8.load8x8_u 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <8 x i8>, ptr %s
%v2 = zext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i8> @load_ext_v8i16_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_ext_v8i16_with_folded_offset:
; CHECK: .functype load_ext_v8i16_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load64_zero 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <8 x i8>, ptr %s
ret <8 x i8> %v
}
define <8 x i16> @load_v8i16_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_v8i16_with_folded_gep_offset:
; CHECK: .functype load_v8i16_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load 16
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <8 x i16>, ptr %p, i32 1
%v = load <8 x i16>, ptr %s
ret <8 x i16> %v
}
define <8 x i16> @load_splat_v8i16_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_splat_v8i16_with_folded_gep_offset:
; CHECK: .functype load_splat_v8i16_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load16_splat 2
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds i16, ptr %p, i32 1
%e = load i16, ptr %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
}
define <8 x i16> @load_sext_v8i16_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_sext_v8i16_with_folded_gep_offset:
; CHECK: .functype load_sext_v8i16_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i16x8.load8x8_s 8
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <8 x i8>, ptr %p, i32 1
%v = load <8 x i8>, ptr %s
%v2 = sext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i16> @load_zext_v8i16_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_zext_v8i16_with_folded_gep_offset:
; CHECK: .functype load_zext_v8i16_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i16x8.load8x8_u 8
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <8 x i8>, ptr %p, i32 1
%v = load <8 x i8>, ptr %s
%v2 = zext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i8> @load_ext_v8i16_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_ext_v8i16_with_folded_gep_offset:
; CHECK: .functype load_ext_v8i16_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load64_zero 8
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <8 x i8>, ptr %p, i32 1
%v = load <8 x i8>, ptr %s
ret <8 x i8> %v
}
define <8 x i16> @load_v8i16_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_v8i16_with_unfolded_gep_negative_offset:
; CHECK: .functype load_v8i16_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <8 x i16>, ptr %p, i32 -1
%v = load <8 x i16>, ptr %s
ret <8 x i16> %v
}
define <8 x i16> @load_splat_v8i16_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_splat_v8i16_with_unfolded_gep_negative_offset:
; CHECK: .functype load_splat_v8i16_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -2
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load16_splat 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds i16, ptr %p, i32 -1
%e = load i16, ptr %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
}
define <8 x i16> @load_sext_v8i16_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_sext_v8i16_with_unfolded_gep_negative_offset:
; CHECK: .functype load_sext_v8i16_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -8
; CHECK-NEXT: i32.add
; CHECK-NEXT: i16x8.load8x8_s 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <8 x i8>, ptr %p, i32 -1
%v = load <8 x i8>, ptr %s
%v2 = sext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i16> @load_zext_v8i16_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_zext_v8i16_with_unfolded_gep_negative_offset:
; CHECK: .functype load_zext_v8i16_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -8
; CHECK-NEXT: i32.add
; CHECK-NEXT: i16x8.load8x8_u 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <8 x i8>, ptr %p, i32 -1
%v = load <8 x i8>, ptr %s
%v2 = zext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i8> @load_ext_v8i16_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_ext_v8i16_with_unfolded_gep_negative_offset:
; CHECK: .functype load_ext_v8i16_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -8
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load64_zero 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <8 x i8>, ptr %p, i32 -1
%v = load <8 x i8>, ptr %s
ret <8 x i8> %v
}
define <8 x i16> @load_v8i16_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_v8i16_with_unfolded_offset:
; CHECK: .functype load_v8i16_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <8 x i16>, ptr %s
ret <8 x i16> %v
}
define <8 x i16> @load_splat_v8i16_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_splat_v8i16_with_unfolded_offset:
; CHECK: .functype load_splat_v8i16_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load16_splat 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%e = load i16, ptr %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
}
define <8 x i16> @load_sext_v8i16_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_sext_v8i16_with_unfolded_offset:
; CHECK: .functype load_sext_v8i16_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: i16x8.load8x8_s 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <8 x i8>, ptr %s
%v2 = sext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i16> @load_zext_v8i16_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_zext_v8i16_with_unfolded_offset:
; CHECK: .functype load_zext_v8i16_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: i16x8.load8x8_u 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <8 x i8>, ptr %s
%v2 = zext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i8> @load_ext_v8i16_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_ext_v8i16_with_unfolded_offset:
; CHECK: .functype load_ext_v8i16_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load64_zero 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <8 x i8>, ptr %s
ret <8 x i8> %v
}
define <8 x i16> @load_v8i16_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_v8i16_with_unfolded_gep_offset:
; CHECK: .functype load_v8i16_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <8 x i16>, ptr %p, i32 1
%v = load <8 x i16>, ptr %s
ret <8 x i16> %v
}
define <8 x i16> @load_splat_v8i16_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_splat_v8i16_with_unfolded_gep_offset:
; CHECK: .functype load_splat_v8i16_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 2
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load16_splat 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr i16, ptr %p, i32 1
%e = load i16, ptr %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
}
define <8 x i16> @load_sext_v8i16_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_sext_v8i16_with_unfolded_gep_offset:
; CHECK: .functype load_sext_v8i16_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 8
; CHECK-NEXT: i32.add
; CHECK-NEXT: i16x8.load8x8_s 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <8 x i8>, ptr %p, i32 1
%v = load <8 x i8>, ptr %s
%v2 = sext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i16> @load_zext_v8i16_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_zext_v8i16_with_unfolded_gep_offset:
; CHECK: .functype load_zext_v8i16_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 8
; CHECK-NEXT: i32.add
; CHECK-NEXT: i16x8.load8x8_u 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <8 x i8>, ptr %p, i32 1
%v = load <8 x i8>, ptr %s
%v2 = zext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i8> @load_ext_v8i16_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_ext_v8i16_with_unfolded_gep_offset:
; CHECK: .functype load_ext_v8i16_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 8
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load64_zero 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <8 x i8>, ptr %p, i32 1
%v = load <8 x i8>, ptr %s
ret <8 x i8> %v
}
define <8 x i16> @load_v8i16_from_numeric_address() {
; CHECK-LABEL: load_v8i16_from_numeric_address:
; CHECK: .functype load_v8i16_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%v = load <8 x i16>, ptr %s
ret <8 x i16> %v
}
define <8 x i16> @load_splat_v8i16_from_numeric_address() {
; CHECK-LABEL: load_splat_v8i16_from_numeric_address:
; CHECK: .functype load_splat_v8i16_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load16_splat 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%e = load i16, ptr %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
}
define <8 x i16> @load_sext_v8i16_from_numeric_address() {
; CHECK-LABEL: load_sext_v8i16_from_numeric_address:
; CHECK: .functype load_sext_v8i16_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i16x8.load8x8_s 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%v = load <8 x i8>, ptr %s
%v2 = sext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i16> @load_zext_v8i16_from_numeric_address() {
; CHECK-LABEL: load_zext_v8i16_from_numeric_address:
; CHECK: .functype load_zext_v8i16_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i16x8.load8x8_u 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%v = load <8 x i8>, ptr %s
%v2 = zext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i8> @load_ext_v8i16_from_numeric_address() {
; CHECK-LABEL: load_ext_v8i16_from_numeric_address:
; CHECK: .functype load_ext_v8i16_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load64_zero 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%v = load <8 x i8>, ptr %s
ret <8 x i8> %v
}
@gv_v8i16 = global <8 x i16> <i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42>
define <8 x i16> @load_v8i16_from_global_address() {
; CHECK-LABEL: load_v8i16_from_global_address:
; CHECK: .functype load_v8i16_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load gv_v8i16
; CHECK-NEXT: # fallthrough-return
%v = load <8 x i16>, ptr @gv_v8i16
ret <8 x i16> %v
}
@gv_i16 = global i16 42
define <8 x i16> @load_splat_v8i16_from_global_address() {
; CHECK-LABEL: load_splat_v8i16_from_global_address:
; CHECK: .functype load_splat_v8i16_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load16_splat gv_i16
; CHECK-NEXT: # fallthrough-return
%e = load i16, ptr @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
}
@gv_v8i8 = global <8 x i8> <i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42>
define <8 x i16> @load_sext_v8i16_from_global_address() {
; CHECK-LABEL: load_sext_v8i16_from_global_address:
; CHECK: .functype load_sext_v8i16_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i16x8.load8x8_s gv_v8i8
; CHECK-NEXT: # fallthrough-return
%v = load <8 x i8>, ptr @gv_v8i8
%v2 = sext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i16> @load_zext_v8i16_from_global_address() {
; CHECK-LABEL: load_zext_v8i16_from_global_address:
; CHECK: .functype load_zext_v8i16_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i16x8.load8x8_u gv_v8i8
; CHECK-NEXT: # fallthrough-return
%v = load <8 x i8>, ptr @gv_v8i8
%v2 = zext <8 x i8> %v to <8 x i16>
ret <8 x i16> %v2
}
define <8 x i8> @load_ext_v8i16_from_global_address() {
; CHECK-LABEL: load_ext_v8i16_from_global_address:
; CHECK: .functype load_ext_v8i16_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load64_zero gv_v8i8
; CHECK-NEXT: # fallthrough-return
%v = load <8 x i8>, ptr @gv_v8i8
ret <8 x i8> %v
}
define void @store_v8i16(<8 x i16> %v, ptr %p) {
; CHECK-LABEL: store_v8i16:
; CHECK: .functype store_v8i16 (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 0
; CHECK-NEXT: # fallthrough-return
store <8 x i16> %v , ptr %p
ret void
}
define void @store_narrowing_v8i16(<8 x i8> %v, ptr %p) {
; CHECK-LABEL: store_narrowing_v8i16:
; CHECK: .functype store_narrowing_v8i16 (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane 0, 0
; CHECK-NEXT: # fallthrough-return
store <8 x i8> %v, ptr %p
ret void
}
define void @store_v8i16_with_folded_offset(<8 x i16> %v, ptr %p) {
; CHECK-LABEL: store_v8i16_with_folded_offset:
; CHECK: .functype store_v8i16_with_folded_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
store <8 x i16> %v , ptr %s
ret void
}
define void @store_narrowing_v8i16_with_folded_offset(<8 x i8> %v, ptr %p) {
; CHECK-LABEL: store_narrowing_v8i16_with_folded_offset:
; CHECK: .functype store_narrowing_v8i16_with_folded_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane 16, 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
store <8 x i8> %v , ptr %s
ret void
}
define void @store_v8i16_with_folded_gep_offset(<8 x i16> %v, ptr %p) {
; CHECK-LABEL: store_v8i16_with_folded_gep_offset:
; CHECK: .functype store_v8i16_with_folded_gep_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 16
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <8 x i16>, ptr %p, i32 1
store <8 x i16> %v , ptr %s
ret void
}
define void @store_narrowing_v8i16_with_folded_gep_offset(<8 x i8> %v, ptr %p) {
; CHECK-LABEL: store_narrowing_v8i16_with_folded_gep_offset:
; CHECK: .functype store_narrowing_v8i16_with_folded_gep_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane 8, 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <8 x i8>, ptr %p, i32 1
store <8 x i8> %v , ptr %s
ret void
}
define void @store_v8i16_with_unfolded_gep_negative_offset(<8 x i16> %v, ptr %p) {
; CHECK-LABEL: store_v8i16_with_unfolded_gep_negative_offset:
; CHECK: .functype store_v8i16_with_unfolded_gep_negative_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const -16
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <8 x i16>, ptr %p, i32 -1
store <8 x i16> %v , ptr %s
ret void
}
define void @store_narrowing_v8i16_with_unfolded_gep_negative_offset(<8 x i8> %v, ptr %p) {
; CHECK-LABEL: store_narrowing_v8i16_with_unfolded_gep_negative_offset:
; CHECK: .functype store_narrowing_v8i16_with_unfolded_gep_negative_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const -8
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane 0, 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <8 x i8>, ptr %p, i32 -1
store <8 x i8> %v , ptr %s
ret void
}
define void @store_v8i16_with_unfolded_offset(<8 x i16> %v, ptr %p) {
; CHECK-LABEL: store_v8i16_with_unfolded_offset:
; CHECK: .functype store_v8i16_with_unfolded_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
store <8 x i16> %v , ptr %s
ret void
}
define void @store_narrowing_v8i16_with_unfolded_offset(<8 x i8> %v, ptr %p) {
; CHECK-LABEL: store_narrowing_v8i16_with_unfolded_offset:
; CHECK: .functype store_narrowing_v8i16_with_unfolded_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane 0, 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
store <8 x i8> %v , ptr %s
ret void
}
define void @store_v8i16_with_unfolded_gep_offset(<8 x i16> %v, ptr %p) {
; CHECK-LABEL: store_v8i16_with_unfolded_gep_offset:
; CHECK: .functype store_v8i16_with_unfolded_gep_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <8 x i16>, ptr %p, i32 1
store <8 x i16> %v , ptr %s
ret void
}
define void @store_narrowing_v8i16_with_unfolded_gep_offset(<8 x i8> %v, ptr %p) {
; CHECK-LABEL: store_narrowing_v8i16_with_unfolded_gep_offset:
; CHECK: .functype store_narrowing_v8i16_with_unfolded_gep_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 8
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane 0, 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <8 x i8>, ptr %p, i32 1
store <8 x i8> %v , ptr %s
ret void
}
define void @store_v8i16_to_numeric_address(<8 x i16> %v) {
; CHECK-LABEL: store_v8i16_to_numeric_address:
; CHECK: .functype store_v8i16_to_numeric_address (v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
store <8 x i16> %v , ptr %s
ret void
}
define void @store_narrowing_v8i16_to_numeric_address(<8 x i8> %v, ptr %p) {
; CHECK-LABEL: store_narrowing_v8i16_to_numeric_address:
; CHECK: .functype store_narrowing_v8i16_to_numeric_address (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane 32, 0
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
store <8 x i8> %v , ptr %s
ret void
}
define void @store_v8i16_to_global_address(<8 x i16> %v) {
; CHECK-LABEL: store_v8i16_to_global_address:
; CHECK: .functype store_v8i16_to_global_address (v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store gv_v8i16
; CHECK-NEXT: # fallthrough-return
store <8 x i16> %v , ptr @gv_v8i16
ret void
}
define void @store_narrowing_v8i16_to_global_address(<8 x i8> %v) {
; CHECK-LABEL: store_narrowing_v8i16_to_global_address:
; CHECK: .functype store_narrowing_v8i16_to_global_address (v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane gv_v8i8, 0
; CHECK-NEXT: # fallthrough-return
store <8 x i8> %v , ptr @gv_v8i8
ret void
}
; ==============================================================================
; 4 x i32
; ==============================================================================
define <4 x i32> @load_v4i32(ptr %p) {
; CHECK-LABEL: load_v4i32:
; CHECK: .functype load_v4i32 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%v = load <4 x i32>, ptr %p
ret <4 x i32> %v
}
define <4 x i32> @load_splat_v4i32(ptr %addr) {
; CHECK-LABEL: load_splat_v4i32:
; CHECK: .functype load_splat_v4i32 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load32_splat 0
; CHECK-NEXT: # fallthrough-return
%e = load i32, ptr %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
}
define <4 x i32> @load_sext_v4i16_to_v4i32(ptr %p) {
; CHECK-LABEL: load_sext_v4i16_to_v4i32:
; CHECK: .functype load_sext_v4i16_to_v4i32 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32x4.load16x4_s 0
; CHECK-NEXT: # fallthrough-return
%v = load <4 x i16>, ptr %p
%v2 = sext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i16_to_v4i32(ptr %p) {
; CHECK-LABEL: load_zext_v4i16_to_v4i32:
; CHECK: .functype load_zext_v4i16_to_v4i32 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32x4.load16x4_u 0
; CHECK-NEXT: # fallthrough-return
%v = load <4 x i16>, ptr %p
%v2 = zext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_sext_v4i8_to_v4i32(ptr %p) {
; CHECK-LABEL: load_sext_v4i8_to_v4i32:
; CHECK: .functype load_sext_v4i8_to_v4i32 (i32) -> (v128)
; CHECK-NEXT: .local v128
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load32_zero 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i8x16.shuffle 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shl
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shr_s
; CHECK-NEXT: # fallthrough-return
%v = load <4 x i8>, ptr %p
%v2 = sext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i8_to_v4i32(ptr %p) {
; CHECK-LABEL: load_zext_v4i8_to_v4i32:
; CHECK: .functype load_zext_v4i8_to_v4i32 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: v128.const 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load32_zero 0
; CHECK-NEXT: i8x16.shuffle 16, 1, 2, 3, 17, 5, 6, 7, 18, 9, 10, 11, 19, 13, 14, 15
; CHECK-NEXT: # fallthrough-return
%v = load <4 x i8>, ptr %p
%v2 = zext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i16> @load_ext_v4i32(ptr %p) {
; CHECK-LABEL: load_ext_v4i32:
; CHECK: .functype load_ext_v4i32 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load64_zero 0
; CHECK-NEXT: # fallthrough-return
%v = load <4 x i16>, ptr %p
ret <4 x i16> %v
}
define <4 x i32> @load_v4i32_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_v4i32_with_folded_offset:
; CHECK: .functype load_v4i32_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <4 x i32>, ptr %s
ret <4 x i32> %v
}
define <4 x i32> @load_splat_v4i32_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_splat_v4i32_with_folded_offset:
; CHECK: .functype load_splat_v4i32_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load32_splat 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%e = load i32, ptr %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
}
define <4 x i32> @load_sext_v4i16_to_v4i32_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_sext_v4i16_to_v4i32_with_folded_offset:
; CHECK: .functype load_sext_v4i16_to_v4i32_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32x4.load16x4_s 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <4 x i16>, ptr %s
%v2 = sext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i16_to_v4i32_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_zext_v4i16_to_v4i32_with_folded_offset:
; CHECK: .functype load_zext_v4i16_to_v4i32_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32x4.load16x4_u 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <4 x i16>, ptr %s
%v2 = zext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_sext_v4i8_to_v4i32_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_sext_v4i8_to_v4i32_with_folded_offset:
; CHECK: .functype load_sext_v4i8_to_v4i32_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: .local v128
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load32_zero 16
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i8x16.shuffle 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shl
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shr_s
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <4 x i8>, ptr %s
%v2 = sext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i8_to_v4i32_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_zext_v4i8_to_v4i32_with_folded_offset:
; CHECK: .functype load_zext_v4i8_to_v4i32_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: v128.const 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load32_zero 16
; CHECK-NEXT: i8x16.shuffle 16, 1, 2, 3, 17, 5, 6, 7, 18, 9, 10, 11, 19, 13, 14, 15
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <4 x i8>, ptr %s
%v2 = zext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i16> @load_ext_v4i32_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_ext_v4i32_with_folded_offset:
; CHECK: .functype load_ext_v4i32_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load64_zero 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <4 x i16>, ptr %s
ret <4 x i16> %v
}
define <4 x i32> @load_v4i32_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_v4i32_with_folded_gep_offset:
; CHECK: .functype load_v4i32_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load 16
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i32>, ptr %p, i32 1
%v = load <4 x i32>, ptr %s
ret <4 x i32> %v
}
define <4 x i32> @load_splat_v4i32_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_splat_v4i32_with_folded_gep_offset:
; CHECK: .functype load_splat_v4i32_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load32_splat 4
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds i32, ptr %p, i32 1
%e = load i32, ptr %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
}
define <4 x i32> @load_sext_v4i16_to_v4i32_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_sext_v4i16_to_v4i32_with_folded_gep_offset:
; CHECK: .functype load_sext_v4i16_to_v4i32_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32x4.load16x4_s 8
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i16>, ptr %p, i32 1
%v = load <4 x i16>, ptr %s
%v2 = sext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i16_to_v4i32_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_zext_v4i16_to_v4i32_with_folded_gep_offset:
; CHECK: .functype load_zext_v4i16_to_v4i32_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32x4.load16x4_u 8
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i16>, ptr %p, i32 1
%v = load <4 x i16>, ptr %s
%v2 = zext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_sext_v4i8_to_v4i32_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_sext_v4i8_to_v4i32_with_folded_gep_offset:
; CHECK: .functype load_sext_v4i8_to_v4i32_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: .local v128
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load32_zero 4
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i8x16.shuffle 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shl
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shr_s
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i8>, ptr %p, i32 1
%v = load <4 x i8>, ptr %s
%v2 = sext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i8_to_v4i32_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_zext_v4i8_to_v4i32_with_folded_gep_offset:
; CHECK: .functype load_zext_v4i8_to_v4i32_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: v128.const 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load32_zero 4
; CHECK-NEXT: i8x16.shuffle 16, 1, 2, 3, 17, 5, 6, 7, 18, 9, 10, 11, 19, 13, 14, 15
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i8>, ptr %p, i32 1
%v = load <4 x i8>, ptr %s
%v2 = zext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i16> @load_ext_v4i32_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_ext_v4i32_with_folded_gep_offset:
; CHECK: .functype load_ext_v4i32_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load64_zero 8
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i16>, ptr %p, i32 1
%v = load <4 x i16>, ptr %s
ret <4 x i16> %v
}
define <4 x i32> @load_v4i32_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_v4i32_with_unfolded_gep_negative_offset:
; CHECK: .functype load_v4i32_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i32>, ptr %p, i32 -1
%v = load <4 x i32>, ptr %s
ret <4 x i32> %v
}
define <4 x i32> @load_splat_v4i32_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_splat_v4i32_with_unfolded_gep_negative_offset:
; CHECK: .functype load_splat_v4i32_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -4
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load32_splat 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds i32, ptr %p, i32 -1
%e = load i32, ptr %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
}
define <4 x i32> @load_sext_v4i16_to_v4i32_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_sext_v4i16_to_v4i32_with_unfolded_gep_negative_offset:
; CHECK: .functype load_sext_v4i16_to_v4i32_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -8
; CHECK-NEXT: i32.add
; CHECK-NEXT: i32x4.load16x4_s 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i16>, ptr %p, i32 -1
%v = load <4 x i16>, ptr %s
%v2 = sext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i16_to_v4i32_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_zext_v4i16_to_v4i32_with_unfolded_gep_negative_offset:
; CHECK: .functype load_zext_v4i16_to_v4i32_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -8
; CHECK-NEXT: i32.add
; CHECK-NEXT: i32x4.load16x4_u 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i16>, ptr %p, i32 -1
%v = load <4 x i16>, ptr %s
%v2 = zext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_sext_v4i8_to_v4i32_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_sext_v4i8_to_v4i32_with_unfolded_gep_negative_offset:
; CHECK: .functype load_sext_v4i8_to_v4i32_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: .local v128
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -4
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load32_zero 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i8x16.shuffle 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shl
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shr_s
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i8>, ptr %p, i32 -1
%v = load <4 x i8>, ptr %s
%v2 = sext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i8_to_v4i32_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_zext_v4i8_to_v4i32_with_unfolded_gep_negative_offset:
; CHECK: .functype load_zext_v4i8_to_v4i32_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: v128.const 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -4
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load32_zero 0
; CHECK-NEXT: i8x16.shuffle 16, 1, 2, 3, 17, 5, 6, 7, 18, 9, 10, 11, 19, 13, 14, 15
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i8>, ptr %p, i32 -1
%v = load <4 x i8>, ptr %s
%v2 = zext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i16> @load_ext_v4i32_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_ext_v4i32_with_unfolded_gep_negative_offset:
; CHECK: .functype load_ext_v4i32_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -8
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load64_zero 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i16>, ptr %p, i32 -1
%v = load <4 x i16>, ptr %s
ret <4 x i16> %v
}
define <4 x i32> @load_v4i32_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_v4i32_with_unfolded_offset:
; CHECK: .functype load_v4i32_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <4 x i32>, ptr %s
ret <4 x i32> %v
}
define <4 x i32> @load_splat_v4i32_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_splat_v4i32_with_unfolded_offset:
; CHECK: .functype load_splat_v4i32_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load32_splat 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%e = load i32, ptr %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
}
define <4 x i32> @load_sext_v4i16_to_v4i32_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_sext_v4i16_to_v4i32_with_unfolded_offset:
; CHECK: .functype load_sext_v4i16_to_v4i32_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: i32x4.load16x4_s 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <4 x i16>, ptr %s
%v2 = sext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i16_to_v4i32_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_zext_v4i16_to_v4i32_with_unfolded_offset:
; CHECK: .functype load_zext_v4i16_to_v4i32_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: i32x4.load16x4_u 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <4 x i16>, ptr %s
%v2 = zext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_sext_v4i8_to_v4i32_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_sext_v4i8_to_v4i32_with_unfolded_offset:
; CHECK: .functype load_sext_v4i8_to_v4i32_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: .local v128
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load32_zero 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i8x16.shuffle 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shl
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shr_s
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <4 x i8>, ptr %s
%v2 = sext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i8_to_v4i32_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_zext_v4i8_to_v4i32_with_unfolded_offset:
; CHECK: .functype load_zext_v4i8_to_v4i32_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: v128.const 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load32_zero 0
; CHECK-NEXT: i8x16.shuffle 16, 1, 2, 3, 17, 5, 6, 7, 18, 9, 10, 11, 19, 13, 14, 15
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <4 x i8>, ptr %s
%v2 = zext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i16> @load_ext_v4i32_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_ext_v4i32_with_unfolded_offset:
; CHECK: .functype load_ext_v4i32_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load64_zero 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <4 x i16>, ptr %s
ret <4 x i16> %v
}
define <4 x i32> @load_v4i32_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_v4i32_with_unfolded_gep_offset:
; CHECK: .functype load_v4i32_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <4 x i32>, ptr %p, i32 1
%v = load <4 x i32>, ptr %s
ret <4 x i32> %v
}
define <4 x i32> @load_splat_v4i32_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_splat_v4i32_with_unfolded_gep_offset:
; CHECK: .functype load_splat_v4i32_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load32_splat 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr i32, ptr %p, i32 1
%e = load i32, ptr %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
}
define <4 x i32> @load_sext_v4i16_to_v4i32_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_sext_v4i16_to_v4i32_with_unfolded_gep_offset:
; CHECK: .functype load_sext_v4i16_to_v4i32_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 8
; CHECK-NEXT: i32.add
; CHECK-NEXT: i32x4.load16x4_s 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <4 x i16>, ptr %p, i32 1
%v = load <4 x i16>, ptr %s
%v2 = sext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i16_to_v4i32_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_zext_v4i16_to_v4i32_with_unfolded_gep_offset:
; CHECK: .functype load_zext_v4i16_to_v4i32_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 8
; CHECK-NEXT: i32.add
; CHECK-NEXT: i32x4.load16x4_u 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <4 x i16>, ptr %p, i32 1
%v = load <4 x i16>, ptr %s
%v2 = zext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_sext_v4i8_to_v4i32_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_sext_v4i8_to_v4i32_with_unfolded_gep_offset:
; CHECK: .functype load_sext_v4i8_to_v4i32_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: .local v128
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load32_zero 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i8x16.shuffle 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shl
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shr_s
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <4 x i8>, ptr %p, i32 1
%v = load <4 x i8>, ptr %s
%v2 = sext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i8_to_v4i32_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_zext_v4i8_to_v4i32_with_unfolded_gep_offset:
; CHECK: .functype load_zext_v4i8_to_v4i32_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: v128.const 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load32_zero 0
; CHECK-NEXT: i8x16.shuffle 16, 1, 2, 3, 17, 5, 6, 7, 18, 9, 10, 11, 19, 13, 14, 15
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <4 x i8>, ptr %p, i32 1
%v = load <4 x i8>, ptr %s
%v2 = zext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i16> @load_ext_v4i32_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_ext_v4i32_with_unfolded_gep_offset:
; CHECK: .functype load_ext_v4i32_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 8
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load64_zero 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <4 x i16>, ptr %p, i32 1
%v = load <4 x i16>, ptr %s
ret <4 x i16> %v
}
define <4 x i32> @load_v4i32_from_numeric_address() {
; CHECK-LABEL: load_v4i32_from_numeric_address:
; CHECK: .functype load_v4i32_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%v = load <4 x i32>, ptr %s
ret <4 x i32> %v
}
define <4 x i32> @load_splat_v4i32_from_numeric_address() {
; CHECK-LABEL: load_splat_v4i32_from_numeric_address:
; CHECK: .functype load_splat_v4i32_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load32_splat 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%e = load i32, ptr %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
}
define <4 x i32> @load_sext_v4i16_to_v4i32_from_numeric_address() {
; CHECK-LABEL: load_sext_v4i16_to_v4i32_from_numeric_address:
; CHECK: .functype load_sext_v4i16_to_v4i32_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32x4.load16x4_s 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%v = load <4 x i16>, ptr %s
%v2 = sext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i16_to_v4i32_from_numeric_address() {
; CHECK-LABEL: load_zext_v4i16_to_v4i32_from_numeric_address:
; CHECK: .functype load_zext_v4i16_to_v4i32_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32x4.load16x4_u 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%v = load <4 x i16>, ptr %s
%v2 = zext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_sext_v4i8_to_v4i32_from_numeric_address() {
; CHECK-LABEL: load_sext_v4i8_to_v4i32_from_numeric_address:
; CHECK: .functype load_sext_v4i8_to_v4i32_from_numeric_address () -> (v128)
; CHECK-NEXT: .local v128
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load32_zero 32
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i8x16.shuffle 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shl
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shr_s
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%v = load <4 x i8>, ptr %s
%v2 = sext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i8_to_v4i32_from_numeric_address() {
; CHECK-LABEL: load_zext_v4i8_to_v4i32_from_numeric_address:
; CHECK: .functype load_zext_v4i8_to_v4i32_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: v128.const 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load32_zero 32
; CHECK-NEXT: i8x16.shuffle 16, 1, 2, 3, 17, 5, 6, 7, 18, 9, 10, 11, 19, 13, 14, 15
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%v = load <4 x i8>, ptr %s
%v2 = zext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i16> @load_ext_v4i32_from_numeric_address() {
; CHECK-LABEL: load_ext_v4i32_from_numeric_address:
; CHECK: .functype load_ext_v4i32_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load64_zero 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%v = load <4 x i16>, ptr %s
ret <4 x i16> %v
}
@gv_v4i32 = global <4 x i32> <i32 42, i32 42, i32 42, i32 42>
define <4 x i32> @load_v4i32_from_global_address() {
; CHECK-LABEL: load_v4i32_from_global_address:
; CHECK: .functype load_v4i32_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load gv_v4i32
; CHECK-NEXT: # fallthrough-return
%v = load <4 x i32>, ptr @gv_v4i32
ret <4 x i32> %v
}
@gv_i32 = global i32 42
define <4 x i32> @load_splat_v4i32_from_global_address() {
; CHECK-LABEL: load_splat_v4i32_from_global_address:
; CHECK: .functype load_splat_v4i32_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load32_splat gv_i32
; CHECK-NEXT: # fallthrough-return
%e = load i32, ptr @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
}
@gv_v4i16 = global <4 x i16> <i16 42, i16 42, i16 42, i16 42>
define <4 x i32> @load_sext_v4i16_to_v4i32_from_global_address() {
; CHECK-LABEL: load_sext_v4i16_to_v4i32_from_global_address:
; CHECK: .functype load_sext_v4i16_to_v4i32_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32x4.load16x4_s gv_v4i16
; CHECK-NEXT: # fallthrough-return
%v = load <4 x i16>, ptr @gv_v4i16
%v2 = sext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i16_to_v4i32_from_global_address() {
; CHECK-LABEL: load_zext_v4i16_to_v4i32_from_global_address:
; CHECK: .functype load_zext_v4i16_to_v4i32_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32x4.load16x4_u gv_v4i16
; CHECK-NEXT: # fallthrough-return
%v = load <4 x i16>, ptr @gv_v4i16
%v2 = zext <4 x i16> %v to <4 x i32>
ret <4 x i32> %v2
}
@gv_v4i8 = global <4 x i8> <i8 42, i8 42, i8 42, i8 42>
define <4 x i32> @load_sext_v4i8_to_v4i32_from_global_address() {
; CHECK-LABEL: load_sext_v4i8_to_v4i32_from_global_address:
; CHECK: .functype load_sext_v4i8_to_v4i32_from_global_address () -> (v128)
; CHECK-NEXT: .local v128
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load32_zero gv_v4i8
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i8x16.shuffle 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shl
; CHECK-NEXT: i32.const 24
; CHECK-NEXT: i32x4.shr_s
; CHECK-NEXT: # fallthrough-return
%v = load <4 x i8>, ptr @gv_v4i8
%v2 = sext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i32> @load_zext_v4i8_to_v4i32_from_global_address() {
; CHECK-LABEL: load_zext_v4i8_to_v4i32_from_global_address:
; CHECK: .functype load_zext_v4i8_to_v4i32_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: v128.const 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load32_zero gv_v4i8
; CHECK-NEXT: i8x16.shuffle 16, 1, 2, 3, 17, 5, 6, 7, 18, 9, 10, 11, 19, 13, 14, 15
; CHECK-NEXT: # fallthrough-return
%v = load <4 x i8>, ptr @gv_v4i8
%v2 = zext <4 x i8> %v to <4 x i32>
ret <4 x i32> %v2
}
define <4 x i16> @load_ext_v4i32_from_global_address() {
; CHECK-LABEL: load_ext_v4i32_from_global_address:
; CHECK: .functype load_ext_v4i32_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load64_zero gv_v4i16
; CHECK-NEXT: # fallthrough-return
%v = load <4 x i16>, ptr @gv_v4i16
ret <4 x i16> %v
}
define void @store_v4i32(<4 x i32> %v, ptr %p) {
; CHECK-LABEL: store_v4i32:
; CHECK: .functype store_v4i32 (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 0
; CHECK-NEXT: # fallthrough-return
store <4 x i32> %v , ptr %p
ret void
}
define void @store_narrowing_v4i32(<4 x i16> %v, ptr %p) {
; CHECK-LABEL: store_narrowing_v4i32:
; CHECK: .functype store_narrowing_v4i32 (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane 0, 0
; CHECK-NEXT: # fallthrough-return
store <4 x i16> %v , ptr %p
ret void
}
define void @store_v4i32_with_folded_offset(<4 x i32> %v, ptr %p) {
; CHECK-LABEL: store_v4i32_with_folded_offset:
; CHECK: .functype store_v4i32_with_folded_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
store <4 x i32> %v , ptr %s
ret void
}
define void @store_narrowing_v4i32_with_folded_offset(<4 x i16> %v, ptr %p) {
; CHECK-LABEL: store_narrowing_v4i32_with_folded_offset:
; CHECK: .functype store_narrowing_v4i32_with_folded_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane 16, 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
store <4 x i16> %v , ptr %s
ret void
}
define void @store_v4i32_with_folded_gep_offset(<4 x i32> %v, ptr %p) {
; CHECK-LABEL: store_v4i32_with_folded_gep_offset:
; CHECK: .functype store_v4i32_with_folded_gep_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 16
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i32>, ptr %p, i32 1
store <4 x i32> %v , ptr %s
ret void
}
define void @store_narrowing_v4i32_with_folded_gep_offset(<4 x i16> %v, ptr %p) {
; CHECK-LABEL: store_narrowing_v4i32_with_folded_gep_offset:
; CHECK: .functype store_narrowing_v4i32_with_folded_gep_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane 8, 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i16>, ptr %p, i32 1
store <4 x i16> %v , ptr %s
ret void
}
define void @store_v4i32_with_unfolded_gep_negative_offset(<4 x i32> %v, ptr %p) {
; CHECK-LABEL: store_v4i32_with_unfolded_gep_negative_offset:
; CHECK: .functype store_v4i32_with_unfolded_gep_negative_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const -16
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i32>, ptr %p, i32 -1
store <4 x i32> %v , ptr %s
ret void
}
define void @store_narrowing_v4i32_with_unfolded_gep_negative_offset(<4 x i16> %v, ptr %p) {
; CHECK-LABEL: store_narrowing_v4i32_with_unfolded_gep_negative_offset:
; CHECK: .functype store_narrowing_v4i32_with_unfolded_gep_negative_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const -8
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane 0, 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <4 x i16>, ptr %p, i32 -1
store <4 x i16> %v , ptr %s
ret void
}
define void @store_v4i32_with_unfolded_offset(<4 x i32> %v, ptr %p) {
; CHECK-LABEL: store_v4i32_with_unfolded_offset:
; CHECK: .functype store_v4i32_with_unfolded_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
store <4 x i32> %v , ptr %s
ret void
}
define void @store_narrowing_v4i32_with_unfolded_offset(<4 x i16> %v, ptr %p) {
; CHECK-LABEL: store_narrowing_v4i32_with_unfolded_offset:
; CHECK: .functype store_narrowing_v4i32_with_unfolded_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane 0, 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
store <4 x i16> %v , ptr %s
ret void
}
define void @store_v4i32_with_unfolded_gep_offset(<4 x i32> %v, ptr %p) {
; CHECK-LABEL: store_v4i32_with_unfolded_gep_offset:
; CHECK: .functype store_v4i32_with_unfolded_gep_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <4 x i32>, ptr %p, i32 1
store <4 x i32> %v , ptr %s
ret void
}
define void @store_narrowing_v4i32_with_unfolded_gep_offset(<4 x i16> %v, ptr %p) {
; CHECK-LABEL: store_narrowing_v4i32_with_unfolded_gep_offset:
; CHECK: .functype store_narrowing_v4i32_with_unfolded_gep_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 8
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane 0, 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <4 x i16>, ptr %p, i32 1
store <4 x i16> %v , ptr %s
ret void
}
define void @store_v4i32_to_numeric_address(<4 x i32> %v) {
; CHECK-LABEL: store_v4i32_to_numeric_address:
; CHECK: .functype store_v4i32_to_numeric_address (v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
store <4 x i32> %v , ptr %s
ret void
}
define void @store_narrowing_v4i32_to_numeric_address(<4 x i16> %v) {
; CHECK-LABEL: store_narrowing_v4i32_to_numeric_address:
; CHECK: .functype store_narrowing_v4i32_to_numeric_address (v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane 32, 0
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
store <4 x i16> %v , ptr %s
ret void
}
define void @store_v4i32_to_global_address(<4 x i32> %v) {
; CHECK-LABEL: store_v4i32_to_global_address:
; CHECK: .functype store_v4i32_to_global_address (v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store gv_v4i32
; CHECK-NEXT: # fallthrough-return
store <4 x i32> %v , ptr @gv_v4i32
ret void
}
define void @store_narrowing_v4i32_to_global_address(<4 x i16> %v) {
; CHECK-LABEL: store_narrowing_v4i32_to_global_address:
; CHECK: .functype store_narrowing_v4i32_to_global_address (v128) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store64_lane gv_v4i16, 0
; CHECK-NEXT: # fallthrough-return
store <4 x i16> %v , ptr @gv_v4i16
ret void
}
; ==============================================================================
; 2 x i64
; ==============================================================================
define <2 x i64> @load_v2i64(ptr %p) {
; CHECK-LABEL: load_v2i64:
; CHECK: .functype load_v2i64 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%v = load <2 x i64>, ptr %p
ret <2 x i64> %v
}
define <2 x i64> @load_splat_v2i64(ptr %p) {
; CHECK-LABEL: load_splat_v2i64:
; CHECK: .functype load_splat_v2i64 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load64_splat 0
; CHECK-NEXT: # fallthrough-return
%e = load i64, ptr %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
}
define <2 x i64> @load_sext_v2i64(ptr %p) {
; CHECK-LABEL: load_sext_v2i64:
; CHECK: .functype load_sext_v2i64 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64x2.load32x2_s 0
; CHECK-NEXT: # fallthrough-return
%v = load <2 x i32>, ptr %p
%v2 = sext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i64> @load_zext_v2i64(ptr %p) {
; CHECK-LABEL: load_zext_v2i64:
; CHECK: .functype load_zext_v2i64 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64x2.load32x2_u 0
; CHECK-NEXT: # fallthrough-return
%v = load <2 x i32>, ptr %p
%v2 = zext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i32> @load_ext_v2i64(ptr %p) {
; CHECK-LABEL: load_ext_v2i64:
; CHECK: .functype load_ext_v2i64 (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load64_zero 0
; CHECK-NEXT: # fallthrough-return
%v = load <2 x i32>, ptr %p
ret <2 x i32> %v
}
define <2 x i64> @load_v2i64_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_v2i64_with_folded_offset:
; CHECK: .functype load_v2i64_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <2 x i64>, ptr %s
ret <2 x i64> %v
}
define <2 x i64> @load_splat_v2i64_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_splat_v2i64_with_folded_offset:
; CHECK: .functype load_splat_v2i64_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load64_splat 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%e = load i64, ptr %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
}
define <2 x i64> @load_sext_v2i64_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_sext_v2i64_with_folded_offset:
; CHECK: .functype load_sext_v2i64_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64x2.load32x2_s 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <2 x i32>, ptr %s
%v2 = sext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i64> @load_zext_v2i64_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_zext_v2i64_with_folded_offset:
; CHECK: .functype load_zext_v2i64_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64x2.load32x2_u 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <2 x i32>, ptr %s
%v2 = zext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i32> @load_ext_v2i64_with_folded_offset(ptr %p) {
; CHECK-LABEL: load_ext_v2i64_with_folded_offset:
; CHECK: .functype load_ext_v2i64_with_folded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load64_zero 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <2 x i32>, ptr %s
ret <2 x i32> %v
}
define <2 x i64> @load_v2i64_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_v2i64_with_folded_gep_offset:
; CHECK: .functype load_v2i64_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load 16
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <2 x i64>, ptr %p, i32 1
%v = load <2 x i64>, ptr %s
ret <2 x i64> %v
}
define <2 x i64> @load_splat_v2i64_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_splat_v2i64_with_folded_gep_offset:
; CHECK: .functype load_splat_v2i64_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load64_splat 8
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds i64, ptr %p, i32 1
%e = load i64, ptr %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
}
define <2 x i64> @load_sext_v2i64_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_sext_v2i64_with_folded_gep_offset:
; CHECK: .functype load_sext_v2i64_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64x2.load32x2_s 8
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <2 x i32>, ptr %p, i32 1
%v = load <2 x i32>, ptr %s
%v2 = sext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i64> @load_zext_v2i64_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_zext_v2i64_with_folded_gep_offset:
; CHECK: .functype load_zext_v2i64_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64x2.load32x2_u 8
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <2 x i32>, ptr %p, i32 1
%v = load <2 x i32>, ptr %s
%v2 = zext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i32> @load_ext_v2i64_with_folded_gep_offset(ptr %p) {
; CHECK-LABEL: load_ext_v2i64_with_folded_gep_offset:
; CHECK: .functype load_ext_v2i64_with_folded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.load64_zero 8
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <2 x i32>, ptr %p, i32 1
%v = load <2 x i32>, ptr %s
ret <2 x i32> %v
}
define <2 x i64> @load_v2i64_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_v2i64_with_unfolded_gep_negative_offset:
; CHECK: .functype load_v2i64_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <2 x i64>, ptr %p, i32 -1
%v = load <2 x i64>, ptr %s
ret <2 x i64> %v
}
define <2 x i64> @load_splat_v2i64_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_splat_v2i64_with_unfolded_gep_negative_offset:
; CHECK: .functype load_splat_v2i64_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -8
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load64_splat 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds i64, ptr %p, i32 -1
%e = load i64, ptr %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
}
define <2 x i64> @load_sext_v2i64_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_sext_v2i64_with_unfolded_gep_negative_offset:
; CHECK: .functype load_sext_v2i64_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -8
; CHECK-NEXT: i32.add
; CHECK-NEXT: i64x2.load32x2_s 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <2 x i32>, ptr %p, i32 -1
%v = load <2 x i32>, ptr %s
%v2 = sext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i64> @load_zext_v2i64_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_zext_v2i64_with_unfolded_gep_negative_offset:
; CHECK: .functype load_zext_v2i64_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -8
; CHECK-NEXT: i32.add
; CHECK-NEXT: i64x2.load32x2_u 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <2 x i32>, ptr %p, i32 -1
%v = load <2 x i32>, ptr %s
%v2 = zext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i32> @load_ext_v2i64_with_unfolded_gep_negative_offset(ptr %p) {
; CHECK-LABEL: load_ext_v2i64_with_unfolded_gep_negative_offset:
; CHECK: .functype load_ext_v2i64_with_unfolded_gep_negative_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const -8
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load64_zero 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <2 x i32>, ptr %p, i32 -1
%v = load <2 x i32>, ptr %s
ret <2 x i32> %v
}
define <2 x i64> @load_v2i64_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_v2i64_with_unfolded_offset:
; CHECK: .functype load_v2i64_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <2 x i64>, ptr %s
ret <2 x i64> %v
}
define <2 x i64> @load_splat_v2i64_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_splat_v2i64_with_unfolded_offset:
; CHECK: .functype load_splat_v2i64_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load64_splat 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%e = load i64, ptr %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
}
define <2 x i64> @load_sext_v2i64_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_sext_v2i64_with_unfolded_offset:
; CHECK: .functype load_sext_v2i64_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: i64x2.load32x2_s 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <2 x i32>, ptr %s
%v2 = sext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i64> @load_zext_v2i64_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_zext_v2i64_with_unfolded_offset:
; CHECK: .functype load_zext_v2i64_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: i64x2.load32x2_u 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <2 x i32>, ptr %s
%v2 = zext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i32> @load_ext_v2i64_with_unfolded_offset(ptr %p) {
; CHECK-LABEL: load_ext_v2i64_with_unfolded_offset:
; CHECK: .functype load_ext_v2i64_with_unfolded_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load64_zero 0
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nsw i32 %q, 16
%s = inttoptr i32 %r to ptr
%v = load <2 x i32>, ptr %s
ret <2 x i32> %v
}
define <2 x i64> @load_v2i64_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_v2i64_with_unfolded_gep_offset:
; CHECK: .functype load_v2i64_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <2 x i64>, ptr %p, i32 1
%v = load <2 x i64>, ptr %s
ret <2 x i64> %v
}
define <2 x i64> @load_splat_v2i64_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_splat_v2i64_with_unfolded_gep_offset:
; CHECK: .functype load_splat_v2i64_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 8
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load64_splat 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr i64, ptr %p, i32 1
%e = load i64, ptr %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
}
define <2 x i64> @load_sext_v2i64_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_sext_v2i64_with_unfolded_gep_offset:
; CHECK: .functype load_sext_v2i64_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 8
; CHECK-NEXT: i32.add
; CHECK-NEXT: i64x2.load32x2_s 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <2 x i32>, ptr %p, i32 1
%v = load <2 x i32>, ptr %s
%v2 = sext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i64> @load_zext_v2i64_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_zext_v2i64_with_unfolded_gep_offset:
; CHECK: .functype load_zext_v2i64_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 8
; CHECK-NEXT: i32.add
; CHECK-NEXT: i64x2.load32x2_u 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <2 x i32>, ptr %p, i32 1
%v = load <2 x i32>, ptr %s
%v2 = zext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i32> @load_ext_v2i64_with_unfolded_gep_offset(ptr %p) {
; CHECK-LABEL: load_ext_v2i64_with_unfolded_gep_offset:
; CHECK: .functype load_ext_v2i64_with_unfolded_gep_offset (i32) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 8
; CHECK-NEXT: i32.add
; CHECK-NEXT: v128.load64_zero 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr <2 x i32>, ptr %p, i32 1
%v = load <2 x i32>, ptr %s
ret <2 x i32> %v
}
define <2 x i64> @load_v2i64_from_numeric_address() {
; CHECK-LABEL: load_v2i64_from_numeric_address:
; CHECK: .functype load_v2i64_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%v = load <2 x i64>, ptr %s
ret <2 x i64> %v
}
define <2 x i64> @load_splat_v2i64_from_numeric_address() {
; CHECK-LABEL: load_splat_v2i64_from_numeric_address:
; CHECK: .functype load_splat_v2i64_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load64_splat 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%e = load i64, ptr %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
}
define <2 x i64> @load_sext_v2i64_from_numeric_address() {
; CHECK-LABEL: load_sext_v2i64_from_numeric_address:
; CHECK: .functype load_sext_v2i64_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i64x2.load32x2_s 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%v = load <2 x i32>, ptr %s
%v2 = sext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i64> @load_zext_v2i64_from_numeric_address() {
; CHECK-LABEL: load_zext_v2i64_from_numeric_address:
; CHECK: .functype load_zext_v2i64_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i64x2.load32x2_u 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%v = load <2 x i32>, ptr %s
%v2 = zext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i32> @load_ext_v2i64_from_numeric_address() {
; CHECK-LABEL: load_ext_v2i64_from_numeric_address:
; CHECK: .functype load_ext_v2i64_from_numeric_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load64_zero 32
; CHECK-NEXT: # fallthrough-return
%s = inttoptr i32 32 to ptr
%v = load <2 x i32>, ptr %s
ret <2 x i32> %v
}
@gv_v2i64 = global <2 x i64> <i64 42, i64 42>
define <2 x i64> @load_v2i64_from_global_address() {
; CHECK-LABEL: load_v2i64_from_global_address:
; CHECK: .functype load_v2i64_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load gv_v2i64
; CHECK-NEXT: # fallthrough-return
%v = load <2 x i64>, ptr @gv_v2i64
ret <2 x i64> %v
}
@gv_i64 = global i64 42
define <2 x i64> @load_splat_v2i64_from_global_address() {
; CHECK-LABEL: load_splat_v2i64_from_global_address:
; CHECK: .functype load_splat_v2i64_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load64_splat gv_i64
; CHECK-NEXT: # fallthrough-return
%e = load i64, ptr @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
}
@gv_v2i32 = global <2 x i32> <i32 42, i32 42>
define <2 x i64> @load_sext_v2i64_from_global_address() {
; CHECK-LABEL: load_sext_v2i64_from_global_address:
; CHECK: .functype load_sext_v2i64_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i64x2.load32x2_s gv_v2i32
; CHECK-NEXT: # fallthrough-return
%v = load <2 x i32>, ptr @gv_v2i32
%v2 = sext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i64> @load_zext_v2i64_from_global_address() {
; CHECK-LABEL: load_zext_v2i64_from_global_address:
; CHECK: .functype load_zext_v2i64_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i64x2.load32x2_u gv_v2i32
; CHECK-NEXT: # fallthrough-return
%v = load <2 x i32>, ptr @gv_v2i32
%v2 = zext <2 x i32> %v to <2 x i64>
ret <2 x i64> %v2
}
define <2 x i32> @load_ext_v2i64_from_global_address() {
; CHECK-LABEL: load_ext_v2i64_from_global_address:
; CHECK: .functype load_ext_v2i64_from_global_address () -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: v128.load64_zero gv_v2i32
; CHECK-NEXT: # fallthrough-return
%v = load <2 x i32>, ptr @gv_v2i32
ret <2 x i32> %v
}
define void @store_v2i64(<2 x i64> %v, ptr %p) {
; CHECK-LABEL: store_v2i64:
; CHECK: .functype store_v2i64 (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 0
; CHECK-NEXT: # fallthrough-return
store <2 x i64> %v , ptr %p
ret void
}
define void @store_v2i64_with_folded_offset(<2 x i64> %v, ptr %p) {
; CHECK-LABEL: store_v2i64_with_folded_offset:
; CHECK: .functype store_v2i64_with_folded_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 16
; CHECK-NEXT: # fallthrough-return
%q = ptrtoint ptr %p to i32
%r = add nuw i32 %q, 16
%s = inttoptr i32 %r to ptr
store <2 x i64> %v , ptr %s
ret void
}
define void @store_v2i64_with_folded_gep_offset(<2 x i64> %v, ptr %p) {
; CHECK-LABEL: store_v2i64_with_folded_gep_offset:
; CHECK: .functype store_v2i64_with_folded_gep_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 16
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <2 x i64>, ptr %p, i32 1
store <2 x i64> %v , ptr %s
ret void
}
define void @store_v2i64_with_unfolded_gep_negative_offset(<2 x i64> %v, ptr %p) {
; CHECK-LABEL: store_v2i64_with_unfolded_gep_negative_offset:
; CHECK: .functype store_v2i64_with_unfolded_gep_negative_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const -16
; CHECK-NEXT: i32.add
; CHECK-NEXT: local.get 0
; CHECK-NEXT: v128.store 0
; CHECK-NEXT: # fallthrough-return
%s = getelementptr inbounds <2 x i64>, ptr %p, i32 -1
store <2 x i64> %v , ptr %s
ret void
}
define void @store_v2i64_with_unfolded_offset(<2 x i64> %v, ptr %p) {
; CHECK-LABEL: store_v2i64_with_unfolded_offset:
; CHECK: .functype store_v2i64_with_unfolded_offset (v128, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add