286 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4define i32 @extractelement_in_range(<vscale x 4 x i32> %a) {5; CHECK-LABEL: @extractelement_in_range(6; CHECK-NEXT: [[R:%.*]] = extractelement <vscale x 4 x i32> [[A:%.*]], i64 17; CHECK-NEXT: ret i32 [[R]]8;9 %r = extractelement <vscale x 4 x i32> %a, i64 110 ret i32 %r11}12 13define i32 @extractelement_maybe_out_of_range(<vscale x 4 x i32> %a) {14; CHECK-LABEL: @extractelement_maybe_out_of_range(15; CHECK-NEXT: [[R:%.*]] = extractelement <vscale x 4 x i32> [[A:%.*]], i64 416; CHECK-NEXT: ret i32 [[R]]17;18 %r = extractelement <vscale x 4 x i32> %a, i64 419 ret i32 %r20}21 22define i32 @extractelement_bitcast(float %f) {23; CHECK-LABEL: @extractelement_bitcast(24; CHECK-NEXT: [[R:%.*]] = bitcast float [[F:%.*]] to i3225; CHECK-NEXT: ret i32 [[R]]26;27 %vec_float = insertelement <vscale x 4 x float> undef, float %f, i32 028 %vec_int = bitcast <vscale x 4 x float> %vec_float to <vscale x 4 x i32>29 %r = extractelement <vscale x 4 x i32> %vec_int, i32 030 ret i32 %r31}32 33define i8 @extractelement_bitcast_to_trunc(<vscale x 2 x i32> %a, i32 %x) {34; CHECK-LABEL: @extractelement_bitcast_to_trunc(35; CHECK-NEXT: [[R:%.*]] = trunc i32 [[X:%.*]] to i836; CHECK-NEXT: ret i8 [[R]]37;38 %vec = insertelement <vscale x 2 x i32> %a, i32 %x, i32 139 %vec_cast = bitcast <vscale x 2 x i32> %vec to <vscale x 8 x i8>40 %r = extractelement <vscale x 8 x i8> %vec_cast, i32 441 ret i8 %r42}43 44define i8 @extractelement_bitcast_useless_insert(<vscale x 2 x i32> %a, i32 %x) {45; CHECK-LABEL: @extractelement_bitcast_useless_insert(46; CHECK-NEXT: [[TMP1:%.*]] = bitcast <vscale x 2 x i32> [[A:%.*]] to <vscale x 8 x i8>47; CHECK-NEXT: [[R:%.*]] = extractelement <vscale x 8 x i8> [[TMP1]], i64 248; CHECK-NEXT: ret i8 [[R]]49;50 %vec = insertelement <vscale x 2 x i32> %a, i32 %x, i32 1 ; <- This insert could be removed.51 %vec_cast = bitcast <vscale x 2 x i32> %vec to <vscale x 8 x i8>52 %r = extractelement <vscale x 8 x i8> %vec_cast, i32 253 ret i8 %r54}55 56; while in these tests it may be that the extract is out-of-bounds,57; any valid index is going to yield %v (because the mask is all-zeros).58 59define i32 @extractelement_shuffle_maybe_out_of_range(i32 %v) {60; CHECK-LABEL: @extractelement_shuffle_maybe_out_of_range(61; CHECK-NEXT: ret i32 [[V:%.*]]62;63 %in = insertelement <vscale x 4 x i32> undef, i32 %v, i32 064 %splat = shufflevector <vscale x 4 x i32> %in, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer65 %r = extractelement <vscale x 4 x i32> %splat, i32 466 ret i32 %r67}68 69define i32 @extractelement_shuffle_invalid_index(i32 %v) {70; CHECK-LABEL: @extractelement_shuffle_invalid_index(71; CHECK-NEXT: ret i32 [[V:%.*]]72;73 %in = insertelement <vscale x 4 x i32> undef, i32 %v, i32 074 %splat = shufflevector <vscale x 4 x i32> %in, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer75 %r = extractelement <vscale x 4 x i32> %splat, i32 -176 ret i32 %r77}78 79define <vscale x 4 x i32> @extractelement_insertelement_same_positions(<vscale x 4 x i32> %vec) {80; CHECK-LABEL: @extractelement_insertelement_same_positions(81; CHECK-NEXT: ret <vscale x 4 x i32> [[VEC:%.*]]82;83 %vec.e0 = extractelement <vscale x 4 x i32> %vec, i32 084 %vec.e1 = extractelement <vscale x 4 x i32> %vec, i32 185 %vec.e2 = extractelement <vscale x 4 x i32> %vec, i32 286 %vec.e3 = extractelement <vscale x 4 x i32> %vec, i32 387 %1 = insertelement <vscale x 4 x i32> %vec, i32 %vec.e0, i32 088 %2 = insertelement <vscale x 4 x i32> %1, i32 %vec.e1, i32 189 %3 = insertelement <vscale x 4 x i32> %2, i32 %vec.e2, i32 290 %4 = insertelement <vscale x 4 x i32> %3, i32 %vec.e3, i32 391 ret <vscale x 4 x i32> %492}93 94define <vscale x 4 x i32> @extractelement_insertelement_diff_positions(<vscale x 4 x i32> %vec) {95; CHECK-LABEL: @extractelement_insertelement_diff_positions(96; CHECK-NEXT: [[VEC_E0:%.*]] = extractelement <vscale x 4 x i32> [[VEC:%.*]], i64 497; CHECK-NEXT: [[VEC_E1:%.*]] = extractelement <vscale x 4 x i32> [[VEC]], i64 598; CHECK-NEXT: [[VEC_E2:%.*]] = extractelement <vscale x 4 x i32> [[VEC]], i64 699; CHECK-NEXT: [[VEC_E3:%.*]] = extractelement <vscale x 4 x i32> [[VEC]], i64 7100; CHECK-NEXT: [[TMP1:%.*]] = insertelement <vscale x 4 x i32> [[VEC]], i32 [[VEC_E0]], i64 0101; CHECK-NEXT: [[TMP2:%.*]] = insertelement <vscale x 4 x i32> [[TMP1]], i32 [[VEC_E1]], i64 1102; CHECK-NEXT: [[TMP3:%.*]] = insertelement <vscale x 4 x i32> [[TMP2]], i32 [[VEC_E2]], i64 2103; CHECK-NEXT: [[TMP4:%.*]] = insertelement <vscale x 4 x i32> [[TMP3]], i32 [[VEC_E3]], i64 3104; CHECK-NEXT: ret <vscale x 4 x i32> [[TMP4]]105;106 %vec.e0 = extractelement <vscale x 4 x i32> %vec, i32 4107 %vec.e1 = extractelement <vscale x 4 x i32> %vec, i32 5108 %vec.e2 = extractelement <vscale x 4 x i32> %vec, i32 6109 %vec.e3 = extractelement <vscale x 4 x i32> %vec, i32 7110 %1 = insertelement <vscale x 4 x i32> %vec, i32 %vec.e0, i32 0111 %2 = insertelement <vscale x 4 x i32> %1, i32 %vec.e1, i32 1112 %3 = insertelement <vscale x 4 x i32> %2, i32 %vec.e2, i32 2113 %4 = insertelement <vscale x 4 x i32> %3, i32 %vec.e3, i32 3114 ret <vscale x 4 x i32> %4115}116 117define i32 @bitcast_of_extractelement( <vscale x 2 x float> %d) {118; CHECK-LABEL: @bitcast_of_extractelement(119; CHECK-NEXT: [[BC:%.*]] = bitcast <vscale x 2 x float> [[D:%.*]] to <vscale x 2 x i32>120; CHECK-NEXT: [[CAST:%.*]] = extractelement <vscale x 2 x i32> [[BC]], i64 0121; CHECK-NEXT: ret i32 [[CAST]]122;123 %ext = extractelement <vscale x 2 x float> %d, i32 0124 %cast = bitcast float %ext to i32125 ret i32 %cast126}127 128define i1 @extractelement_is_zero(<vscale x 2 x i32> %d, i1 %b, i32 %z) {129; CHECK-LABEL: @extractelement_is_zero(130; CHECK-NEXT: [[EXT:%.*]] = extractelement <vscale x 2 x i32> [[D:%.*]], i64 0131; CHECK-NEXT: [[BB:%.*]] = icmp eq i32 [[EXT]], 0132; CHECK-NEXT: ret i1 [[BB]]133;134 %ext = extractelement <vscale x 2 x i32> %d, i32 0135 %bb = icmp eq i32 %ext, 0136 ret i1 %bb137}138 139; OSS-Fuzz #25272140; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25272141define i32 @ossfuzz_25272(float %f) {142; CHECK-LABEL: @ossfuzz_25272(143; CHECK-NEXT: [[VEC_FLOAT:%.*]] = insertelement <vscale x 4 x float> undef, float [[F:%.*]], i64 0144; CHECK-NEXT: [[VEC_INT:%.*]] = bitcast <vscale x 4 x float> [[VEC_FLOAT]] to <vscale x 4 x i32>145; CHECK-NEXT: [[E:%.*]] = extractelement <vscale x 4 x i32> [[VEC_INT]], i64 2147483647146; CHECK-NEXT: ret i32 [[E]]147;148 %vec_float = insertelement <vscale x 4 x float> undef, float %f, i32 0149 %vec_int = bitcast <vscale x 4 x float> %vec_float to <vscale x 4 x i32>150 %E = extractelement <vscale x 4 x i32> %vec_int, i32 2147483647151 ret i32 %E152}153 154; Step vector optimization155 156define i64 @ext_lane0_from_stepvec() {157; CHECK-LABEL: @ext_lane0_from_stepvec(158; CHECK-NEXT: entry:159; CHECK-NEXT: ret i64 0160;161entry:162 %0 = call <vscale x 4 x i64> @llvm.stepvector.nxv4i64()163 %1 = extractelement <vscale x 4 x i64> %0, i32 0164 ret i64 %1165}166 167define i32 @ext_lane3_from_stepvec() {168; CHECK-LABEL: @ext_lane3_from_stepvec(169; CHECK-NEXT: entry:170; CHECK-NEXT: ret i32 3171;172entry:173 %0 = call <vscale x 4 x i32> @llvm.stepvector.nxv4i32()174 %1 = extractelement <vscale x 4 x i32> %0, i64 3175 ret i32 %1176}177 178define i64 @ext_lane_out_of_range_from_stepvec() {179; CHECK-LABEL: @ext_lane_out_of_range_from_stepvec(180; CHECK-NEXT: entry:181; CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 4 x i64> @llvm.stepvector.nxv4i64()182; CHECK-NEXT: [[TMP1:%.*]] = extractelement <vscale x 4 x i64> [[TMP0]], i64 4183; CHECK-NEXT: ret i64 [[TMP1]]184;185entry:186 %0 = call <vscale x 4 x i64> @llvm.stepvector.nxv4i64()187 %1 = extractelement <vscale x 4 x i64> %0, i32 4188 ret i64 %1189}190 191define i64 @ext_lane_invalid_from_stepvec() {192; CHECK-LABEL: @ext_lane_invalid_from_stepvec(193; CHECK-NEXT: entry:194; CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 4 x i64> @llvm.stepvector.nxv4i64()195; CHECK-NEXT: [[TMP1:%.*]] = extractelement <vscale x 4 x i64> [[TMP0]], i64 4294967295196; CHECK-NEXT: ret i64 [[TMP1]]197;198entry:199 %0 = call <vscale x 4 x i64> @llvm.stepvector.nxv4i64()200 %1 = extractelement <vscale x 4 x i64> %0, i32 -1201 ret i64 %1202}203 204define i64 @ext_lane_unknown_from_stepvec(i32 %v) {205; CHECK-LABEL: @ext_lane_unknown_from_stepvec(206; CHECK-NEXT: entry:207; CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 4 x i64> @llvm.stepvector.nxv4i64()208; CHECK-NEXT: [[TMP1:%.*]] = extractelement <vscale x 4 x i64> [[TMP0]], i32 [[V:%.*]]209; CHECK-NEXT: ret i64 [[TMP1]]210;211entry:212 %0 = call <vscale x 4 x i64> @llvm.stepvector.nxv4i64()213 %1 = extractelement <vscale x 4 x i64> %0, i32 %v214 ret i64 %1215}216 217; Check that poison is returned when the extracted element has wrapped.218 219define i8 @ext_lane256_from_stepvec() {220; CHECK-LABEL: @ext_lane256_from_stepvec(221; CHECK-NEXT: entry:222; CHECK-NEXT: ret i8 poison223;224entry:225 %0 = call <vscale x 512 x i8> @llvm.stepvector.nxv512i8()226 %1 = extractelement <vscale x 512 x i8> %0, i64 256227 ret i8 %1228}229 230define i8 @ext_lane255_from_stepvec() {231; CHECK-LABEL: @ext_lane255_from_stepvec(232; CHECK-NEXT: entry:233; CHECK-NEXT: ret i8 -1234;235entry:236 %0 = call <vscale x 512 x i8> @llvm.stepvector.nxv512i8()237 %1 = extractelement <vscale x 512 x i8> %0, i64 255238 ret i8 %1239}240 241; Check that we can extract more complex cases where the stepvector is242; involved in a binary operation prior to the lane being extracted.243 244define i64 @ext_lane0_from_add_with_stepvec(i64 %i) {245; CHECK-LABEL: @ext_lane0_from_add_with_stepvec(246; CHECK-NEXT: ret i64 [[I:%.*]]247;248 %tmp = insertelement <vscale x 2 x i64> poison, i64 %i, i32 0249 %splatofi = shufflevector <vscale x 2 x i64> %tmp, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer250 %stepvec = call <vscale x 2 x i64> @llvm.stepvector.nxv2i64()251 %add = add <vscale x 2 x i64> %splatofi, %stepvec252 %res = extractelement <vscale x 2 x i64> %add, i32 0253 ret i64 %res254}255 256define i1 @ext_lane1_from_cmp_with_stepvec(i64 %i) {257; CHECK-LABEL: @ext_lane1_from_cmp_with_stepvec(258; CHECK-NEXT: [[RES:%.*]] = icmp eq i64 [[I:%.*]], 1259; CHECK-NEXT: ret i1 [[RES]]260;261 %tmp = insertelement <vscale x 2 x i64> poison, i64 %i, i32 0262 %splatofi = shufflevector <vscale x 2 x i64> %tmp, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer263 %stepvec = call <vscale x 2 x i64> @llvm.stepvector.nxv2i64()264 %cmp = icmp eq <vscale x 2 x i64> %splatofi, %stepvec265 %res = extractelement <vscale x 2 x i1> %cmp, i32 1266 ret i1 %res267}268 269define ptr @ext_lane_from_bitcast_of_splat(ptr %v) {270; CHECK-LABEL: @ext_lane_from_bitcast_of_splat(271; CHECK-NEXT: entry:272; CHECK-NEXT: ret ptr [[V:%.*]]273;274entry:275 %in = insertelement <vscale x 4 x ptr> poison, ptr %v, i32 0276 %splat = shufflevector <vscale x 4 x ptr> %in, <vscale x 4 x ptr> poison, <vscale x 4 x i32> zeroinitializer277 %bc = bitcast <vscale x 4 x ptr> %splat to <vscale x 4 x ptr>278 %r = extractelement <vscale x 4 x ptr> %bc, i32 3279 ret ptr %r280}281 282declare <vscale x 2 x i64> @llvm.stepvector.nxv2i64()283declare <vscale x 4 x i64> @llvm.stepvector.nxv4i64()284declare <vscale x 4 x i32> @llvm.stepvector.nxv4i32()285declare <vscale x 512 x i8> @llvm.stepvector.nxv512i8()286