diff --git a/llvm/test/Transforms/InstCombine/extractelement.ll b/llvm/test/Transforms/InstCombine/extractelement.ll --- a/llvm/test/Transforms/InstCombine/extractelement.ll +++ b/llvm/test/Transforms/InstCombine/extractelement.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -passes=instcombine -S -data-layout="e-n64" | FileCheck %s --check-prefixes=ANY,LE -; RUN: opt < %s -passes=instcombine -S -data-layout="E-n64" | FileCheck %s --check-prefixes=ANY,BE +; RUN: opt < %s -passes=instcombine -S -data-layout="e-n64" | FileCheck %s --check-prefixes=ANY,ANYLE,LE64 +; RUN: opt < %s -passes=instcombine -S -data-layout="e-n128" | FileCheck %s --check-prefixes=ANY,ANYLE,LE128 +; RUN: opt < %s -passes=instcombine -S -data-layout="E-n64" | FileCheck %s --check-prefixes=ANY,ANYBE,BE64 +; RUN: opt < %s -passes=instcombine -S -data-layout="E-n128" | FileCheck %s --check-prefixes=ANY,ANYBE,BE128 define i32 @extractelement_out_of_range(<2 x i32> %x) { ; ANY-LABEL: @extractelement_out_of_range( @@ -42,14 +44,14 @@ } define i32 @bitcasted_inselt_wide_source_zero_elt(i64 %x) { -; LE-LABEL: @bitcasted_inselt_wide_source_zero_elt( -; LE-NEXT: [[R:%.*]] = trunc i64 [[X:%.*]] to i32 -; LE-NEXT: ret i32 [[R]] +; ANYLE-LABEL: @bitcasted_inselt_wide_source_zero_elt( +; ANYLE-NEXT: [[R:%.*]] = trunc i64 [[X:%.*]] to i32 +; ANYLE-NEXT: ret i32 [[R]] ; -; BE-LABEL: @bitcasted_inselt_wide_source_zero_elt( -; BE-NEXT: [[TMP1:%.*]] = lshr i64 [[X:%.*]], 32 -; BE-NEXT: [[R:%.*]] = trunc i64 [[TMP1]] to i32 -; BE-NEXT: ret i32 [[R]] +; ANYBE-LABEL: @bitcasted_inselt_wide_source_zero_elt( +; ANYBE-NEXT: [[TMP1:%.*]] = lshr i64 [[X:%.*]], 32 +; ANYBE-NEXT: [[R:%.*]] = trunc i64 [[TMP1]] to i32 +; ANYBE-NEXT: ret i32 [[R]] ; %i = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0 %b = bitcast <2 x i64> %i to <4 x i32> @@ -58,14 +60,14 @@ } define i16 @bitcasted_inselt_wide_source_modulo_elt(i64 %x) { -; LE-LABEL: @bitcasted_inselt_wide_source_modulo_elt( -; LE-NEXT: [[R:%.*]] = trunc i64 [[X:%.*]] to i16 -; LE-NEXT: ret i16 [[R]] +; ANYLE-LABEL: @bitcasted_inselt_wide_source_modulo_elt( +; ANYLE-NEXT: [[R:%.*]] = trunc i64 [[X:%.*]] to i16 +; ANYLE-NEXT: ret i16 [[R]] ; -; BE-LABEL: @bitcasted_inselt_wide_source_modulo_elt( -; BE-NEXT: [[TMP1:%.*]] = lshr i64 [[X:%.*]], 48 -; BE-NEXT: [[R:%.*]] = trunc i64 [[TMP1]] to i16 -; BE-NEXT: ret i16 [[R]] +; ANYBE-LABEL: @bitcasted_inselt_wide_source_modulo_elt( +; ANYBE-NEXT: [[TMP1:%.*]] = lshr i64 [[X:%.*]], 48 +; ANYBE-NEXT: [[R:%.*]] = trunc i64 [[TMP1]] to i16 +; ANYBE-NEXT: ret i16 [[R]] ; %i = insertelement <2 x i64> undef, i64 %x, i32 1 %b = bitcast <2 x i64> %i to <8 x i16> @@ -74,14 +76,14 @@ } define i32 @bitcasted_inselt_wide_source_not_modulo_elt(i64 %x) { -; LE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt( -; LE-NEXT: [[TMP1:%.*]] = lshr i64 [[X:%.*]], 32 -; LE-NEXT: [[R:%.*]] = trunc i64 [[TMP1]] to i32 -; LE-NEXT: ret i32 [[R]] +; ANYLE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt( +; ANYLE-NEXT: [[TMP1:%.*]] = lshr i64 [[X:%.*]], 32 +; ANYLE-NEXT: [[R:%.*]] = trunc i64 [[TMP1]] to i32 +; ANYLE-NEXT: ret i32 [[R]] ; -; BE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt( -; BE-NEXT: [[R:%.*]] = trunc i64 [[X:%.*]] to i32 -; BE-NEXT: ret i32 [[R]] +; ANYBE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt( +; ANYBE-NEXT: [[R:%.*]] = trunc i64 [[X:%.*]] to i32 +; ANYBE-NEXT: ret i32 [[R]] ; %i = insertelement <2 x i64> undef, i64 %x, i32 0 %b = bitcast <2 x i64> %i to <4 x i32> @@ -90,15 +92,15 @@ } define i8 @bitcasted_inselt_wide_source_not_modulo_elt_not_half(i32 %x) { -; LE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half( -; LE-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 16 -; LE-NEXT: [[R:%.*]] = trunc i32 [[TMP1]] to i8 -; LE-NEXT: ret i8 [[R]] +; ANYLE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half( +; ANYLE-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 16 +; ANYLE-NEXT: [[R:%.*]] = trunc i32 [[TMP1]] to i8 +; ANYLE-NEXT: ret i8 [[R]] ; -; BE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half( -; BE-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8 -; BE-NEXT: [[R:%.*]] = trunc i32 [[TMP1]] to i8 -; BE-NEXT: ret i8 [[R]] +; ANYBE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half( +; ANYBE-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8 +; ANYBE-NEXT: [[R:%.*]] = trunc i32 [[TMP1]] to i8 +; ANYBE-NEXT: ret i8 [[R]] ; %i = insertelement <2 x i32> undef, i32 %x, i32 0 %b = bitcast <2 x i32> %i to <8 x i8> @@ -107,15 +109,15 @@ } define i3 @bitcasted_inselt_wide_source_not_modulo_elt_not_half_weird_types(i15 %x) { -; LE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half_weird_types( -; LE-NEXT: [[TMP1:%.*]] = lshr i15 [[X:%.*]], 3 -; LE-NEXT: [[R:%.*]] = trunc i15 [[TMP1]] to i3 -; LE-NEXT: ret i3 [[R]] +; ANYLE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half_weird_types( +; ANYLE-NEXT: [[TMP1:%.*]] = lshr i15 [[X:%.*]], 3 +; ANYLE-NEXT: [[R:%.*]] = trunc i15 [[TMP1]] to i3 +; ANYLE-NEXT: ret i3 [[R]] ; -; BE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half_weird_types( -; BE-NEXT: [[TMP1:%.*]] = lshr i15 [[X:%.*]], 9 -; BE-NEXT: [[R:%.*]] = trunc i15 [[TMP1]] to i3 -; BE-NEXT: ret i3 [[R]] +; ANYBE-LABEL: @bitcasted_inselt_wide_source_not_modulo_elt_not_half_weird_types( +; ANYBE-NEXT: [[TMP1:%.*]] = lshr i15 [[X:%.*]], 9 +; ANYBE-NEXT: [[R:%.*]] = trunc i15 [[TMP1]] to i3 +; ANYBE-NEXT: ret i3 [[R]] ; %i = insertelement <3 x i15> undef, i15 %x, i32 0 %b = bitcast <3 x i15> %i to <15 x i3> @@ -127,8 +129,8 @@ define i8 @bitcasted_inselt_wide_source_wrong_insert(<2 x i32> %v, i32 %x) { ; ANY-LABEL: @bitcasted_inselt_wide_source_wrong_insert( -; ANY-NEXT: [[B:%.*]] = bitcast <2 x i32> [[V:%.*]] to <8 x i8> -; ANY-NEXT: [[R:%.*]] = extractelement <8 x i8> [[B]], i64 2 +; ANY-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[V:%.*]] to <8 x i8> +; ANY-NEXT: [[R:%.*]] = extractelement <8 x i8> [[TMP1]], i64 2 ; ANY-NEXT: ret i8 [[R]] ; %i = insertelement <2 x i32> %v, i32 %x, i32 1 @@ -142,19 +144,19 @@ declare void @use(<8 x i8>) define i8 @bitcasted_inselt_wide_source_uses(i32 %x) { -; LE-LABEL: @bitcasted_inselt_wide_source_uses( -; LE-NEXT: [[I:%.*]] = insertelement <2 x i32> undef, i32 [[X:%.*]], i64 0 -; LE-NEXT: [[B:%.*]] = bitcast <2 x i32> [[I]] to <8 x i8> -; LE-NEXT: call void @use(<8 x i8> [[B]]) -; LE-NEXT: [[R:%.*]] = extractelement <8 x i8> [[B]], i64 3 -; LE-NEXT: ret i8 [[R]] -; -; BE-LABEL: @bitcasted_inselt_wide_source_uses( -; BE-NEXT: [[I:%.*]] = insertelement <2 x i32> undef, i32 [[X:%.*]], i64 0 -; BE-NEXT: [[B:%.*]] = bitcast <2 x i32> [[I]] to <8 x i8> -; BE-NEXT: call void @use(<8 x i8> [[B]]) -; BE-NEXT: [[R:%.*]] = trunc i32 [[X]] to i8 -; BE-NEXT: ret i8 [[R]] +; ANYLE-LABEL: @bitcasted_inselt_wide_source_uses( +; ANYLE-NEXT: [[I:%.*]] = insertelement <2 x i32> undef, i32 [[X:%.*]], i64 0 +; ANYLE-NEXT: [[B:%.*]] = bitcast <2 x i32> [[I]] to <8 x i8> +; ANYLE-NEXT: call void @use(<8 x i8> [[B]]) +; ANYLE-NEXT: [[R:%.*]] = extractelement <8 x i8> [[B]], i64 3 +; ANYLE-NEXT: ret i8 [[R]] +; +; ANYBE-LABEL: @bitcasted_inselt_wide_source_uses( +; ANYBE-NEXT: [[I:%.*]] = insertelement <2 x i32> undef, i32 [[X:%.*]], i64 0 +; ANYBE-NEXT: [[B:%.*]] = bitcast <2 x i32> [[I]] to <8 x i8> +; ANYBE-NEXT: call void @use(<8 x i8> [[B]]) +; ANYBE-NEXT: [[R:%.*]] = trunc i32 [[X]] to i8 +; ANYBE-NEXT: ret i8 [[R]] ; %i = insertelement <2 x i32> undef, i32 %x, i32 0 %b = bitcast <2 x i32> %i to <8 x i8> @@ -164,16 +166,16 @@ } define float @bitcasted_inselt_to_FP(i64 %x) { -; LE-LABEL: @bitcasted_inselt_to_FP( -; LE-NEXT: [[TMP1:%.*]] = lshr i64 [[X:%.*]], 32 -; LE-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 -; LE-NEXT: [[R:%.*]] = bitcast i32 [[TMP2]] to float -; LE-NEXT: ret float [[R]] +; ANYLE-LABEL: @bitcasted_inselt_to_FP( +; ANYLE-NEXT: [[TMP1:%.*]] = lshr i64 [[X:%.*]], 32 +; ANYLE-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 +; ANYLE-NEXT: [[R:%.*]] = bitcast i32 [[TMP2]] to float +; ANYLE-NEXT: ret float [[R]] ; -; BE-LABEL: @bitcasted_inselt_to_FP( -; BE-NEXT: [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32 -; BE-NEXT: [[R:%.*]] = bitcast i32 [[TMP1]] to float -; BE-NEXT: ret float [[R]] +; ANYBE-LABEL: @bitcasted_inselt_to_FP( +; ANYBE-NEXT: [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32 +; ANYBE-NEXT: [[R:%.*]] = bitcast i32 [[TMP1]] to float +; ANYBE-NEXT: ret float [[R]] ; %i = insertelement <2 x i64> undef, i64 %x, i32 0 %b = bitcast <2 x i64> %i to <4 x float> @@ -215,16 +217,16 @@ } define i32 @bitcasted_inselt_from_FP(double %x) { -; LE-LABEL: @bitcasted_inselt_from_FP( -; LE-NEXT: [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64 -; LE-NEXT: [[TMP2:%.*]] = lshr i64 [[TMP1]], 32 -; LE-NEXT: [[R:%.*]] = trunc i64 [[TMP2]] to i32 -; LE-NEXT: ret i32 [[R]] +; ANYLE-LABEL: @bitcasted_inselt_from_FP( +; ANYLE-NEXT: [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64 +; ANYLE-NEXT: [[TMP2:%.*]] = lshr i64 [[TMP1]], 32 +; ANYLE-NEXT: [[R:%.*]] = trunc i64 [[TMP2]] to i32 +; ANYLE-NEXT: ret i32 [[R]] ; -; BE-LABEL: @bitcasted_inselt_from_FP( -; BE-NEXT: [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64 -; BE-NEXT: [[R:%.*]] = trunc i64 [[TMP1]] to i32 -; BE-NEXT: ret i32 [[R]] +; ANYBE-LABEL: @bitcasted_inselt_from_FP( +; ANYBE-NEXT: [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64 +; ANYBE-NEXT: [[R:%.*]] = trunc i64 [[TMP1]] to i32 +; ANYBE-NEXT: ret i32 [[R]] ; %i = insertelement <2 x double> undef, double %x, i32 0 %b = bitcast <2 x double> %i to <4 x i32> @@ -333,14 +335,14 @@ ; i32 is a desirable/supported type independent of data layout. define i8 @bitcast_scalar_supported_type_index0(i32 %x) { -; LE-LABEL: @bitcast_scalar_supported_type_index0( -; LE-NEXT: [[R:%.*]] = trunc i32 [[X:%.*]] to i8 -; LE-NEXT: ret i8 [[R]] +; ANYLE-LABEL: @bitcast_scalar_supported_type_index0( +; ANYLE-NEXT: [[R:%.*]] = trunc i32 [[X:%.*]] to i8 +; ANYLE-NEXT: ret i8 [[R]] ; -; BE-LABEL: @bitcast_scalar_supported_type_index0( -; BE-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 24 -; BE-NEXT: [[R:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i8 -; BE-NEXT: ret i8 [[R]] +; ANYBE-LABEL: @bitcast_scalar_supported_type_index0( +; ANYBE-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 24 +; ANYBE-NEXT: [[R:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i8 +; ANYBE-NEXT: ret i8 [[R]] ; %v = bitcast i32 %x to <4 x i8> %r = extractelement <4 x i8> %v, i8 0 @@ -348,15 +350,15 @@ } define i8 @bitcast_scalar_supported_type_index2(i32 %x) { -; LE-LABEL: @bitcast_scalar_supported_type_index2( -; LE-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16 -; LE-NEXT: [[R:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i8 -; LE-NEXT: ret i8 [[R]] +; ANYLE-LABEL: @bitcast_scalar_supported_type_index2( +; ANYLE-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16 +; ANYLE-NEXT: [[R:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i8 +; ANYLE-NEXT: ret i8 [[R]] ; -; BE-LABEL: @bitcast_scalar_supported_type_index2( -; BE-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 8 -; BE-NEXT: [[R:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i8 -; BE-NEXT: ret i8 [[R]] +; ANYBE-LABEL: @bitcast_scalar_supported_type_index2( +; ANYBE-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 8 +; ANYBE-NEXT: [[R:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i8 +; ANYBE-NEXT: ret i8 [[R]] ; %v = bitcast i32 %x to <4 x i8> %r = extractelement <4 x i8> %v, i64 2 @@ -366,16 +368,27 @@ ; i64 is legal based on data layout. define i4 @bitcast_scalar_legal_type_index3(i64 %x) { -; LE-LABEL: @bitcast_scalar_legal_type_index3( -; LE-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i64 [[X:%.*]], 12 -; LE-NEXT: [[R:%.*]] = trunc i64 [[EXTELT_OFFSET]] to i4 -; LE-NEXT: ret i4 [[R]] +; LE64-LABEL: @bitcast_scalar_legal_type_index3( +; LE64-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i64 [[X:%.*]], 12 +; LE64-NEXT: [[R:%.*]] = trunc i64 [[EXTELT_OFFSET]] to i4 +; LE64-NEXT: ret i4 [[R]] ; -; BE-LABEL: @bitcast_scalar_legal_type_index3( -; BE-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i64 [[X:%.*]], 48 -; BE-NEXT: [[R:%.*]] = trunc i64 [[EXTELT_OFFSET]] to i4 -; BE-NEXT: ret i4 [[R]] +; LE128-LABEL: @bitcast_scalar_legal_type_index3( +; LE128-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <16 x i4> +; LE128-NEXT: [[R:%.*]] = extractelement <16 x i4> [[V]], i64 3 +; LE128-NEXT: ret i4 [[R]] ; +; BE64-LABEL: @bitcast_scalar_legal_type_index3( +; BE64-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i64 [[X:%.*]], 48 +; BE64-NEXT: [[R:%.*]] = trunc i64 [[EXTELT_OFFSET]] to i4 +; BE64-NEXT: ret i4 [[R]] +; +; BE128-LABEL: @bitcast_scalar_legal_type_index3( +; BE128-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <16 x i4> +; BE128-NEXT: [[R:%.*]] = extractelement <16 x i4> [[V]], i64 3 +; BE128-NEXT: ret i4 [[R]] +; + %v = bitcast i64 %x to <16 x i4> %r = extractelement <16 x i4> %v, i64 3 ret i4 %r @@ -384,10 +397,25 @@ ; negative test - don't create a shift for an illegal type. define i8 @bitcast_scalar_illegal_type_index1(i128 %x) { -; ANY-LABEL: @bitcast_scalar_illegal_type_index1( -; ANY-NEXT: [[V:%.*]] = bitcast i128 [[X:%.*]] to <16 x i8> -; ANY-NEXT: [[R:%.*]] = extractelement <16 x i8> [[V]], i64 1 -; ANY-NEXT: ret i8 [[R]] +; LE64-LABEL: @bitcast_scalar_illegal_type_index1( +; LE64-NEXT: [[V:%.*]] = bitcast i128 [[X:%.*]] to <16 x i8> +; LE64-NEXT: [[R:%.*]] = extractelement <16 x i8> [[V]], i64 1 +; LE64-NEXT: ret i8 [[R]] +; +; LE128-LABEL: @bitcast_scalar_illegal_type_index1( +; LE128-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i128 [[X:%.*]], 8 +; LE128-NEXT: [[R:%.*]] = trunc i128 [[EXTELT_OFFSET]] to i8 +; LE128-NEXT: ret i8 [[R]] +; +; BE64-LABEL: @bitcast_scalar_illegal_type_index1( +; BE64-NEXT: [[V:%.*]] = bitcast i128 [[X:%.*]] to <16 x i8> +; BE64-NEXT: [[R:%.*]] = extractelement <16 x i8> [[V]], i64 1 +; BE64-NEXT: ret i8 [[R]] +; +; BE128-LABEL: @bitcast_scalar_illegal_type_index1( +; BE128-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i128 [[X:%.*]], 112 +; BE128-NEXT: [[R:%.*]] = trunc i128 [[EXTELT_OFFSET]] to i8 +; BE128-NEXT: ret i8 [[R]] ; %v = bitcast i128 %x to <16 x i8> %r = extractelement <16 x i8> %v, i64 1 @@ -407,10 +435,8 @@ ret i8 %r } -; negative test - can't have FP dest type without a cast - -define half @bitcast_fpvec_index0(i32 %x) { -; ANY-LABEL: @bitcast_fpvec_index0( +define half @bitcast_fp16vec_index0(i32 %x) { +; ANY-LABEL: @bitcast_fp16vec_index0( ; ANY-NEXT: [[V:%.*]] = bitcast i32 [[X:%.*]] to <2 x half> ; ANY-NEXT: [[R:%.*]] = extractelement <2 x half> [[V]], i64 0 ; ANY-NEXT: ret half [[R]] @@ -420,7 +446,173 @@ ret half %r } -; negative test - need constant index +define half @bitcast_fp16vec_index1(i32 %x) { +; ANY-LABEL: @bitcast_fp16vec_index1( +; ANY-NEXT: [[V:%.*]] = bitcast i32 [[X:%.*]] to <2 x half> +; ANY-NEXT: [[R:%.*]] = extractelement <2 x half> [[V]], i64 1 +; ANY-NEXT: ret half [[R]] +; + %v = bitcast i32 %x to <2 x half> + %r = extractelement <2 x half> %v, i8 1 + ret half %r +} + +define bfloat @bitcast_bfp16vec_index0(i32 %x) { +; ANY-LABEL: @bitcast_bfp16vec_index0( +; ANY-NEXT: [[V:%.*]] = bitcast i32 [[X:%.*]] to <2 x bfloat> +; ANY-NEXT: [[R:%.*]] = extractelement <2 x bfloat> [[V]], i64 0 +; ANY-NEXT: ret bfloat [[R]] +; + %v = bitcast i32 %x to <2 x bfloat> + %r = extractelement <2 x bfloat> %v, i8 0 + ret bfloat %r +} + +define bfloat @bitcast_bfp16vec_index1(i32 %x) { +; ANY-LABEL: @bitcast_bfp16vec_index1( +; ANY-NEXT: [[V:%.*]] = bitcast i32 [[X:%.*]] to <2 x bfloat> +; ANY-NEXT: [[R:%.*]] = extractelement <2 x bfloat> [[V]], i64 1 +; ANY-NEXT: ret bfloat [[R]] +; + %v = bitcast i32 %x to <2 x bfloat> + %r = extractelement <2 x bfloat> %v, i8 1 + ret bfloat %r +} + +define float @bitcast_fp32vec_index0(i64 %x) { +; ANY-LABEL: @bitcast_fp32vec_index0( +; ANY-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float> +; ANY-NEXT: [[R:%.*]] = extractelement <2 x float> [[V]], i64 0 +; ANY-NEXT: ret float [[R]] +; + %v = bitcast i64 %x to <2 x float> + %r = extractelement <2 x float> %v, i8 0 + ret float %r +} + +define float @bitcast_fp32vec_index1(i64 %x) { +; ANY-LABEL: @bitcast_fp32vec_index1( +; ANY-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float> +; ANY-NEXT: [[R:%.*]] = extractelement <2 x float> [[V]], i64 1 +; ANY-NEXT: ret float [[R]] +; + %v = bitcast i64 %x to <2 x float> + %r = extractelement <2 x float> %v, i8 1 + ret float %r +} + +define double @bitcast_fp64vec64_index0(i64 %x) { +; ANY-LABEL: @bitcast_fp64vec64_index0( +; ANY-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <1 x double> +; ANY-NEXT: [[R:%.*]] = extractelement <1 x double> [[V]], i64 0 +; ANY-NEXT: ret double [[R]] +; + %v = bitcast i64 %x to <1 x double> + %r = extractelement <1 x double> %v, i8 0 + ret double %r +} + +define double @bitcast_fp64vec_index0(i128 %x) { +; ANY-LABEL: @bitcast_fp64vec_index0( +; ANY-NEXT: [[V:%.*]] = bitcast i128 [[X:%.*]] to <2 x double> +; ANY-NEXT: [[R:%.*]] = extractelement <2 x double> [[V]], i64 0 +; ANY-NEXT: ret double [[R]] +; + %v = bitcast i128 %x to <2 x double> + %r = extractelement <2 x double> %v, i8 0 + ret double %r +} + +define double @bitcast_fp64vec_index1(i128 %x) { +; ANY-LABEL: @bitcast_fp64vec_index1( +; ANY-NEXT: [[V:%.*]] = bitcast i128 [[X:%.*]] to <2 x double> +; ANY-NEXT: [[R:%.*]] = extractelement <2 x double> [[V]], i64 1 +; ANY-NEXT: ret double [[R]] +; + %v = bitcast i128 %x to <2 x double> + %r = extractelement <2 x double> %v, i8 1 + ret double %r +} + +; negative test - input integer should be legal + +define x86_fp80 @bitcast_x86fp80vec_index0(i160 %x) { +; ANY-LABEL: @bitcast_x86fp80vec_index0( +; ANY-NEXT: [[V:%.*]] = bitcast i160 [[X:%.*]] to <2 x x86_fp80> +; ANY-NEXT: [[R:%.*]] = extractelement <2 x x86_fp80> [[V]], i64 0 +; ANY-NEXT: ret x86_fp80 [[R]] +; + %v = bitcast i160 %x to <2 x x86_fp80> + %r = extractelement <2 x x86_fp80> %v, i8 0 + ret x86_fp80 %r +} + +; negative test - input integer should be legal + +define x86_fp80 @bitcast_x86fp80vec_index1(i160 %x) { +; ANY-LABEL: @bitcast_x86fp80vec_index1( +; ANY-NEXT: [[V:%.*]] = bitcast i160 [[X:%.*]] to <2 x x86_fp80> +; ANY-NEXT: [[R:%.*]] = extractelement <2 x x86_fp80> [[V]], i64 1 +; ANY-NEXT: ret x86_fp80 [[R]] +; + %v = bitcast i160 %x to <2 x x86_fp80> + %r = extractelement <2 x x86_fp80> %v, i8 1 + ret x86_fp80 %r +} + +; negative test - input integer should be legal + +define fp128 @bitcast_fp128vec_index0(i256 %x) { +; ANY-LABEL: @bitcast_fp128vec_index0( +; ANY-NEXT: [[V:%.*]] = bitcast i256 [[X:%.*]] to <2 x fp128> +; ANY-NEXT: [[R:%.*]] = extractelement <2 x fp128> [[V]], i64 0 +; ANY-NEXT: ret fp128 [[R]] +; + %v = bitcast i256 %x to <2 x fp128> + %r = extractelement <2 x fp128> %v, i8 0 + ret fp128 %r +} + +; negative test - input integer should be legal + +define fp128 @bitcast_fp128vec_index1(i256 %x) { +; ANY-LABEL: @bitcast_fp128vec_index1( +; ANY-NEXT: [[V:%.*]] = bitcast i256 [[X:%.*]] to <2 x fp128> +; ANY-NEXT: [[R:%.*]] = extractelement <2 x fp128> [[V]], i64 1 +; ANY-NEXT: ret fp128 [[R]] +; + %v = bitcast i256 %x to <2 x fp128> + %r = extractelement <2 x fp128> %v, i8 1 + ret fp128 %r +} + +; negative test - input integer should be legal + +define ppc_fp128 @bitcast_ppcfp128vec_index0(i256 %x) { +; ANY-LABEL: @bitcast_ppcfp128vec_index0( +; ANY-NEXT: [[V:%.*]] = bitcast i256 [[X:%.*]] to <2 x ppc_fp128> +; ANY-NEXT: [[R:%.*]] = extractelement <2 x ppc_fp128> [[V]], i64 0 +; ANY-NEXT: ret ppc_fp128 [[R]] +; + %v = bitcast i256 %x to <2 x ppc_fp128> + %r = extractelement <2 x ppc_fp128> %v, i8 0 + ret ppc_fp128 %r +} + +; negative test -input integer should be legal + +define ppc_fp128 @bitcast_ppcfp128vec_index1(i256 %x) { +; ANY-LABEL: @bitcast_ppcfp128vec_index1( +; ANY-NEXT: [[V:%.*]] = bitcast i256 [[X:%.*]] to <2 x ppc_fp128> +; ANY-NEXT: [[R:%.*]] = extractelement <2 x ppc_fp128> [[V]], i64 1 +; ANY-NEXT: ret ppc_fp128 [[R]] +; + %v = bitcast i256 %x to <2 x ppc_fp128> + %r = extractelement <2 x ppc_fp128> %v, i8 1 + ret ppc_fp128 %r +} + +; negative test - input integer should be legal define i8 @bitcast_scalar_index_variable(i32 %x, i64 %y) { ; ANY-LABEL: @bitcast_scalar_index_variable( @@ -436,20 +628,40 @@ ; extra use is ok if we don't need a shift define i8 @bitcast_scalar_index0_use(i64 %x) { -; LE-LABEL: @bitcast_scalar_index0_use( -; LE-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <8 x i8> -; LE-NEXT: call void @use(<8 x i8> [[V]]) -; LE-NEXT: [[R:%.*]] = trunc i64 [[X]] to i8 -; LE-NEXT: ret i8 [[R]] -; -; BE-LABEL: @bitcast_scalar_index0_use( -; BE-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <8 x i8> -; BE-NEXT: call void @use(<8 x i8> [[V]]) -; BE-NEXT: [[R:%.*]] = extractelement <8 x i8> [[V]], i64 0 -; BE-NEXT: ret i8 [[R]] +; LE64-LABEL: @bitcast_scalar_index0_use( +; LE64-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <8 x i8> +; LE64-NEXT: call void @use(<8 x i8> [[V]]) +; LE64-NEXT: [[R:%.*]] = trunc i64 [[X]] to i8 +; LE64-NEXT: ret i8 [[R]] +; +; LE128-LABEL: @bitcast_scalar_index0_use( +; LE128-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <8 x i8> +; LE128-NEXT: call void @use(<8 x i8> [[V]]) +; LE128-NEXT: [[R:%.*]] = extractelement <8 x i8> [[V]], i64 0 +; LE128-NEXT: ret i8 [[R]] ; +; ANYBE-LABEL: @bitcast_scalar_index0_use( +; ANYBE-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <8 x i8> +; ANYBE-NEXT: call void @use(<8 x i8> [[V]]) +; ANYBE-NEXT: [[R:%.*]] = extractelement <8 x i8> [[V]], i64 0 +; ANYBE-NEXT: ret i8 [[R]] +; + %v = bitcast i64 %x to <8 x i8> call void @use(<8 x i8> %v) %r = extractelement <8 x i8> %v, i64 0 ret i8 %r } + +define i1 @bit_extract_cmp(i64 %x) { +; ANY-LABEL: @bit_extract_cmp( +; ANY-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float> +; ANY-NEXT: [[E:%.*]] = extractelement <2 x float> [[V]], i64 1 +; ANY-NEXT: [[R:%.*]] = fcmp oeq float [[E]], 0.000000e+00 +; ANY-NEXT: ret i1 [[R]] +; + %v = bitcast i64 %x to <2 x float> + %e = extractelement <2 x float> %v, i8 1 + %r = fcmp oeq float %e, 0.0 + ret i1 %r +}