482 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare float @llvm.vector.reduce.fadd.f32.v4f32(float, <4 x float>)5declare float @llvm.vector.reduce.fadd.f32.v8f32(float, <8 x float>)6declare float @llvm.vector.reduce.fmul.f32.nxv4f32(float, <vscale x 4 x float>)7declare float @llvm.vector.reduce.fmin.f32.v4f32(float, <4 x float>)8declare float @llvm.vector.reduce.fmax.f32.nxv4f32(float, <vscale x 4 x float>)9declare void @use_f32(float)10 11declare i32 @llvm.vector.reduce.add.v4i32(<4 x i32>)12declare i32 @llvm.vector.reduce.add.nxv4i32(<vscale x 4 x i32>)13declare i32 @llvm.vector.reduce.add.v8i32(<8 x i32>)14declare void @use_i32(i32)15 16declare i32 @llvm.vector.reduce.mul.v4i32(<4 x i32>)17declare i32 @llvm.vector.reduce.mul.nxv4i32(<vscale x 4 x i32>)18 19declare i32 @llvm.vector.reduce.smin.v4i32(<4 x i32>)20declare i32 @llvm.vector.reduce.smax.nxv4i32(<vscale x 4 x i32>)21declare i32 @llvm.vector.reduce.umin.v4i32(<4 x i32>)22declare i32 @llvm.vector.reduce.umax.nxv4i32(<vscale x 4 x i32>)23 24declare <vscale x 4 x i32> @llvm.vector.reverse.nxv4i32(<vscale x 4 x i32>)25declare <vscale x 4 x float> @llvm.vector.reverse.nxv4f32(<vscale x 4 x float>)26declare <4 x i32> @llvm.vector.reverse.v4i32(<4 x i32>)27declare <4 x float> @llvm.vector.reverse.v4f32(<4 x float>)28 29define float @diff_of_sums_v4f32(float %a0, <4 x float> %v0, float %a1, <4 x float> %v1) {30; CHECK-LABEL: @diff_of_sums_v4f32(31; CHECK-NEXT: [[TMP1:%.*]] = fsub reassoc nsz <4 x float> [[V0:%.*]], [[V1:%.*]]32; CHECK-NEXT: [[TMP2:%.*]] = call reassoc nsz float @llvm.vector.reduce.fadd.v4f32(float [[A0:%.*]], <4 x float> [[TMP1]])33; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[TMP2]], [[A1:%.*]]34; CHECK-NEXT: ret float [[R]]35;36 %r0 = call float @llvm.vector.reduce.fadd.f32.v4f32(float %a0, <4 x float> %v0)37 %r1 = call float @llvm.vector.reduce.fadd.f32.v4f32(float %a1, <4 x float> %v1)38 %r = fsub reassoc nsz float %r0, %r139 ret float %r40}41 42define float @reassoc_sum_of_reverse_v4f32(<4 x float> %v0) {43; CHECK-LABEL: @reassoc_sum_of_reverse_v4f32(44; CHECK-NEXT: [[RED:%.*]] = call reassoc float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[V0:%.*]])45; CHECK-NEXT: ret float [[RED]]46;47 %rev = call <4 x float> @llvm.vector.reverse.v4f32(<4 x float> %v0)48 %red = call reassoc float @llvm.vector.reduce.fadd.v4f32(float zeroinitializer, <4 x float> %rev)49 ret float %red50}51 52define float @reassoc_mul_reduction_of_reverse_nxv4f32(<vscale x 4 x float> %v0) {53; CHECK-LABEL: @reassoc_mul_reduction_of_reverse_nxv4f32(54; CHECK-NEXT: [[RED:%.*]] = call reassoc float @llvm.vector.reduce.fmul.nxv4f32(float 1.000000e+00, <vscale x 4 x float> [[V0:%.*]])55; CHECK-NEXT: ret float [[RED]]56;57 %rev = call <vscale x 4 x float> @llvm.vector.reverse.nxv4f32(<vscale x 4 x float> %v0)58 %red = call reassoc float @llvm.vector.reduce.fmul.nxv4f32(float 1.0, <vscale x 4 x float> %rev)59 ret float %red60}61 62define float @fmax_of_reverse_v4f32(<4 x float> %v0) {63; CHECK-LABEL: @fmax_of_reverse_v4f32(64; CHECK-NEXT: [[RED:%.*]] = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> [[V0:%.*]])65; CHECK-NEXT: ret float [[RED]]66;67 %rev = call <4 x float> @llvm.vector.reverse.v4f32(<4 x float> %v0)68 %red = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> %rev)69 ret float %red70}71 72define float @fmin_of_reverse_nxv4f32(<vscale x 4 x float> %v0) {73; CHECK-LABEL: @fmin_of_reverse_nxv4f32(74; CHECK-NEXT: [[RED:%.*]] = call float @llvm.vector.reduce.fmin.nxv4f32(<vscale x 4 x float> [[V0:%.*]])75; CHECK-NEXT: ret float [[RED]]76;77 %rev = call <vscale x 4 x float> @llvm.vector.reverse.nxv4f32(<vscale x 4 x float> %v0)78 %red = call float @llvm.vector.reduce.fmin.nxv4f32(<vscale x 4 x float> %rev)79 ret float %red80}81 82; negative test - fadd cannot be folded with reverse due to lack of reassoc83define float @sum_of_reverse_v4f32(<4 x float> %v0) {84; CHECK-LABEL: @sum_of_reverse_v4f32(85; CHECK-NEXT: [[REV:%.*]] = call <4 x float> @llvm.vector.reverse.v4f32(<4 x float> [[V0:%.*]])86; CHECK-NEXT: [[RED:%.*]] = call float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[REV]])87; CHECK-NEXT: ret float [[RED]]88;89 %rev = call <4 x float> @llvm.vector.reverse.v4f32(<4 x float> %v0)90 %red = call float @llvm.vector.reduce.fadd.v4f32(float zeroinitializer, <4 x float> %rev)91 ret float %red92}93 94; negative test - fmul cannot be folded with reverse due to lack of reassoc95define float @mul_reduction_of_reverse_nxv4f32(<vscale x 4 x float> %v0) {96; CHECK-LABEL: @mul_reduction_of_reverse_nxv4f32(97; CHECK-NEXT: [[REV:%.*]] = call <vscale x 4 x float> @llvm.vector.reverse.nxv4f32(<vscale x 4 x float> [[V0:%.*]])98; CHECK-NEXT: [[RED:%.*]] = call float @llvm.vector.reduce.fmul.nxv4f32(float 0.000000e+00, <vscale x 4 x float> [[REV]])99; CHECK-NEXT: ret float [[RED]]100;101 %rev = call <vscale x 4 x float> @llvm.vector.reverse.nxv4f32(<vscale x 4 x float> %v0)102 %red = call float @llvm.vector.reduce.fmul.nxv4f32(float zeroinitializer, <vscale x 4 x float> %rev)103 ret float %red104}105 106 107; negative test - fsub must allow reassociation108 109define float @diff_of_sums_v4f32_fmf(float %a0, <4 x float> %v0, float %a1, <4 x float> %v1) {110; CHECK-LABEL: @diff_of_sums_v4f32_fmf(111; CHECK-NEXT: [[R0:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float [[A0:%.*]], <4 x float> [[V0:%.*]])112; CHECK-NEXT: [[R1:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float [[A1:%.*]], <4 x float> [[V1:%.*]])113; CHECK-NEXT: [[R:%.*]] = fsub nnan ninf nsz float [[R0]], [[R1]]114; CHECK-NEXT: ret float [[R]]115;116 %r0 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float %a0, <4 x float> %v0)117 %r1 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float %a1, <4 x float> %v1)118 %r = fsub ninf nnan nsz float %r0, %r1119 ret float %r120}121 122; negative test - extra uses could create extra instructions123 124define float @diff_of_sums_extra_use1(float %a0, <4 x float> %v0, float %a1, <4 x float> %v1) {125; CHECK-LABEL: @diff_of_sums_extra_use1(126; CHECK-NEXT: [[R0:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float [[A0:%.*]], <4 x float> [[V0:%.*]])127; CHECK-NEXT: call void @use_f32(float [[R0]])128; CHECK-NEXT: [[R1:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float [[A1:%.*]], <4 x float> [[V1:%.*]])129; CHECK-NEXT: [[R:%.*]] = fsub fast float [[R0]], [[R1]]130; CHECK-NEXT: ret float [[R]]131;132 %r0 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float %a0, <4 x float> %v0)133 call void @use_f32(float %r0)134 %r1 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float %a1, <4 x float> %v1)135 %r = fsub fast float %r0, %r1136 ret float %r137}138 139; negative test - extra uses could create extra instructions140 141define float @diff_of_sums_extra_use2(float %a0, <4 x float> %v0, float %a1, <4 x float> %v1) {142; CHECK-LABEL: @diff_of_sums_extra_use2(143; CHECK-NEXT: [[R0:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float [[A0:%.*]], <4 x float> [[V0:%.*]])144; CHECK-NEXT: [[R1:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float [[A1:%.*]], <4 x float> [[V1:%.*]])145; CHECK-NEXT: call void @use_f32(float [[R1]])146; CHECK-NEXT: [[R:%.*]] = fsub fast float [[R0]], [[R1]]147; CHECK-NEXT: ret float [[R]]148;149 %r0 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float %a0, <4 x float> %v0)150 %r1 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float %a1, <4 x float> %v1)151 call void @use_f32(float %r1)152 %r = fsub fast float %r0, %r1153 ret float %r154}155 156; negative test - can't reassociate different vector types157 158define float @diff_of_sums_type_mismatch(float %a0, <4 x float> %v0, float %a1, <8 x float> %v1) {159; CHECK-LABEL: @diff_of_sums_type_mismatch(160; CHECK-NEXT: [[R0:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float [[A0:%.*]], <4 x float> [[V0:%.*]])161; CHECK-NEXT: [[R1:%.*]] = call fast float @llvm.vector.reduce.fadd.v8f32(float [[A1:%.*]], <8 x float> [[V1:%.*]])162; CHECK-NEXT: [[R:%.*]] = fsub fast float [[R0]], [[R1]]163; CHECK-NEXT: ret float [[R]]164;165 %r0 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float %a0, <4 x float> %v0)166 %r1 = call fast float @llvm.vector.reduce.fadd.f32.v8f32(float %a1, <8 x float> %v1)167 %r = fsub fast float %r0, %r1168 ret float %r169}170 171define i32 @diff_of_sums_v4i32(<4 x i32> %v0, <4 x i32> %v1) {172; CHECK-LABEL: @diff_of_sums_v4i32(173; CHECK-NEXT: [[TMP1:%.*]] = sub <4 x i32> [[V0:%.*]], [[V1:%.*]]174; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP1]])175; CHECK-NEXT: ret i32 [[R]]176;177 %r0 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %v0)178 %r1 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %v1)179 %r = sub i32 %r0, %r1180 ret i32 %r181}182 183define i32 @sum_of_reverse_v4i32(<4 x i32> %v0) {184; CHECK-LABEL: @sum_of_reverse_v4i32(185; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[V0:%.*]])186; CHECK-NEXT: ret i32 [[RED]]187;188 %rev = call <4 x i32> @llvm.vector.reverse.v4i32(<4 x i32> %v0)189 %red = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %rev)190 ret i32 %red191}192 193define i32 @sum_of_reverse_nxv4i32(<vscale x 4 x i32> %v0) {194; CHECK-LABEL: @sum_of_reverse_nxv4i32(195; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32(<vscale x 4 x i32> [[V0:%.*]])196; CHECK-NEXT: ret i32 [[RED]]197;198 %rev = call <vscale x 4 x i32> @llvm.vector.reverse.nxv4i32(<vscale x 4 x i32> %v0)199 %red = call i32 @llvm.vector.reduce.add.nxv4i32(<vscale x 4 x i32> %rev)200 ret i32 %red201}202 203define i32 @mul_reduce_of_reverse_v4i32(<4 x i32> %v0) {204; CHECK-LABEL: @mul_reduce_of_reverse_v4i32(205; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> [[V0:%.*]])206; CHECK-NEXT: ret i32 [[RED]]207;208 %rev = call <4 x i32> @llvm.vector.reverse.v4i32(<4 x i32> %v0)209 %red = call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> %rev)210 ret i32 %red211}212 213define i32 @mul_reduce_of_reverse_nxv4i32(<vscale x 4 x i32> %v0) {214; CHECK-LABEL: @mul_reduce_of_reverse_nxv4i32(215; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.mul.nxv4i32(<vscale x 4 x i32> [[V0:%.*]])216; CHECK-NEXT: ret i32 [[RED]]217;218 %rev = call <vscale x 4 x i32> @llvm.vector.reverse.nxv4i32(<vscale x 4 x i32> %v0)219 %red = call i32 @llvm.vector.reduce.mul.nxv4i32(<vscale x 4 x i32> %rev)220 ret i32 %red221}222 223define i32 @smin_reduce_of_reverse_v4i32(<4 x i32> %v0) {224; CHECK-LABEL: @smin_reduce_of_reverse_v4i32(225; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.smin.v4i32(<4 x i32> [[V0:%.*]])226; CHECK-NEXT: ret i32 [[RED]]227;228 %rev = call <4 x i32> @llvm.vector.reverse.v4i32(<4 x i32> %v0)229 %red = call i32 @llvm.vector.reduce.smin.v4i32(<4 x i32> %rev)230 ret i32 %red231}232 233define i32 @smax_reduce_of_reverse_nxv4i32(<vscale x 4 x i32> %v0) {234; CHECK-LABEL: @smax_reduce_of_reverse_nxv4i32(235; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.smax.nxv4i32(<vscale x 4 x i32> [[V0:%.*]])236; CHECK-NEXT: ret i32 [[RED]]237;238 %rev = call <vscale x 4 x i32> @llvm.vector.reverse.nxv4i32(<vscale x 4 x i32> %v0)239 %red = call i32 @llvm.vector.reduce.smax.nxv4i32(<vscale x 4 x i32> %rev)240 ret i32 %red241}242 243define i32 @umin_reduce_of_reverse_v4i32(<4 x i32> %v0) {244; CHECK-LABEL: @umin_reduce_of_reverse_v4i32(245; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> [[V0:%.*]])246; CHECK-NEXT: ret i32 [[RED]]247;248 %rev = call <4 x i32> @llvm.vector.reverse.v4i32(<4 x i32> %v0)249 %red = call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> %rev)250 ret i32 %red251}252 253define i32 @umax_reduce_of_reverse_nxv4i32(<vscale x 4 x i32> %v0) {254; CHECK-LABEL: @umax_reduce_of_reverse_nxv4i32(255; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.nxv4i32(<vscale x 4 x i32> [[V0:%.*]])256; CHECK-NEXT: ret i32 [[RED]]257;258 %rev = call <vscale x 4 x i32> @llvm.vector.reverse.nxv4i32(<vscale x 4 x i32> %v0)259 %red = call i32 @llvm.vector.reduce.umax.nxv4i32(<vscale x 4 x i32> %rev)260 ret i32 %red261}262 263; negative test - extra uses could create extra instructions264 265define i32 @diff_of_sums_v4i32_extra_use1(<4 x i32> %v0, <4 x i32> %v1) {266; CHECK-LABEL: @diff_of_sums_v4i32_extra_use1(267; CHECK-NEXT: [[R0:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[V0:%.*]])268; CHECK-NEXT: call void @use_i32(i32 [[R0]])269; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[V1:%.*]])270; CHECK-NEXT: [[R:%.*]] = sub i32 [[R0]], [[R1]]271; CHECK-NEXT: ret i32 [[R]]272;273 %r0 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %v0)274 call void @use_i32(i32 %r0)275 %r1 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %v1)276 %r = sub i32 %r0, %r1277 ret i32 %r278}279 280; negative test - extra uses could create extra instructions281 282define i32 @diff_of_sums_v4i32_extra_use2(<4 x i32> %v0, <4 x i32> %v1) {283; CHECK-LABEL: @diff_of_sums_v4i32_extra_use2(284; CHECK-NEXT: [[R0:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[V0:%.*]])285; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[V1:%.*]])286; CHECK-NEXT: call void @use_i32(i32 [[R1]])287; CHECK-NEXT: [[R:%.*]] = sub i32 [[R0]], [[R1]]288; CHECK-NEXT: ret i32 [[R]]289;290 %r0 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %v0)291 %r1 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %v1)292 call void @use_i32(i32 %r1)293 %r = sub i32 %r0, %r1294 ret i32 %r295}296 297; negative test - can't reassociate different vector types298 299define i32 @diff_of_sums_type_mismatch2(<8 x i32> %v0, <4 x i32> %v1) {300; CHECK-LABEL: @diff_of_sums_type_mismatch2(301; CHECK-NEXT: [[R0:%.*]] = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> [[V0:%.*]])302; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[V1:%.*]])303; CHECK-NEXT: [[R:%.*]] = sub i32 [[R0]], [[R1]]304; CHECK-NEXT: ret i32 [[R]]305;306 %r0 = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %v0)307 %r1 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %v1)308 %r = sub i32 %r0, %r1309 ret i32 %r310}311 312define i32 @constant_multiplied_4xi32(i32 %0) {313; CHECK-LABEL: @constant_multiplied_4xi32(314; CHECK-NEXT: [[TMP2:%.*]] = shl i32 [[TMP0:%.*]], 2315; CHECK-NEXT: ret i32 [[TMP2]]316;317 %2 = insertelement <4 x i32> poison, i32 %0, i64 0318 %3 = shufflevector <4 x i32> %2, <4 x i32> poison, <4 x i32> zeroinitializer319 %4 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %3)320 ret i32 %4321}322 323define i32 @constant_multiplied_3xi32(i32 %0) {324; CHECK-LABEL: @constant_multiplied_3xi32(325; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[TMP0:%.*]], 3326; CHECK-NEXT: ret i32 [[TMP2]]327;328 %2 = insertelement <3 x i32> poison, i32 %0, i64 0329 %3 = shufflevector <3 x i32> %2, <3 x i32> poison, <3 x i32> zeroinitializer330 %4 = tail call i32 @llvm.vector.reduce.add.v3i32(<3 x i32> %3)331 ret i32 %4332}333 334define i64 @constant_multiplied_4xi64(i64 %0) {335; CHECK-LABEL: @constant_multiplied_4xi64(336; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[TMP0:%.*]], 2337; CHECK-NEXT: ret i64 [[TMP2]]338;339 %2 = insertelement <4 x i64> poison, i64 %0, i64 0340 %3 = shufflevector <4 x i64> %2, <4 x i64> poison, <4 x i32> zeroinitializer341 %4 = tail call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %3)342 ret i64 %4343}344 345define i32 @constant_multiplied_8xi32(i32 %0) {346; CHECK-LABEL: @constant_multiplied_8xi32(347; CHECK-NEXT: [[TMP2:%.*]] = shl i32 [[TMP0:%.*]], 3348; CHECK-NEXT: ret i32 [[TMP2]]349;350 %2 = insertelement <4 x i32> poison, i32 %0, i64 0351 %3 = shufflevector <4 x i32> %2, <4 x i32> poison, <8 x i32> zeroinitializer352 %4 = tail call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %3)353 ret i32 %4354}355 356 357define i32 @constant_multiplied_16xi32(i32 %0) {358; CHECK-LABEL: @constant_multiplied_16xi32(359; CHECK-NEXT: [[TMP2:%.*]] = shl i32 [[TMP0:%.*]], 4360; CHECK-NEXT: ret i32 [[TMP2]]361;362 %2 = insertelement <4 x i32> poison, i32 %0, i64 0363 %3 = shufflevector <4 x i32> %2, <4 x i32> poison, <16 x i32> zeroinitializer364 %4 = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %3)365 ret i32 %4366}367 368 369define i32 @constant_multiplied_4xi32_at_idx1(i32 %0) {370; CHECK-LABEL: @constant_multiplied_4xi32_at_idx1(371; CHECK-NEXT: [[TMP2:%.*]] = shl i32 [[TMP0:%.*]], 2372; CHECK-NEXT: ret i32 [[TMP2]]373;374 %2 = insertelement <4 x i32> poison, i32 %0, i64 1375 %3 = shufflevector <4 x i32> %2, <4 x i32> poison,376 <4 x i32> <i32 1, i32 1, i32 1, i32 1>377 %4 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %3)378 ret i32 %4379}380 381define i32 @negative_constant_multiplied_4xi32(i32 %0) {382; CHECK-LABEL: @negative_constant_multiplied_4xi32(383; CHECK-NEXT: ret i32 poison384;385 %2 = insertelement <4 x i32> poison, i32 %0, i64 1386 %3 = shufflevector <4 x i32> %2, <4 x i32> poison, <4 x i32> zeroinitializer387 %4 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %3)388 ret i32 %4389}390 391define i32 @constant_multiplied_6xi32(i32 %0) {392; CHECK-LABEL: @constant_multiplied_6xi32(393; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[TMP0:%.*]], 6394; CHECK-NEXT: ret i32 [[TMP2]]395;396 %2 = insertelement <4 x i32> poison, i32 %0, i64 0397 %3 = shufflevector <4 x i32> %2, <4 x i32> poison, <6 x i32> zeroinitializer398 %4 = tail call i32 @llvm.vector.reduce.add.v6i32(<6 x i32> %3)399 ret i32 %4400}401 402define i64 @constant_multiplied_6xi64(i64 %0) {403; CHECK-LABEL: @constant_multiplied_6xi64(404; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[TMP0:%.*]], 6405; CHECK-NEXT: ret i64 [[TMP2]]406;407 %2 = insertelement <4 x i64> poison, i64 %0, i64 0408 %3 = shufflevector <4 x i64> %2, <4 x i64> poison, <6 x i32> zeroinitializer409 %4 = tail call i64 @llvm.vector.reduce.add.v6i64(<6 x i64> %3)410 ret i64 %4411}412 413define i1 @constant_multiplied_8xi1(i1 %0) {414; CHECK-LABEL: @constant_multiplied_8xi1(415; CHECK-NEXT: [[TMP2:%.*]] = insertelement <8 x i1> poison, i1 [[TMP0:%.*]], i64 0416; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <8 x i1> [[TMP2]], <8 x i1> poison, <8 x i32> zeroinitializer417; CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i1> [[TMP3]] to i8418; CHECK-NEXT: [[TMP5:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[TMP4]])419; CHECK-NEXT: [[TMP6:%.*]] = trunc i8 [[TMP5]] to i1420; CHECK-NEXT: ret i1 [[TMP6]]421;422 %2 = insertelement <8 x i1> poison, i1 %0, i32 0423 %3 = shufflevector <8 x i1> %2, <8 x i1> poison, <8 x i32> zeroinitializer424 %4 = tail call i1 @llvm.vector.reduce.add.v8i1(<8 x i1> %3)425 ret i1 %4426}427 428define i2 @constant_multiplied_4xi2(i2 %0) {429; CHECK-LABEL: @constant_multiplied_4xi2(430; CHECK-NEXT: ret i2 0431;432 %2 = insertelement <4 x i2> poison, i2 %0, i32 0433 %3 = shufflevector <4 x i2> %2, <4 x i2> poison, <4 x i32> zeroinitializer434 %4 = tail call i2 @llvm.vector.reduce.add.v4i2(<4 x i2> %3)435 ret i2 %4436}437 438define i2 @constant_multiplied_5xi2(i2 %0) {439; CHECK-LABEL: @constant_multiplied_5xi2(440; CHECK-NEXT: ret i2 [[TMP0:%.*]]441;442 %2 = insertelement <5 x i2> poison, i2 %0, i64 0443 %3 = shufflevector <5 x i2> %2, <5 x i2> poison, <5 x i32> zeroinitializer444 %4 = tail call i2 @llvm.vector.reduce.add.v5i2(<5 x i2> %3)445 ret i2 %4446}447 448define i2 @constant_multiplied_6xi2(i2 %0) {449; CHECK-LABEL: @constant_multiplied_6xi2(450; CHECK-NEXT: [[TMP2:%.*]] = shl i2 [[TMP0:%.*]], 1451; CHECK-NEXT: ret i2 [[TMP2]]452;453 %2 = insertelement <6 x i2> poison, i2 %0, i64 0454 %3 = shufflevector <6 x i2> %2, <6 x i2> poison, <6 x i32> zeroinitializer455 %4 = tail call i2 @llvm.vector.reduce.add.v6i2(<6 x i2> %3)456 ret i2 %4457}458 459define i2 @constant_multiplied_7xi2(i2 %0) {460; CHECK-LABEL: @constant_multiplied_7xi2(461; CHECK-NEXT: [[TMP2:%.*]] = sub i2 0, [[TMP0:%.*]]462; CHECK-NEXT: ret i2 [[TMP2]]463;464 %2 = insertelement <7 x i2> poison, i2 %0, i64 0465 %3 = shufflevector <7 x i2> %2, <7 x i2> poison, <7 x i32> zeroinitializer466 %4 = tail call i2 @llvm.vector.reduce.add.v7i2(<7 x i2> %3)467 ret i2 %4468}469 470define i32 @negative_scalable_vector(i32 %0) {471; CHECK-LABEL: @negative_scalable_vector(472; CHECK-NEXT: [[TMP2:%.*]] = insertelement <vscale x 4 x i32> poison, i32 [[TMP0:%.*]], i64 0473; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer474; CHECK-NEXT: [[TMP4:%.*]] = tail call i32 @llvm.vector.reduce.add.nxv4i32(<vscale x 4 x i32> [[TMP3]])475; CHECK-NEXT: ret i32 [[TMP4]]476;477 %2 = insertelement <vscale x 4 x i32> poison, i32 %0, i64 0478 %3 = shufflevector <vscale x 4 x i32> %2, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer479 %4 = tail call i32 @llvm.vector.reduce.add.nxv4i32(<vscale x 4 x i32> %3)480 ret i32 %4481}482