; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -p vector-combine -mtriple=arm64-apple-macosx -S %s | FileCheck %s

declare void @use.i32(i32)
declare void @use.v2i32(<2 x i32>)
declare void @use.v8i8(<8 x i8>)
declare void @use.v8i16(<8 x i16>)
declare void @use.v4i16(<4 x i16>)

define <4 x i32> @load_i32_zext_to_v4i32(ptr %di) {
; CHECK-LABEL: define <4 x i32> @load_i32_zext_to_v4i32(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[E_1:%.*]] = zext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[E_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext nneg <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %e.1 = zext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %e.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %ext.2 = zext nneg <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}

define <4 x i32> @load_i32_zext_to_v4i32_both_nneg(ptr %di) {
; CHECK-LABEL: define <4 x i32> @load_i32_zext_to_v4i32_both_nneg(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[E_1:%.*]] = zext nneg <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[E_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext nneg <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %e.1 = zext nneg <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %e.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %ext.2 = zext nneg <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}

define <4 x i32> @load_i32_zext_to_v4i32_inner_nneg(ptr %di) {
; CHECK-LABEL: define <4 x i32> @load_i32_zext_to_v4i32_inner_nneg(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[E_1:%.*]] = zext nneg <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[E_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %e.1 = zext nneg <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %e.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %ext.2 = zext <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}

define <4 x i32> @load_i32_zext_to_v4i32_outer_nneg(ptr %di) {
; CHECK-LABEL: define <4 x i32> @load_i32_zext_to_v4i32_outer_nneg(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[E_1:%.*]] = zext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[E_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext nneg <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %e.1 = zext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %e.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %ext.2 = zext nneg <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}

define <4 x i32> @load_i32_zext_to_v4i32_inner_nneg_outer_sext(ptr %di) {
; CHECK-LABEL: define <4 x i32> @load_i32_zext_to_v4i32_inner_nneg_outer_sext(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[E_1:%.*]] = zext nneg <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[E_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT:    [[EXT_2:%.*]] = sext <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %e.1 = zext nneg <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %e.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %ext.2 = sext <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}

define <4 x i32> @load_i32_zext_to_v4i32_clobber_after_load(ptr %di) {
; CHECK-LABEL: define <4 x i32> @load_i32_zext_to_v4i32_clobber_after_load(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    call void @use.i32(i32 0)
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[E_1:%.*]] = zext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[E_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext nneg <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  call void @use.i32(i32 0)
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %e.1 = zext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %e.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %ext.2 = zext nneg <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}

define <4 x i32> @load_i32_sext_zext_to_v4i32(ptr %di) {
; CHECK-LABEL: define <4 x i32> @load_i32_sext_zext_to_v4i32(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[E_1:%.*]] = sext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[E_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %e.1 = sext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %e.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %ext.2 = zext <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}

define <4 x i32> @load_i32_zext_to_v4i32_load_other_users(ptr %di) {
; CHECK-LABEL: define <4 x i32> @load_i32_zext_to_v4i32_load_other_users(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[E_1:%.*]] = zext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[E_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext nneg <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    call void @use.i32(i32 [[L]])
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %e.1 = zext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %e.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %ext.2 = zext nneg <4 x i16> %vec.shuffle to <4 x i32>
  call void @use.i32(i32 %l)
  ret <4 x i32> %ext.2
}

define <4 x i32> @load_i32_zext_to_v4i32_ins_other_users(ptr %di) {
; CHECK-LABEL: define <4 x i32> @load_i32_zext_to_v4i32_ins_other_users(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[E_1:%.*]] = zext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[E_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext nneg <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    call void @use.v2i32(<2 x i32> [[VEC_INS]])
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %e.1 = zext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %e.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %ext.2 = zext nneg <4 x i16> %vec.shuffle to <4 x i32>
  call void @use.v2i32(<2 x i32> %vec.ins)
  ret <4 x i32> %ext.2
}

define <4 x i32> @load_i32_zext_to_v4i32_bc_other_users(ptr %di) {
; CHECK-LABEL: define <4 x i32> @load_i32_zext_to_v4i32_bc_other_users(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[E_1:%.*]] = zext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[E_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext nneg <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    call void @use.v8i8(<8 x i8> [[VEC_BC]])
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %e.1 = zext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %e.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %ext.2 = zext nneg <4 x i16> %vec.shuffle to <4 x i32>
  call void @use.v8i8(<8 x i8> %vec.bc)
  ret <4 x i32> %ext.2
}

define <4 x i32> @load_i32_zext_to_v4i32_ext_other_users(ptr %di) {
; CHECK-LABEL: define <4 x i32> @load_i32_zext_to_v4i32_ext_other_users(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[E_1:%.*]] = zext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[E_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext nneg <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    call void @use.v8i16(<8 x i16> [[E_1]])
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %e.1 = zext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %e.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %ext.2 = zext nneg <4 x i16> %vec.shuffle to <4 x i32>
  call void @use.v8i16(<8 x i16> %e.1)
  ret <4 x i32> %ext.2
}

define <4 x i32> @load_i32_zext_to_v4i32_shuffle_other_users(ptr %di) {
; CHECK-LABEL: define <4 x i32> @load_i32_zext_to_v4i32_shuffle_other_users(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[E_1:%.*]] = zext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[E_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext nneg <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    call void @use.v8i16(<4 x i16> [[VEC_SHUFFLE]])
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %e.1 = zext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %e.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %ext.2 = zext nneg <4 x i16> %vec.shuffle to <4 x i32>
  call void @use.v8i16(<4 x i16> %vec.shuffle)
  ret <4 x i32> %ext.2
}

define <8 x i32> @load_i64_zext_to_v8i32(ptr %di) {
; CHECK-LABEL: define <8 x i32> @load_i64_zext_to_v8i32(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i64, ptr [[DI]], align 8
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i64> <i64 poison, i64 0>, i64 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i64> [[VEC_INS]] to <16 x i8>
; CHECK-NEXT:    [[EXT_1:%.*]] = zext <16 x i8> [[VEC_BC]] to <16 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <16 x i16> [[EXT_1]], <16 x i16> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
; CHECK-NEXT:    [[OUTER_EXT:%.*]] = zext nneg <8 x i16> [[VEC_SHUFFLE]] to <8 x i32>
; CHECK-NEXT:    ret <8 x i32> [[OUTER_EXT]]
;
entry:
  %l = load i64, ptr %di
  %vec.ins = insertelement <2 x i64> <i64 poison, i64 0>, i64 %l, i64 0
  %vec.bc = bitcast <2 x i64> %vec.ins to <16 x i8>
  %ext.1 = zext <16 x i8> %vec.bc to <16 x i16>
  %vec.shuffle = shufflevector <16 x i16> %ext.1, <16 x i16> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
  %outer.ext = zext nneg <8 x i16> %vec.shuffle to <8 x i32>
  ret <8 x i32> %outer.ext
}

define <3 x i32> @load_i24_zext_to_v3i32(ptr %di) {
; CHECK-LABEL: define <3 x i32> @load_i24_zext_to_v3i32(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i24, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i24> <i24 poison, i24 0>, i24 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i24> [[VEC_INS]] to <6 x i8>
; CHECK-NEXT:    [[EXT_1:%.*]] = zext <6 x i8> [[VEC_BC]] to <6 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <6 x i16> [[EXT_1]], <6 x i16> poison, <3 x i32> <i32 0, i32 1, i32 2>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext nneg <3 x i16> [[VEC_SHUFFLE]] to <3 x i32>
; CHECK-NEXT:    ret <3 x i32> [[EXT_2]]
;
entry:
  %l = load i24, ptr %di
  %vec.ins = insertelement <2 x i24> <i24 poison, i24 0>, i24 %l, i64 0
  %vec.bc = bitcast <2 x i24> %vec.ins to <6 x i8>
  %ext.1 = zext <6 x i8> %vec.bc to <6 x i16>
  %vec.shuffle = shufflevector <6 x i16> %ext.1, <6 x i16> poison, <3 x i32> <i32 0, i32 1, i32 2>
  %ext.2 = zext nneg <3 x i16> %vec.shuffle to <3 x i32>
  ret <3 x i32> %ext.2
}

define <4 x i32> @load_i32_insert_idx_1_sext(ptr %di) {
; CHECK-LABEL: define <4 x i32> @load_i32_insert_idx_1_sext(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 0, i32 poison>, i32 [[L]], i64 1
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[EXT_1:%.*]] = zext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[EXT_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext nneg <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 0, i32 poison>, i32 %l, i64 1
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %ext.1 = zext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %ext.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %ext.2 = zext nneg <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}

define <4 x i32> @mask_extracts_not_all_elements_1_sext(ptr %di) {
; CHECK-LABEL: define <4 x i32> @mask_extracts_not_all_elements_1_sext(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[EXT_1:%.*]] = zext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[EXT_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 2>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext nneg <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %ext.1 = zext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %ext.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 2>
  %ext.2 = zext nneg <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}

define <4 x i32> @mask_extracts_not_all_elements_2_sext(ptr %di) {
; CHECK-LABEL: define <4 x i32> @mask_extracts_not_all_elements_2_sext(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[EXT_1:%.*]] = zext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[EXT_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 4>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext nneg <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %ext.1 = zext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %ext.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 4>
  %ext.2 = zext nneg <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}

define <4 x i32> @mask_extracts_second_vector_sext(ptr %di, <8 x i16> %other) {
; CHECK-LABEL: define <4 x i32> @mask_extracts_second_vector_sext(
; CHECK-SAME: ptr [[DI:%.*]], <8 x i16> [[OTHER:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[EXT_1:%.*]] = zext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[EXT_1]], <8 x i16> [[OTHER]], <4 x i32> <i32 4, i32 5, i32 6, i32 7>
; CHECK-NEXT:    [[EXT_2:%.*]] = zext nneg <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %ext.1 = zext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %ext.1, <8 x i16> %other, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
  %ext.2 = zext nneg <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}

define <4 x i32> @load_i32_sext_to_v4i32(ptr %di) {
; CHECK-LABEL: define <4 x i32> @load_i32_sext_to_v4i32(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[E_1:%.*]] = sext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[E_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT:    [[EXT_2:%.*]] = sext <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %e.1 = sext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %e.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %ext.2 = sext <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}

define <8 x i32> @load_i64_sext_to_v8i32(ptr %di) {
; CHECK-LABEL: define <8 x i32> @load_i64_sext_to_v8i32(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i64, ptr [[DI]], align 8
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i64> <i64 poison, i64 0>, i64 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i64> [[VEC_INS]] to <16 x i8>
; CHECK-NEXT:    [[EXT_1:%.*]] = sext <16 x i8> [[VEC_BC]] to <16 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <16 x i16> [[EXT_1]], <16 x i16> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
; CHECK-NEXT:    [[OUTER_EXT:%.*]] = sext <8 x i16> [[VEC_SHUFFLE]] to <8 x i32>
; CHECK-NEXT:    ret <8 x i32> [[OUTER_EXT]]
;
entry:
  %l = load i64, ptr %di
  %vec.ins = insertelement <2 x i64> <i64 poison, i64 0>, i64 %l, i64 0
  %vec.bc = bitcast <2 x i64> %vec.ins to <16 x i8>
  %ext.1 = sext <16 x i8> %vec.bc to <16 x i16>
  %vec.shuffle = shufflevector <16 x i16> %ext.1, <16 x i16> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
  %outer.ext = sext <8 x i16> %vec.shuffle to <8 x i32>
  ret <8 x i32> %outer.ext
}

define <3 x i32> @load_i24_sext_to_v3i32(ptr %di) {
; CHECK-LABEL: define <3 x i32> @load_i24_sext_to_v3i32(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i24, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i24> <i24 poison, i24 0>, i24 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i24> [[VEC_INS]] to <6 x i8>
; CHECK-NEXT:    [[EXT_1:%.*]] = sext <6 x i8> [[VEC_BC]] to <6 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <6 x i16> [[EXT_1]], <6 x i16> poison, <3 x i32> <i32 0, i32 1, i32 2>
; CHECK-NEXT:    [[EXT_2:%.*]] = sext <3 x i16> [[VEC_SHUFFLE]] to <3 x i32>
; CHECK-NEXT:    ret <3 x i32> [[EXT_2]]
;
entry:
  %l = load i24, ptr %di
  %vec.ins = insertelement <2 x i24> <i24 poison, i24 0>, i24 %l, i64 0
  %vec.bc = bitcast <2 x i24> %vec.ins to <6 x i8>
  %ext.1 = sext <6 x i8> %vec.bc to <6 x i16>
  %vec.shuffle = shufflevector <6 x i16> %ext.1, <6 x i16> poison, <3 x i32> <i32 0, i32 1, i32 2>
  %ext.2 = sext <3 x i16> %vec.shuffle to <3 x i32>
  ret <3 x i32> %ext.2
}

define <4 x i32> @load_i32_insert_idx_1(ptr %di) {
; CHECK-LABEL: define <4 x i32> @load_i32_insert_idx_1(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 0, i32 poison>, i32 [[L]], i64 1
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[EXT_1:%.*]] = sext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[EXT_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT:    [[EXT_2:%.*]] = sext <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 0, i32 poison>, i32 %l, i64 1
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %ext.1 = sext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %ext.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %ext.2 = sext <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}

define <4 x i32> @mask_extracts_not_all_elements_1(ptr %di) {
; CHECK-LABEL: define <4 x i32> @mask_extracts_not_all_elements_1(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[EXT_1:%.*]] = sext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[EXT_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 2>
; CHECK-NEXT:    [[EXT_2:%.*]] = sext <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %ext.1 = sext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %ext.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 2>
  %ext.2 = sext <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}

define <4 x i32> @mask_extracts_not_all_elements_2(ptr %di) {
; CHECK-LABEL: define <4 x i32> @mask_extracts_not_all_elements_2(
; CHECK-SAME: ptr [[DI:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[EXT_1:%.*]] = sext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[EXT_1]], <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 4>
; CHECK-NEXT:    [[EXT_2:%.*]] = sext <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %ext.1 = sext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %ext.1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 4>
  %ext.2 = sext <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}

define <4 x i32> @mask_extracts_second_vector(ptr %di, <8 x i16> %other) {
; CHECK-LABEL: define <4 x i32> @mask_extracts_second_vector(
; CHECK-SAME: ptr [[DI:%.*]], <8 x i16> [[OTHER:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[DI]], align 4
; CHECK-NEXT:    [[VEC_INS:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[L]], i64 0
; CHECK-NEXT:    [[VEC_BC:%.*]] = bitcast <2 x i32> [[VEC_INS]] to <8 x i8>
; CHECK-NEXT:    [[EXT_1:%.*]] = sext <8 x i8> [[VEC_BC]] to <8 x i16>
; CHECK-NEXT:    [[VEC_SHUFFLE:%.*]] = shufflevector <8 x i16> [[EXT_1]], <8 x i16> [[OTHER]], <4 x i32> <i32 4, i32 5, i32 6, i32 7>
; CHECK-NEXT:    [[EXT_2:%.*]] = sext <4 x i16> [[VEC_SHUFFLE]] to <4 x i32>
; CHECK-NEXT:    ret <4 x i32> [[EXT_2]]
;
entry:
  %l = load i32, ptr %di
  %vec.ins = insertelement <2 x i32> <i32 poison, i32 0>, i32 %l, i64 0
  %vec.bc = bitcast <2 x i32> %vec.ins to <8 x i8>
  %ext.1 = sext <8 x i8> %vec.bc to <8 x i16>
  %vec.shuffle = shufflevector <8 x i16> %ext.1, <8 x i16> %other, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
  %ext.2 = sext <4 x i16> %vec.shuffle to <4 x i32>
  ret <4 x i32> %ext.2
}
