| ; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "(Cost of .*(WIDEN-INDUCTION|SCALAR-STEPS|DERIVED-IV|WIDEN-POINTER-INDUCTION))|(canonical IV increment)|(Cost for VF)" --filter-out-after "LV: (Selecting|Using user) VF" --version 6 |
| ; REQUIRES: asserts |
| ; RUN: opt -passes=loop-vectorize -force-vector-width=2 -force-vector-interleave=1 -debug-only=loop-vectorize -disable-output %s 2>&1 | FileCheck --check-prefix=VF2 %s |
| ; RUN: opt -passes=loop-vectorize -force-vector-width=4 -force-vector-interleave=1 -debug-only=loop-vectorize -disable-output %s 2>&1 | FileCheck --check-prefix=VF4 %s |
| |
| define void @int_induction(ptr noalias %dst, i64 %n) { |
| ; VF2-LABEL: 'int_induction' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 0 for VF 2: vp<[[VP4:%[0-9]+]]> = SCALAR-STEPS vp<[[VP3:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost for VF 2: 6 (Estimated cost per lane: 3) |
| ; |
| ; VF4-LABEL: 'int_induction' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 0 for VF 4: vp<[[VP4:%[0-9]+]]> = SCALAR-STEPS vp<[[VP3:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost for VF 4: 6 (Estimated cost per lane: 1.5) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %gep = getelementptr inbounds i64, ptr %dst, i64 %iv |
| store i64 %iv, ptr %gep, align 8 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| define void @fp_induction(ptr noalias %dst, i64 %n) { |
| ; VF2-LABEL: 'fp_induction' |
| ; VF2: Cost of 2 for VF 2: ir<%fp.iv> = WIDEN-INDUCTION fast ir<0.000000e+00>, ir<1.000000e+00>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 0 for VF 2: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 1 for VF 2: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF2: Cost for VF 2: 6 (Estimated cost per lane: 3) |
| ; |
| ; VF4-LABEL: 'fp_induction' |
| ; VF4: Cost of 2 for VF 4: ir<%fp.iv> = WIDEN-INDUCTION fast ir<0.000000e+00>, ir<1.000000e+00>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 0 for VF 4: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 1 for VF 4: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF4: Cost for VF 4: 6 (Estimated cost per lane: 1.5) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %fp.iv = phi float [ 0.000000e+00, %entry ], [ %fp.iv.next, %loop ] |
| %gep = getelementptr inbounds float, ptr %dst, i64 %iv |
| store float %fp.iv, ptr %gep, align 4 |
| %fp.iv.next = fadd fast float %fp.iv, 1.000000e+00 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| define void @trunc_induction(ptr noalias %dst, i64 %n) { |
| ; VF2-LABEL: 'trunc_induction' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> (truncated to i32) |
| ; VF2: Cost of 0 for VF 2: vp<[[VP4:%[0-9]+]]> = SCALAR-STEPS vp<[[VP3:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost for VF 2: 6 (Estimated cost per lane: 3) |
| ; |
| ; VF4-LABEL: 'trunc_induction' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> (truncated to i32) |
| ; VF4: Cost of 0 for VF 4: vp<[[VP4:%[0-9]+]]> = SCALAR-STEPS vp<[[VP3:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost for VF 4: 6 (Estimated cost per lane: 1.5) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %iv.trunc = trunc i64 %iv to i32 |
| %gep = getelementptr inbounds i32, ptr %dst, i64 %iv |
| store i32 %iv.trunc, ptr %gep, align 4 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| define void @trunc_and_wide_induction(ptr noalias %dst, ptr noalias %dst2, i64 %n) { |
| ; VF2-LABEL: 'trunc_and_wide_induction' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 2 for VF 2: ir<%iv>.1 = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VP0]]> (truncated to i32) |
| ; VF2: Cost of 0 for VF 2: vp<[[VP4:%[0-9]+]]> = SCALAR-STEPS vp<[[VP3:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost for VF 2: 9 (Estimated cost per lane: 4.5) |
| ; |
| ; VF4-LABEL: 'trunc_and_wide_induction' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 2 for VF 4: ir<%iv>.1 = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VP0]]> (truncated to i32) |
| ; VF4: Cost of 0 for VF 4: vp<[[VP4:%[0-9]+]]> = SCALAR-STEPS vp<[[VP3:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost for VF 4: 9 (Estimated cost per lane: 2.25) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %iv.trunc = trunc i64 %iv to i32 |
| %gep = getelementptr inbounds i32, ptr %dst, i64 %iv |
| store i32 %iv.trunc, ptr %gep, align 4 |
| %gep2 = getelementptr inbounds i64, ptr %dst2, i64 %iv |
| store i64 %iv, ptr %gep2, align 8 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; All users of the FP induction need scalars, so no wide induction is generated |
| ; and the scalar steps materialize one FAdd per lane, except for the first. |
| define void @fp_induction_scalar_users(ptr noalias %dst, i64 %n) { |
| ; VF2-LABEL: 'fp_induction_scalar_users' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 1 for VF 2: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF2: Cost for VF 2: 10 (Estimated cost per lane: 5) |
| ; |
| ; VF4-LABEL: 'fp_induction_scalar_users' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 1 for VF 4: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF4: Cost of 3 for VF 4: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 1 for VF 4: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF4: Cost for VF 4: 14 (Estimated cost per lane: 3.5) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %fp.iv = phi float [ 0.000000e+00, %entry ], [ %fp.iv.next, %loop ] |
| %idx = mul i64 %iv, 3 |
| %gep = getelementptr inbounds float, ptr %dst, i64 %idx |
| store float %fp.iv, ptr %gep, align 4 |
| %fp.iv.next = fadd fast float %fp.iv, 1.000000e+00 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; Same as @fp_induction_scalar_users, but for a decreasing induction, which uses |
| ; FSub to compute the per-lane values. |
| define void @fp_induction_fsub_scalar_users(ptr noalias %dst, i64 %n) { |
| ; VF2-LABEL: 'fp_induction_fsub_scalar_users' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 2 for VF 2: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<1.000000e+02> + vp<[[VP4:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 2 for VF 2: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<1.000000e+02> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF2: Cost for VF 2: 11 (Estimated cost per lane: 5.5) |
| ; |
| ; VF4-LABEL: 'fp_induction_fsub_scalar_users' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 2 for VF 4: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<1.000000e+02> + vp<[[VP4:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF4: Cost of 3 for VF 4: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 2 for VF 4: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<1.000000e+02> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF4: Cost for VF 4: 15 (Estimated cost per lane: 3.75) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %fp.iv = phi float [ 1.000000e+02, %entry ], [ %fp.iv.next, %loop ] |
| %idx = mul i64 %iv, 3 |
| %gep = getelementptr inbounds float, ptr %dst, i64 %idx |
| store float %fp.iv, ptr %gep, align 4 |
| %fp.iv.next = fsub fast float %fp.iv, 1.000000e+00 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; Same as @fp_induction_scalar_users, but with a loop-invariant step. |
| define void @fp_induction_invariant_step_scalar_users(ptr noalias %dst, float %step, i64 %n) { |
| ; VF2-LABEL: 'fp_induction_invariant_step_scalar_users' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 3 for VF 2: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<%step> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<%step>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 3 for VF 2: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<%step> |
| ; VF2: Cost for VF 2: 12 (Estimated cost per lane: 6) |
| ; |
| ; VF4-LABEL: 'fp_induction_invariant_step_scalar_users' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 3 for VF 4: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<%step> |
| ; VF4: Cost of 3 for VF 4: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<%step>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 3 for VF 4: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<%step> |
| ; VF4: Cost for VF 4: 16 (Estimated cost per lane: 4) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %fp.iv = phi float [ 0.000000e+00, %entry ], [ %fp.iv.next, %loop ] |
| %idx = mul i64 %iv, 3 |
| %gep = getelementptr inbounds float, ptr %dst, i64 %idx |
| store float %fp.iv, ptr %gep, align 4 |
| %fp.iv.next = fadd fast float %fp.iv, %step |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; Same as @fp_induction_scalar_users (fadd, unit step, zero start), but |
| ; without fast-math flags. The add is still expected to fold away: with a |
| ; unit step the DERIVED-IV's addend is exactly sitofp(<the non-negative |
| ; canonical/scalar IV>), which can never be -0.0, so "fadd 0.0, X" folds to X |
| ; regardless of fast-math flags. |
| define void @fp_induction_no_fastmath_unit_step_zero_start(ptr noalias %dst, i64 %n) { |
| ; VF2-LABEL: 'fp_induction_no_fastmath_unit_step_zero_start' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 1 for VF 2: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF2: Cost for VF 2: 10 (Estimated cost per lane: 5) |
| ; |
| ; VF4-LABEL: 'fp_induction_no_fastmath_unit_step_zero_start' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 1 for VF 4: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF4: Cost of 3 for VF 4: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 1 for VF 4: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF4: Cost for VF 4: 14 (Estimated cost per lane: 3.5) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %fp.iv = phi float [ 0.000000e+00, %entry ], [ %fp.iv.next, %loop ] |
| %idx = mul i64 %iv, 3 |
| %gep = getelementptr inbounds float, ptr %dst, i64 %idx |
| store float %fp.iv, ptr %gep, align 4 |
| %fp.iv.next = fadd float %fp.iv, 1.000000e+00 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; Same as @fp_induction_no_fastmath_unit_step_zero_start, but with a |
| ; loop-invariant, sign-unknown step. Unlike the unit-step case, the add is |
| ; not known to fold away here: with a non-unit step the DERIVED-IV's addend |
| ; is Step * sitofp(Index), whose sign depends on the unknown sign of Step, so |
| ; it may be -0.0, and "fadd 0.0, X" doesn't fold to X in that case. |
| define void @fp_induction_no_fastmath_zero_start_invariant_step(ptr noalias %dst, float %step, i64 %n) { |
| ; VF2-LABEL: 'fp_induction_no_fastmath_zero_start_invariant_step' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 3 for VF 2: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<%step> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<%step>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 3 for VF 2: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<%step> |
| ; VF2: Cost for VF 2: 12 (Estimated cost per lane: 6) |
| ; |
| ; VF4-LABEL: 'fp_induction_no_fastmath_zero_start_invariant_step' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 3 for VF 4: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<%step> |
| ; VF4: Cost of 3 for VF 4: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<%step>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 3 for VF 4: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<%step> |
| ; VF4: Cost for VF 4: 16 (Estimated cost per lane: 4) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %fp.iv = phi float [ 0.000000e+00, %entry ], [ %fp.iv.next, %loop ] |
| %idx = mul i64 %iv, 3 |
| %gep = getelementptr inbounds float, ptr %dst, i64 %idx |
| store float %fp.iv, ptr %gep, align 4 |
| %fp.iv.next = fadd float %fp.iv, %step |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; FSub never folds away for a zero start, regardless of the step: "fsub 0.0, |
| ; X" isn't X, at best it simplifies to "fneg X", which is still a real |
| ; instruction. |
| define void @fp_induction_fsub_zero_start(ptr noalias %dst, i64 %n) { |
| ; VF2-LABEL: 'fp_induction_fsub_zero_start' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 2 for VF 2: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 2 for VF 2: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF2: Cost for VF 2: 11 (Estimated cost per lane: 5.5) |
| ; |
| ; VF4-LABEL: 'fp_induction_fsub_zero_start' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 2 for VF 4: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF4: Cost of 3 for VF 4: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 2 for VF 4: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF4: Cost for VF 4: 15 (Estimated cost per lane: 3.75) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %fp.iv = phi float [ 0.000000e+00, %entry ], [ %fp.iv.next, %loop ] |
| %idx = mul i64 %iv, 3 |
| %gep = getelementptr inbounds float, ptr %dst, i64 %idx |
| store float %fp.iv, ptr %gep, align 4 |
| %fp.iv.next = fsub fast float %fp.iv, 1.000000e+00 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; Start of -0.0 so the FAdd can be folded. |
| define void @fp_induction_neg_zero_start_neg_step(ptr noalias %dst, i64 %n) { |
| ; VF2-LABEL: 'fp_induction_neg_zero_start_neg_step' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 2 for VF 2: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<-0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<-2.000000e+00> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<-2.000000e+00>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 2 for VF 2: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<-0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<-2.000000e+00> |
| ; VF2: Cost for VF 2: 11 (Estimated cost per lane: 5.5) |
| ; |
| ; VF4-LABEL: 'fp_induction_neg_zero_start_neg_step' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 2 for VF 4: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<-0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<-2.000000e+00> |
| ; VF4: Cost of 3 for VF 4: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<-2.000000e+00>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 2 for VF 4: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<-0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<-2.000000e+00> |
| ; VF4: Cost for VF 4: 15 (Estimated cost per lane: 3.75) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %fp.iv = phi float [ -0.000000e+00, %entry ], [ %fp.iv.next, %loop ] |
| %idx = mul i64 %iv, 3 |
| %gep = getelementptr inbounds float, ptr %dst, i64 %idx |
| store float %fp.iv, ptr %gep, align 4 |
| %fp.iv.next = fadd float %fp.iv, -2.000000e+00 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; Same as @fp_induction_neg_zero_start_neg_step, but with a +0.0 start: the |
| ; FAdd cannot be folded. |
| define void @fp_induction_pos_zero_start_neg_step(ptr noalias %dst, i64 %n) { |
| ; VF2-LABEL: 'fp_induction_pos_zero_start_neg_step' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 3 for VF 2: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<-2.000000e+00> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<-2.000000e+00>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 3 for VF 2: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<-2.000000e+00> |
| ; VF2: Cost for VF 2: 12 (Estimated cost per lane: 6) |
| ; |
| ; VF4-LABEL: 'fp_induction_pos_zero_start_neg_step' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 3 for VF 4: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<-2.000000e+00> |
| ; VF4: Cost of 3 for VF 4: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<-2.000000e+00>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 3 for VF 4: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<-2.000000e+00> |
| ; VF4: Cost for VF 4: 16 (Estimated cost per lane: 4) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %fp.iv = phi float [ 0.000000e+00, %entry ], [ %fp.iv.next, %loop ] |
| %idx = mul i64 %iv, 3 |
| %gep = getelementptr inbounds float, ptr %dst, i64 %idx |
| store float %fp.iv, ptr %gep, align 4 |
| %fp.iv.next = fadd float %fp.iv, -2.000000e+00 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; Same as @fp_induction_pos_zero_start_neg_step, but with a positive step. |
| define void @fp_induction_pos_zero_start_pos_step(ptr noalias %dst, i64 %n) { |
| ; VF2-LABEL: 'fp_induction_pos_zero_start_pos_step' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 3 for VF 2: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<2.000000e+00> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<2.000000e+00>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 3 for VF 2: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<2.000000e+00> |
| ; VF2: Cost for VF 2: 12 (Estimated cost per lane: 6) |
| ; |
| ; VF4-LABEL: 'fp_induction_pos_zero_start_pos_step' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 3 for VF 4: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4:%[0-9]+]]> * ir<2.000000e+00> |
| ; VF4: Cost of 3 for VF 4: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<2.000000e+00>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 3 for VF 4: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<2.000000e+00> |
| ; VF4: Cost for VF 4: 16 (Estimated cost per lane: 4) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %fp.iv = phi float [ 0.000000e+00, %entry ], [ %fp.iv.next, %loop ] |
| %idx = mul i64 %iv, 3 |
| %gep = getelementptr inbounds float, ptr %dst, i64 %idx |
| store float %fp.iv, ptr %gep, align 4 |
| %fp.iv.next = fadd float %fp.iv, 2.000000e+00 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; A non-zero start value never folds, so the FAdd is charged even though the |
| ; unit step folds the FMul away. |
| define void @fp_induction_invariant_start(ptr noalias %dst, float %start, i64 %n) { |
| ; VF2-LABEL: 'fp_induction_invariant_start' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 2 for VF 2: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<%start> + vp<[[VP4:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 2 for VF 2: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<%start> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF2: Cost for VF 2: 11 (Estimated cost per lane: 5.5) |
| ; |
| ; VF4-LABEL: 'fp_induction_invariant_start' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 2 for VF 4: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<%start> + vp<[[VP4:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF4: Cost of 3 for VF 4: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 2 for VF 4: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<%start> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF4: Cost for VF 4: 15 (Estimated cost per lane: 3.75) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %fp.iv = phi float [ %start, %entry ], [ %fp.iv.next, %loop ] |
| %idx = mul i64 %iv, 3 |
| %gep = getelementptr inbounds float, ptr %dst, i64 %idx |
| store float %fp.iv, ptr %gep, align 4 |
| %fp.iv.next = fadd float %fp.iv, 1.000000e+00 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; The FP induction is only used outside the loop, so it is dead in the vector |
| ; loop and nothing is charged for it. |
| define float @fp_induction_used_outside_loop_only(ptr noalias %dst, i64 %n) { |
| ; VF2-LABEL: 'fp_induction_used_outside_loop_only' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 0 for VF 2: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost for VF 2: 8 (Estimated cost per lane: 4) |
| ; |
| ; VF4-LABEL: 'fp_induction_used_outside_loop_only' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 0 for VF 4: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost for VF 4: 8 (Estimated cost per lane: 2) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %fp.iv = phi float [ 0.000000e+00, %entry ], [ %fp.iv.next, %loop ] |
| %gep = getelementptr inbounds i64, ptr %dst, i64 %iv |
| store i64 %iv, ptr %gep, align 8 |
| %fp.iv.next = fadd fast float %fp.iv, 1.000000e+00 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret float %fp.iv.next |
| } |
| |
| ; The FP induction has both wide and scalar users, so both the wide induction |
| ; and the scalar steps are generated and need to be accounted for. |
| define void @fp_induction_wide_and_scalar_users(ptr noalias %dst, ptr noalias %dst2, i64 %n) { |
| ; VF2-LABEL: 'fp_induction_wide_and_scalar_users' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 2 for VF 2: ir<%fp.iv> = WIDEN-INDUCTION fast ir<0.000000e+00>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF2: Cost of 0 for VF 2: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP6:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4]]> * ir<1.000000e+00> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP7:%[0-9]+]]> = SCALAR-STEPS vp<[[VP6]]>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 1 for VF 2: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF2: Cost for VF 2: 13 (Estimated cost per lane: 6.5) |
| ; |
| ; VF4-LABEL: 'fp_induction_wide_and_scalar_users' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 2 for VF 4: ir<%fp.iv> = WIDEN-INDUCTION fast ir<0.000000e+00>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF4: Cost of 0 for VF 4: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: vp<[[VP6:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4]]> * ir<1.000000e+00> |
| ; VF4: Cost of 3 for VF 4: vp<[[VP7:%[0-9]+]]> = SCALAR-STEPS vp<[[VP6]]>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 1 for VF 4: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF4: Cost for VF 4: 17 (Estimated cost per lane: 4.25) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %fp.iv = phi float [ 0.000000e+00, %entry ], [ %fp.iv.next, %loop ] |
| %gep = getelementptr inbounds float, ptr %dst, i64 %iv |
| store float %fp.iv, ptr %gep, align 4 |
| %idx = mul i64 %iv, 3 |
| %gep2 = getelementptr inbounds float, ptr %dst2, i64 %idx |
| store float %fp.iv, ptr %gep2, align 4 |
| %fp.iv.next = fadd fast float %fp.iv, 1.000000e+00 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; The scalar steps are inside a replicate region, for which no cost is computed |
| ; yet. |
| define void @fp_induction_predicated(ptr noalias %dst, ptr noalias %cond, i64 %n) { |
| ; VF2-LABEL: 'fp_induction_predicated' |
| ; VF2: Cost of 2 for VF 2: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 0 for VF 2: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP6:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4]]> * ir<1.000000e+00> |
| ; VF2: Cost of 0.5 for VF 2: vp<[[VP8:%[0-9]+]]> = SCALAR-STEPS vp<[[VP6]]>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 1 for VF 2: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF2: Cost for VF 2: 12.5 (Estimated cost per lane: 6) |
| ; |
| ; VF4-LABEL: 'fp_induction_predicated' |
| ; VF4: Cost of 2 for VF 4: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 0 for VF 4: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: vp<[[VP6:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP4]]> * ir<1.000000e+00> |
| ; VF4: Cost of 1.5 for VF 4: vp<[[VP8:%[0-9]+]]> = SCALAR-STEPS vp<[[VP6]]>, ir<1.000000e+00>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 1 for VF 4: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF4: Cost for VF 4: 16.5 (Estimated cost per lane: 4) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] |
| %fp.iv = phi float [ 0.000000e+00, %entry ], [ %fp.iv.next, %latch ] |
| %c.gep = getelementptr inbounds i8, ptr %cond, i64 %iv |
| %c = load i8, ptr %c.gep, align 1 |
| %c.0 = icmp eq i8 %c, 0 |
| br i1 %c.0, label %latch, label %then |
| |
| then: |
| %idx = mul i64 %iv, 3 |
| %gep = getelementptr inbounds float, ptr %dst, i64 %idx |
| store float %fp.iv, ptr %gep, align 4 |
| br label %latch |
| |
| latch: |
| %fp.iv.next = fadd fast float %fp.iv, 1.000000e+00 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; The vector loop is executed exactly once for VF 4, so the induction increments |
| ; and the canonical IV increment are all simplified away. |
| define void @fp_induction_tc_eq_4(ptr noalias %dst) { |
| ; VF2-LABEL: 'fp_induction_tc_eq_4' |
| ; VF2: Cost of 2 for VF 2: ir<%fp.iv> = WIDEN-INDUCTION fast ir<0.000000e+00>, ir<1.000000e+00>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 0 for VF 2: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 1 for VF 2: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF2: Cost for VF 2: 6 (Estimated cost per lane: 3) |
| ; |
| ; VF4-LABEL: 'fp_induction_tc_eq_4' |
| ; VF4: Cost of 0 for VF 4: ir<%fp.iv> = WIDEN-INDUCTION fast ir<0.000000e+00>, ir<1.000000e+00>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 0 for VF 4: vp<[[VP5:%[0-9]+]]> = SCALAR-STEPS vp<[[VP4:%[0-9]+]]>, ir<1>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2:%[0-9]+]]> * ir<1.000000e+00> |
| ; VF4: Cost for VF 4: 2 (Estimated cost per lane: 0.5) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %fp.iv = phi float [ 0.000000e+00, %entry ], [ %fp.iv.next, %loop ] |
| %gep = getelementptr inbounds float, ptr %dst, i64 %iv |
| store float %fp.iv, ptr %gep, align 4 |
| %fp.iv.next = fadd fast float %fp.iv, 1.000000e+00 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, 4 |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; The loop is advanced by both an FP and a pointer induction. Neither induction |
| ; is costed by the legacy cost model any more; the scalarized pointer induction |
| ; is covered by its DERIVED-IV and SCALAR-STEPS recipes. |
| define void @fp_and_ptr_induction(ptr noalias %dst, ptr %end) { |
| ; VF2-LABEL: 'fp_and_ptr_induction' |
| ; VF2: Cost of 2 for VF 2: ir<%fp.iv> = WIDEN-INDUCTION fast ir<0.000000e+00>, ir<1.000000e+00>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP7:%[0-9]+]]> = DERIVED-IV ir<0> + vp<[[VP6:%[0-9]+]]> * ir<4> |
| ; VF2: Cost of 0 for VF 2: vp<[[VP8:%[0-9]+]]> = SCALAR-STEPS vp<[[VP7]]>, ir<4>, vp<[[VP0]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 0 for VF 2: vp<[[VP4:%[0-9]+]]> = DERIVED-IV ir<%dst> + vp<[[VP2:%[0-9]+]]> * ir<4> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2]]> * ir<1.000000e+00> |
| ; VF2: Cost for VF 2: 7 (Estimated cost per lane: 3.5) |
| ; |
| ; VF4-LABEL: 'fp_and_ptr_induction' |
| ; VF4: Cost of 2 for VF 4: ir<%fp.iv> = WIDEN-INDUCTION fast ir<0.000000e+00>, ir<1.000000e+00>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 1 for VF 4: vp<[[VP7:%[0-9]+]]> = DERIVED-IV ir<0> + vp<[[VP6:%[0-9]+]]> * ir<4> |
| ; VF4: Cost of 0 for VF 4: vp<[[VP8:%[0-9]+]]> = SCALAR-STEPS vp<[[VP7]]>, ir<4>, vp<[[VP0]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 0 for VF 4: vp<[[VP4:%[0-9]+]]> = DERIVED-IV ir<%dst> + vp<[[VP2:%[0-9]+]]> * ir<4> |
| ; VF4: Cost of 1 for VF 4: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0.000000e+00> + vp<[[VP2]]> * ir<1.000000e+00> |
| ; VF4: Cost for VF 4: 7 (Estimated cost per lane: 1.75) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %ptr.iv = phi ptr [ %dst, %entry ], [ %ptr.iv.next, %loop ] |
| %fp.iv = phi float [ 0.000000e+00, %entry ], [ %fp.iv.next, %loop ] |
| store float %fp.iv, ptr %ptr.iv, align 4 |
| %fp.iv.next = fadd fast float %fp.iv, 1.000000e+00 |
| %ptr.iv.next = getelementptr inbounds float, ptr %ptr.iv, i64 1 |
| %ec = icmp eq ptr %ptr.iv.next, %end |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; Same as @fp_and_ptr_induction, but the loop is only advanced by a pointer |
| ; induction. The canonical IV increment is still charged, even though the GEP |
| ; incrementing the pointer induction is free in the scalar cost. |
| define void @ptr_induction_only(ptr %start, ptr %end) { |
| ; VF2-LABEL: 'ptr_induction_only' |
| ; VF2: Cost of 0 for VF 2: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5:%[0-9]+]]>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 0 for VF 2: vp<[[VP4:%[0-9]+]]> = DERIVED-IV ir<%start> + vp<[[VP2:%[0-9]+]]> * ir<1> |
| ; VF2: Cost for VF 2: 6 (Estimated cost per lane: 3) |
| ; |
| ; VF4-LABEL: 'ptr_induction_only' |
| ; VF4: Cost of 0 for VF 4: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5:%[0-9]+]]>, ir<1>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 0 for VF 4: vp<[[VP4:%[0-9]+]]> = DERIVED-IV ir<%start> + vp<[[VP2:%[0-9]+]]> * ir<1> |
| ; VF4: Cost for VF 4: 6 (Estimated cost per lane: 1.5) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop ] |
| %l = load i8, ptr %ptr.iv, align 1 |
| %a = add i8 %l, 1 |
| store i8 %a, ptr %ptr.iv, align 1 |
| %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 1 |
| %ec = icmp eq ptr %ptr.iv.next, %end |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| define void @ptr_induction(ptr noalias %dst, ptr %end) { |
| ; VF2-LABEL: 'ptr_induction' |
| ; VF2: Cost of 1 for VF 2: vp<[[VP6:%[0-9]+]]> = DERIVED-IV ir<0> + vp<[[VP5:%[0-9]+]]> * ir<8> |
| ; VF2: Cost of 0 for VF 2: vp<[[VP7:%[0-9]+]]> = SCALAR-STEPS vp<[[VP6]]>, ir<8>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 0 for VF 2: vp<[[VP4:%[0-9]+]]> = DERIVED-IV ir<%dst> + vp<[[VP2:%[0-9]+]]> * ir<8> |
| ; VF2: Cost for VF 2: 5 (Estimated cost per lane: 2.5) |
| ; |
| ; VF4-LABEL: 'ptr_induction' |
| ; VF4: Cost of 1 for VF 4: vp<[[VP6:%[0-9]+]]> = DERIVED-IV ir<0> + vp<[[VP5:%[0-9]+]]> * ir<8> |
| ; VF4: Cost of 0 for VF 4: vp<[[VP7:%[0-9]+]]> = SCALAR-STEPS vp<[[VP6]]>, ir<8>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 0 for VF 4: vp<[[VP4:%[0-9]+]]> = DERIVED-IV ir<%dst> + vp<[[VP2:%[0-9]+]]> * ir<8> |
| ; VF4: Cost for VF 4: 5 (Estimated cost per lane: 1.25) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %ptr.iv = phi ptr [ %dst, %entry ], [ %ptr.iv.next, %loop ] |
| store i64 0, ptr %ptr.iv, align 8 |
| %ptr.iv.next = getelementptr inbounds i64, ptr %ptr.iv, i64 1 |
| %ec = icmp eq ptr %ptr.iv.next, %end |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; Same as @ptr_induction, but the vector loop body executes at most once for |
| ; VF 4, so there the canonical IV increment is simplified away and must not be |
| ; costed. |
| define void @ptr_induction_tc_eq_vf(ptr noalias %dst) { |
| ; VF2-LABEL: 'ptr_induction_tc_eq_vf' |
| ; VF2: Cost of 1 for VF 2: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0> + vp<[[VP4:%[0-9]+]]> * ir<8> |
| ; VF2: Cost of 0 for VF 2: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<8>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 0 for VF 2: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<%dst> + vp<[[VP2:%[0-9]+]]> * ir<8> |
| ; VF2: Cost for VF 2: 5 (Estimated cost per lane: 2.5) |
| ; |
| ; VF4-LABEL: 'ptr_induction_tc_eq_vf' |
| ; VF4: Cost of 1 for VF 4: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<0> + vp<[[VP4:%[0-9]+]]> * ir<8> |
| ; VF4: Cost of 0 for VF 4: vp<[[VP6:%[0-9]+]]> = SCALAR-STEPS vp<[[VP5]]>, ir<8>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 0 for VF 4: vp<[[VP3:%[0-9]+]]> = DERIVED-IV ir<%dst> + vp<[[VP2:%[0-9]+]]> * ir<8> |
| ; VF4: Cost for VF 4: 3 (Estimated cost per lane: 0.75) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %ptr.iv = phi ptr [ %dst, %entry ], [ %ptr.iv.next, %loop ] |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| store i64 0, ptr %ptr.iv, align 8 |
| %ptr.iv.next = getelementptr inbounds i64, ptr %ptr.iv, i64 1 |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, 4 |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; Test case where %ptr.iv remains a wide pointer induction, while %arr.iv is scalarized. |
| define void @ptr_induction_widened(ptr noalias %dst, ptr noalias %arr, ptr %end) { |
| ; VF2-LABEL: 'ptr_induction_widened' |
| ; VF2: Cost of 1 for VF 2: EMIT ir<%ptr.iv> = WIDEN-POINTER-INDUCTION ir<%dst>, ir<8>, vp<[[VP1:%[0-9]+]]> |
| ; VF2: Cost of 1 for VF 2: vp<[[VP7:%[0-9]+]]> = DERIVED-IV ir<0> + vp<[[VP6:%[0-9]+]]> * ir<8> |
| ; VF2: Cost of 0 for VF 2: vp<[[VP8:%[0-9]+]]> = SCALAR-STEPS vp<[[VP7]]>, ir<8>, vp<[[VP0:%[0-9]+]]> |
| ; VF2: Cost of 1 for VF 2: canonical IV increment |
| ; VF2: Cost of 0 for VF 2: vp<[[VP4:%[0-9]+]]> = DERIVED-IV ir<%dst> + vp<[[VP2:%[0-9]+]]> * ir<8> |
| ; VF2: Cost of 0 for VF 2: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<%arr> + vp<[[VP2]]> * ir<8> |
| ; VF2: Cost for VF 2: 7 (Estimated cost per lane: 3.5) |
| ; |
| ; VF4-LABEL: 'ptr_induction_widened' |
| ; VF4: Cost of 1 for VF 4: EMIT ir<%ptr.iv> = WIDEN-POINTER-INDUCTION ir<%dst>, ir<8>, vp<[[VP1:%[0-9]+]]> |
| ; VF4: Cost of 1 for VF 4: vp<[[VP7:%[0-9]+]]> = DERIVED-IV ir<0> + vp<[[VP6:%[0-9]+]]> * ir<8> |
| ; VF4: Cost of 0 for VF 4: vp<[[VP8:%[0-9]+]]> = SCALAR-STEPS vp<[[VP7]]>, ir<8>, vp<[[VP0:%[0-9]+]]> |
| ; VF4: Cost of 1 for VF 4: canonical IV increment |
| ; VF4: Cost of 0 for VF 4: vp<[[VP4:%[0-9]+]]> = DERIVED-IV ir<%dst> + vp<[[VP2:%[0-9]+]]> * ir<8> |
| ; VF4: Cost of 0 for VF 4: vp<[[VP5:%[0-9]+]]> = DERIVED-IV ir<%arr> + vp<[[VP2]]> * ir<8> |
| ; VF4: Cost for VF 4: 7 (Estimated cost per lane: 1.75) |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %ptr.iv = phi ptr [ %dst, %entry ], [ %ptr.iv.next, %loop ] |
| %arr.iv = phi ptr [ %arr, %entry ], [ %arr.iv.next, %loop ] |
| store ptr %ptr.iv, ptr %arr.iv, align 8 |
| store i64 0, ptr %ptr.iv, align 8 |
| %ptr.iv.next = getelementptr inbounds i64, ptr %ptr.iv, i64 1 |
| %arr.iv.next = getelementptr inbounds ptr, ptr %arr.iv, i64 1 |
| %ec = icmp eq ptr %ptr.iv.next, %end |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |