<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/151664>151664</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[LV] Cost computation skipped for hoisted vector code
</td>
</tr>
<tr>
<th>Labels</th>
<td>
bug,
vectorizers,
vectorization
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
artagnon
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
artagnon
</td>
</tr>
</table>
<pre>
Consider an intrinsic that has an invalid SVE cost like in https://godbolt.org/z/4M46fvMnc:
```llvm
; RUN: opt -mtriple aarch64 -mattr=+sve -passes="print<cost-model>"
define <4 x float> @minimumnum.fixed(<4 x float> %a, <4 x float> %b) {
%c = call <4 x float> @llvm.minimumnum(<4 x float> %a, <4 x float> %b)
ret <4 x float> %c
}
define <vscale x 4 x float> @minimumnum(<vscale x 4 x float> %a, <vscale x 4 x float> %b) {
%c = call <vscale x 4 x float> @llvm.minimumnum(<vscale x 4 x float> %a, <vscale x 4 x float> %b)
ret <vscale x 4 x float> %c
}
```
Now, running loop-vectorize should respect this invalid cost, and not produce a `<vscale x 4 x float> @llvm.minimumnum`. Running this:
```llvm
; RUN: opt -passes=loop-vectorize,simplifycfg -mtriple=aarch64 -mattr=+sve -S %s
define void @vectorized_hoisted(ptr %p) {
entry:
br label %loop
loop: ; preds = %loop, %entry
%iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
%idx = phi i64 [ 0, %entry ], [ %idx.next, %loop ]
%res = tail call float @llvm.minimumnum.f32(float 0.0, float 0.0)
%gep.p.red = getelementptr float, ptr %p, i64 %idx
store float %res, ptr %gep.p.red, align 4
%idx.next = add i64 %idx, 1
%iv.next = add i64 %iv, 1
%exit.cond = icmp eq i64 %iv.next, 0
br i1 %exit.cond, label %exit, label %loop
exit: ; preds = %loop
ret void
}
declare float @llvm.minimumnum.f32(float, float)
```
yields:
```llvm
; ModuleID = 'reduced.ll'
source_filename = "reduced.ll"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
target triple = "aarch64"
define void @vectorized_hoisted(ptr %p) #0 {
entry:
%0 = call i64 @llvm.vscale.i64()
%1 = mul nuw i64 %0, 8
%n.mod.vf = urem i64 -1, %1
%n.vec = sub i64 -1, %n.mod.vf
%2 = call i64 @llvm.vscale.i64()
%3 = mul nuw i64 %2, 8
%4 = add i64 1, %n.vec
%5 = call <vscale x 4 x float> @llvm.minimumnum.nxv4f32(<vscale x 4 x float> zeroinitializer, <vscale x 4 x float> zeroinitializer)
br label %vector.body
vector.body: ; preds = %vector.body, %entry
%index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
%6 = getelementptr float, ptr %p, i64 %index
%7 = call i64 @llvm.vscale.i64()
%8 = mul nuw i64 %7, 4
%9 = getelementptr float, ptr %6, i64 %8
store <vscale x 4 x float> %5, ptr %6, align 4
store <vscale x 4 x float> %5, ptr %9, align 4
%index.next = add nuw i64 %index, %3
%10 = icmp eq i64 %index.next, %n.vec
br i1 %10, label %middle.block, label %vector.body, !llvm.loop !0
middle.block: ; preds = %vector.body
%cmp.n = icmp eq i64 -1, %n.vec
br i1 %cmp.n, label %exit, label %loop
loop: ; preds = %middle.block, %loop
%iv = phi i64 [ %iv.next, %loop ], [ %4, %middle.block ]
%idx = phi i64 [ %idx.next, %loop ], [ %n.vec, %middle.block ]
%res = tail call float @llvm.minimumnum.f32(float 0.000000e+00, float 0.000000e+00)
%gep.p.red = getelementptr float, ptr %p, i64 %idx
store float %res, ptr %gep.p.red, align 4
%idx.next = add i64 %idx, 1
%iv.next = add i64 %iv, 1
%exit.cond = icmp eq i64 %iv.next, 0
br i1 %exit.cond, label %exit, label %loop, !llvm.loop !3
exit: ; preds = %middle.block, %loop
ret void
}
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare float @llvm.minimumnum.f32(float, float) #1
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
declare i64 @llvm.vscale.i64() #2
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare <vscale x 4 x float> @llvm.minimumnum.nxv4f32(<vscale x 4 x float>, <vscale x 4 x float>) #3
attributes #0 = { "target-features"="+sve" }
attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) "target-features"="+sve" }
attributes #2 = { nocallback nofree nosync nounwind willreturn memory(none) }
attributes #3 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
!0 = distinct !{!0, !1, !2}
!1 = !{!"llvm.loop.isvectorized", i32 1}
!2 = !{!"llvm.loop.unroll.runtime.disable"}
!3 = distinct !{!3, !2, !1}
```
LV doesn't seem to cost hoisted instructions. No crash is observed yet due to this bug, but https://github.com/llvm/llvm-project/pull/145545 exhibits a crash.
CC: @davemgreen, @fhahn, @lukel97.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsWM1u4zgSfhrmUrAgUZKtHHxwnA6wwHQfprF9HdBi2eaGIrUk5Xb66RckZVmOfzbOzO5pAsMxpariV_9FMmvFRiHOSflEKGXGsY3SilBKyucH1rmtNvPD04eV5m_zpVZWcDTAFAjljFBW1OC2zMGW2fh0x6Tg8P3HF6i1dSDFK4JQsHWutSRfEPpC6MtG85WWLtFmQ-jLL0Jfiq_FdL37qmpPk4bPNI0fKXeNX-dP8Ps_v5F8Abp1MGmcEa1EYMzU22kBk4Y5Z0j-TOiT3SFMWmYt2vCAtkYoR_KlxzRpNEdJ8i9e1bAVx7VQCCRfFrCHtdTMkfwLkCJthBJN16iuSdZij5zQ6oyKlozQ5Tk3LVeEPgKZPZF0AX5dA8mfoWZSXtrL65kcN7x_q7CNQXfpfe01nT2_13dnayYR9nBd8YjjCuER0FWC20a4CuCiNf4cirF9rhKODHUIwGi0b_qn38R0Sgm1Aal1O9lh7bQRvxDsVneSg0HbYu3AbYUdksEHnWdlioPSDlqjeVcjMPDC77DBNE3g935_v8OHc2VIhVPUhC6taFop1m_1ejOkFMmfrybVd28jexJGOy24RzuI5X9stbAuZEvrjOdoj0GAypm3iBxgZUCyFUpP47FFweFXvgCvRmuQ2xAyBxLvaVpGMX1MiV2gaLcCxLQAUj5BNqYDUj6HdfkUyROFe9dTeKGB4CCM78-kpbek8f0tcQYjfMeEjGEfXHzBv8k6p4RW8XWahD1Hi8eDxA22SZsY5EHuBh1KbFA5b-sYPnQJR8MvoxYBaBBhnTZ4QBEAjhgG4SFipdgoKEaWCZqGfRnnY8F0CdnRHZfJdgOVN-VeuKTWKmoh6qYF_PeRdDBpeggUkZ2w-XdD7PinJw-OwRRe5Qu46-9y5KWLUD58wJ-W01qyo0Vv-nXwafTnuxrzJlDy22n9VfNO4j-ee2Azg76W8ERKQmckXVjdmRr_WAuJijXYk9Exme96jpkNOuDMMcnedOcOhDhpSL7ASUtnKckXOQ1ffpmdLv2vaRG-JqIi-aKKr0Q2JfkifPnVQJL5Cr7IaDVReeSdfPerF78cY-r7eo-nr0Tve_XHiw7N00uVh9AyPXaiEHa942I5TjxyWo3SLgvkTSdBdT8PgRqStOpDWiWN5sluHQg7g02gmhxK0ZAfKtlhbIO2W53SHEQcSOl9GPNLGOmA0a-Kk7Q87rvDulej_FSHTtR-V8RIv8r1C40WSjjBpPiF5mbTPqN9POsY0fmJn01jcIwffDTlz1J9LORSr1Ec72wQnmPcIkY7jDvF9N567uUemGf3BUp1KVBmXvhQ7R8_AGc6glONmsutCat8zz_uMvexP15qUoO1h0AfqRhtFt2QD5mdXuxB79025MixG2XpSddpBOcSk5XU9evJi7OYyoJ34qxAs778n7Bfmn9OAz6O002bqDP4k7O8PmIOHB_tnldHsfeqjnrklYns-uB1TJWifzWW_t9msxsj2FFwtMNt4Z-f1MIfEvqUng5tJ8__nt_und8uZEr--aHurhC-NOd5AS-dqp3QChbOGT-pgdI-VFasfgWl1wYRlLZvqgalO_VTKA7-SNhJ5thKIvwUUhp0nVHQYKPNG6GV0gpjfHx2lPRjTvbnUH4M2K3e4kHQ_7up_toR5dZI0qvYh6A_GItV53zRCDOmD6qZLzY0DrKTNTLXheyk8RYqHqIJpRBj6lRENoj46-z0eTT0DjQ3AVyQnf9PNB3SlPb9nAvrhKp9kcz8CYBm_ZSW9d0xoz0TzXrjHwgJpUPZSYQ9njKC3ZYgcgrZwExvMHfKaCkT0yknGky4sF4TL-bAnV8Bmw8gD6AvXUv99gO4RqsInTmwiA04Ha9e-_MQCGWd6UIq2gS-aagNs1sQFvTKotkhhzd_FOzQs4abq1W38ZuuOvf-4la4bbdKat0Q-hJOpfHfpDX6X1g7Ql_azp8xX7KiLIsScL8VK-EssLhtElEvl2GoKFLOdthsDGKYSEiRrrdse_gtu1eUj7Pkgc9z_pg_sgecZ7OySPMiq-jDdp6XVUn5GutstV4XWZnlnFXTKmXVbLVm9fRBzGlKy7RKs3RW5ClN8llBK5pmdVUVU7pOSZFiw4RMgse02TwIazucZ2U2nRYPoR_Z_oo8WMV7g1A6RISxZ8-YN3V_j27mwTyrbmO9QsI6e9zKCSfD_ftvP0j5DEvvtVo3beeCCLCvom2Rw1qbwZtxE6g1x4fOyPnd_gn6We-hqOJuTv8TAAD__5yjFFA">