<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/61541>61541</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[VPlan] It's a strange optimization.
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
erickq
</td>
</tr>
</table>
<pre>
Recently, when analyzing a function, it is found that when LoopVectorize is enabled in the compiler, some redundant IRs are generated.
The back end is aarch64.
The original IR is as follows:
```
; ModuleID = 'test.cpp'
source_filename = "test.cpp"
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-unknown-linux-gnu"
%struct.SparseMatrix_STRUCT = type { ptr, ptr, i64, i64, i32, i32, i32, ptr, ptr, ptr, ptr, ptr, %"class.std::unordered_map", %"class.std::vector", i8, i8, i8, i8, ptr, ptr, ptr }
%"class.std::unordered_map" = type { %"class.std::_Hashtable" }
%"class.std::_Hashtable" = type { ptr, i64, %"struct.std::__detail::_Hash_node_base", i64, %"struct.std::__detail::_Prime_rehash_policy", ptr }
%"struct.std::__detail::_Hash_node_base" = type { ptr }
%"struct.std::__detail::_Prime_rehash_policy" = type { float, i64 }
%"class.std::vector" = type { %"struct.std::_Vector_base" }
%"struct.std::_Vector_base" = type { %"struct.std::_Vector_base<long long, std::allocator<long long>>::_Vector_impl" }
%"struct.std::_Vector_base<long long, std::allocator<long long>>::_Vector_impl" = type { ptr, ptr, ptr }
%struct.Vector_STRUCT = type { i32, ptr, ptr }
@.str = private unnamed_addr constant [38 x i8] c"x.localLength==A.localNumberOfColumns\00", align 1
@.str.1 = private unnamed_addr constant [9 x i8] c"test.cpp\00", align 1
@__PRETTY_FUNCTION__._Z16ComputeSYMGS_refRK19SparseMatrix_STRUCTRK13Vector_STRUCTRS2_ = private unnamed_addr constant [69 x i8] c"int ComputeSYMGS_ref(const SparseMatrix &, const Vector &, Vector &)\00", align 1
; Function Attrs: mustprogress nounwind uwtable vscale_range(1,16)
define dso_local noundef i32 @_Z16ComputeSYMGS_refRK19SparseMatrix_STRUCTRK13Vector_STRUCTRS2_(ptr nocapture noundef nonnull readonly align 8 dereferenceable(200) %0, ptr nocapture noundef nonnull readonly align 8 dereferenceable(24) %1, ptr nocapture noundef nonnull readonly align 8 dereferenceable(24) %2) local_unnamed_addr #0 {
%4 = load i32, ptr %2, align 8, !tbaa !5
%5 = getelementptr inbounds %struct.SparseMatrix_STRUCT, ptr %0, i64 0, i32 5
%6 = load i32, ptr %5, align 4, !tbaa !11
%7 = icmp eq i32 %4, %6
br i1 %7, label %9, label %8
8: ; preds = %3
tail call void @__assert_fail(ptr noundef nonnull @.str, ptr noundef nonnull @.str.1, i32 noundef 56, ptr noundef nonnull @__PRETTY_FUNCTION__._Z16ComputeSYMGS_refRK19SparseMatrix_STRUCTRK13Vector_STRUCTRS2_) #2
unreachable
9: ; preds = %3
%10 = getelementptr inbounds %struct.SparseMatrix_STRUCT, ptr %0, i64 0, i32 4
%11 = load i32, ptr %10, align 8, !tbaa !24
%12 = getelementptr inbounds %struct.SparseMatrix_STRUCT, ptr %0, i64 0, i32 11
%13 = load ptr, ptr %12, align 8, !tbaa !25
%14 = getelementptr inbounds %struct.Vector_STRUCT, ptr %1, i64 0, i32 1
%15 = load ptr, ptr %14, align 8, !tbaa !26
%16 = getelementptr inbounds %struct.Vector_STRUCT, ptr %2, i64 0, i32 1
%17 = load ptr, ptr %16, align 8, !tbaa !26
%18 = icmp sgt i32 %11, 0
br i1 %18, label %19, label %28
19: ; preds = %9
%20 = getelementptr inbounds %struct.SparseMatrix_STRUCT, ptr %0, i64 0, i32 10
%21 = load ptr, ptr %20, align 8, !tbaa !27
%22 = getelementptr inbounds %struct.SparseMatrix_STRUCT, ptr %0, i64 0, i32 9
%23 = load ptr, ptr %22, align 8, !tbaa !28
%24 = getelementptr inbounds %struct.SparseMatrix_STRUCT, ptr %0, i64 0, i32 7
%25 = load ptr, ptr %24, align 8, !tbaa !29
%26 = zext i32 %11 to i64
br label %29
27: ; preds = %47
br label %28
28: ; preds = %27, %9
ret i32 0
29: ; preds = %19, %47
%30 = phi i64 [ 0, %19 ], [ %54, %47 ]
%31 = getelementptr inbounds ptr, ptr %21, i64 %30
%32 = load ptr, ptr %31, align 8, !tbaa !30
%33 = getelementptr inbounds ptr, ptr %23, i64 %30
%34 = load ptr, ptr %33, align 8, !tbaa !30
%35 = getelementptr inbounds i8, ptr %25, i64 %30
%36 = load i8, ptr %35, align 1, !tbaa !31
%37 = getelementptr inbounds ptr, ptr %13, i64 %30
%38 = load ptr, ptr %37, align 8, !tbaa !30
%39 = load double, ptr %38, align 8, !tbaa !32
%40 = getelementptr inbounds double, ptr %15, i64 %30
%41 = load double, ptr %40, align 8, !tbaa !32
%42 = icmp eq i8 %36, 0
br i1 %42, label %47, label %43
43: ; preds = %29
%44 = zext i8 %36 to i64
br label %56
45: ; preds = %56
%46 = phi double [ %67, %56 ]
br label %47
47: ; preds = %45, %29
%48 = phi double [ %41, %29 ], [ %46, %45 ]
%49 = getelementptr inbounds double, ptr %17, i64 %30
%50 = load double, ptr %49, align 8, !tbaa !32
%51 = fmul fast double %50, %39
%52 = fadd fast double %51, %48
%53 = fdiv fast double %52, %39
store double %53, ptr %49, align 8, !tbaa !32
%54 = add nuw nsw i64 %30, 1
%55 = icmp eq i64 %54, %26
br i1 %55, label %27, label %29, !llvm.loop !34
56: ; preds = %43, %56
%57 = phi i64 [ 0, %43 ], [ %68, %56 ]
%58 = phi double [ %41, %43 ], [ %67, %56 ]
%59 = getelementptr inbounds i32, ptr %34, i64 %57
%60 = load i32, ptr %59, align 4, !tbaa !36
%61 = getelementptr inbounds double, ptr %32, i64 %57
%62 = load double, ptr %61, align 8, !tbaa !32
%63 = sext i32 %60 to i64
%64 = getelementptr inbounds double, ptr %17, i64 %63
%65 = load double, ptr %64, align 8, !tbaa !32
%66 = fmul fast double %65, %62
%67 = fsub fast double %58, %66
%68 = add nuw nsw i64 %57, 1
%69 = icmp eq i64 %68, %44
br i1 %69, label %45, label %56, !llvm.loop !37
}
; Function Attrs: noreturn nounwind
declare void @__assert_fail(ptr noundef, ptr noundef, i32 noundef, ptr noundef) local_unnamed_addr #1
attributes #0 = { mustprogress nounwind uwtable vscale_range(1,16) "approx-func-fp-math"="true" "frame-pointer"="none" "min-legal-vector-width"="0" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+neon,+sve,+v8a" "unsafe-fp-math"="true" }
attributes #1 = { noreturn nounwind "approx-func-fp-math"="true" "frame-pointer"="none" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+neon,+sve,+v8a" "unsafe-fp-math"="true" }
attributes #2 = { noreturn nounwind }
!llvm.module.flags = !{!0, !1, !2, !3}
!llvm.ident = !{!4}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{!"clang version 15.0.3 (https://github.com/flang-compiler/classic-flang-llvm-project.git b1d92376d8eab0d379537cd570d65c69eceed195)"}
!5 = !{!6, !7, i64 0}
!6 = !{!"_ZTS13Vector_STRUCT", !7, i64 0, !10, i64 8, !10, i64 16}
!7 = !{!"int", !8, i64 0}
!8 = !{!"omnipotent char", !9, i64 0}
!9 = !{!"Simple C++ TBAA"}
!10 = !{!"any pointer", !8, i64 0}
!11 = !{!12, !7, i64 36}
!12 = !{!"_ZTS19SparseMatrix_STRUCT", !10, i64 0, !10, i64 8, !13, i64 16, !13, i64 24, !7, i64 32, !7, i64 36, !7, i64 40, !10, i64 48, !10, i64 56, !10, i64 64, !10, i64 72, !10, i64 80, !14, i64 88, !20, i64 144, !23, i64 168, !23, i64 169, !23, i64 170, !23, i64 171, !10, i64 176, !10, i64 184, !10, i64 192}
!13 = !{!"long long", !8, i64 0}
!14 = !{!"_ZTSSt13unordered_mapIxiSt4hashIxESt8equal_toIxESaISt4pairIKxiEEE", !15, i64 0}
!15 = !{!"_ZTSSt10_HashtableIxSt4pairIKxiESaIS2_ENSt8__detail10_Select1stESt8equal_toIxESt4hashIxENS4_18_Mod_range_hashingENS4_20_Default_ranged_hashENS4_20_Prime_rehash_policyENS4_17_Hashtable_traitsILb0ELb0ELb1EEEE", !10, i64 0, !16, i64 8, !17, i64 16, !16, i64 24, !18, i64 32, !10, i64 48}
!16 = !{!"long", !8, i64 0}
!17 = !{!"_ZTSNSt8__detail15_Hash_node_baseE", !10, i64 0}
!18 = !{!"_ZTSNSt8__detail20_Prime_rehash_policyE", !19, i64 0, !16, i64 8}
!19 = !{!"float", !8, i64 0}
!20 = !{!"_ZTSSt6vectorIxSaIxEE", !21, i64 0}
!21 = !{!"_ZTSSt12_Vector_baseIxSaIxEE", !22, i64 0}
!22 = !{!"_ZTSNSt12_Vector_baseIxSaIxEE12_Vector_implE", !10, i64 0, !10, i64 8, !10, i64 16}
!23 = !{!"bool", !8, i64 0}
!24 = !{!12, !7, i64 32}
!25 = !{!12, !10, i64 80}
!26 = !{!6, !10, i64 8}
!27 = !{!12, !10, i64 72}
!28 = !{!12, !10, i64 64}
!29 = !{!12, !10, i64 48}
!30 = !{!10, !10, i64 0}
!31 = !{!8, !8, i64 0}
!32 = !{!33, !33, i64 0}
!33 = !{!"double", !8, i64 0}
!34 = distinct !{!34, !35}
!35 = !{!"llvm.loop.mustprogress"}
!36 = !{!7, !7, i64 0}
!37 = distinct !{!37, !35}
```
`clang++ -march=armv9-a+sve -O3 -ffast-math -mllvm --prefer-predicate-over-epilogue=predicate-else-scalar-epilogue -fvectorize test.ll -S`
After loopvectorize, the cyclic IR changes to:

test.s:

After I further positioned it, I found that this select should be redundant.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsW1tz4yq2_jXKCyWXAF0f8pDEyTmu3d27K85M1cyLCkvI5rSMtAHl0r_-FLoi65Jkdvfb7OrYW7BuLL61WCBMpGRHTum15d1a3vaKVOpUiGsqWPLjr6tDkb5dP9KEcpW_WegOvJwoB4ST_O0n40dAQFbxRLGC606mAJMgKyqeAnUiqqH-UhTlP2miCsF-Uk1AOTnkNAWMA3WiICnOJcup0BJkcaZA0LTiKeEK7B4lIIKCI-VUEEXTjeVsLefm6UTBgSQ_AOWplkiISE6-a_QWgh0ZJznYPdYE2qw8L16khW8aKst32n_NI74FX4u0yuluCyy8BRYKFJVqk5SlhYKGSBaVSGicsZxycqYtHRroUEOniDhSBVKiSE7eikp1lNQ-W_iG2iy08I3-w8hm0LfwTf2hn3zXwje-azOINAFEoc0xatr2uu1CiRKszHtTWk_YFf_Bixdu54xXr_aRVz1b-4k8qUSVqM2-JELSr0QJ9hrvnx7_cfdUC1NvJQVWcAtKVU9N-6XtM74wmn6NGWa_LORZCCU5kXIjVaonBd9UvBApFTSNz6T25RLhc42mloKF858TvcAKtv3g39c-dsIsS_y_RJ6UBnNNvyr-gnbGwa1LG-52cgb2OKWKsNwQFvMipfGBSNp54hMCvgt2prGgJy2oLHKWvLVSZjz1WWMmw_ukwHnjxlKzvCCqHfU7ru_hMjelE1OaVDUM5R3LL8k_qQHf5QU_Av1R57-OiOR5kRBttkmB7-t_phR2LvPP2vnrlC7nictZbw1qBczlmUn2MPibT9fZSN2Mt6AU7JkoCiquE3EakzQVICm4VHrdsLxbHIJXnQm8LUgshF43emj5F8qP6mThrYW3N03Tt-p8oOLP7K7IqzOXlnfnOG0okJwdOYAj7Rv4Mf3RSH2_QqxIj-Pvj_dPT_-KH_7x7e5p9-e3ON7E_4b-XXEuK0X3__r6P_tY0OzxDxjNJO3HPyAeefdxj-KP2eqPjWVcgUulFgprDmBqBhby9UiankZ512Y-RcvD7tfeh7aOADdKCb1Kg3MlVSmKo6BSAl5U_IXxFFQvdRIFzzIhOY0F4UdqoRBa6A7WqmqJKc0YpyCVRVxPcs2f0kyDDGhf_02_WijUAOVFQkpVCdrL5wXnVZ4DQUla8PytHW4I9NKSUUF5QptFIETaJZFOEk4H-L8nz23FwV8rDunv2ovxCEEWwo4O3MbjQJO6Nd7ygqRGNLcyupkPmzUKqgMh-tsz-L2a_0gVzemZcqW5GT9o4yVYLVkMXU63KjhtTQJMFf6Sid5gonthIoSGgKAWwJJzCehfDZ6Q1y28fkd4EIDBmlz35ORAc_0UjZ5CMwh0sQd0JJSC6tHW9ZyHO4F6eQQJyXPwXLC0xnBMpKRCxZleOTtAjue5TVoDIGa7N7DzVEfg-SssvyNRNVjDqBtuxQUlyanGouGkaN1JGvzO78GQa-qASyCCzjLQUSdC06HfY-UIqRAPZpqrqla_YqYZLdD9mJ2j-TQVTS00pXuLBrorBvqmCP_vGYjWDQwWDfQ_amA45At5VF3CgLVnnEm6gOEoQ8BxwkCjjAHraPjcf5PYiQxb0W-KHeiYSuCST9Fa8ASmiN8UPdEQoGgxdtBa7ISmlR-Mnc9aOfLEYgShtQgaTXoTQT_pqwFOoIp6OznAc8BgZGIQBb8Ag24wq2gEdjS_PqKgXXn7IQnajMMZcc8vHE14jSzQy0kTBuWJNZtL77Zxfs0ALG9bP3j1_q5f-d2g7jGkwLXpv5isPk_W6k0paGmCMVye4LEI_AlD8KIh7qIh-KOGrJZ3_alNg-tFO8wCzmTBnrm7uDDDTOo4-Lg_4LI_wkV_BB_1RzSISIuqLrsHKeGKFGTW3KtJeyIXLnrWhSvmuCu5eWwOGtfHYTNp86udi0bLmzsull1shrCL5xOAmctc18hlreaVVNaV660Cb1aBZ67mrt-nhsZFXR7wuzykNxhDHjC1dTmm1fZLEqfXah17IVww0oU9-UUac_0ujXkXacyNPgevYAlenrMGr-iD8PIakGbnKgcZkaofoVbQjgGbzvAaPGYkTScMnTtcc9n2mnSZpex5woAmGqQqBDVJ8H80qga32kZevQAuXwwXortRTdpukvsAa-j6dQhNt6DN1nZYV8dRhto1EOb583mTF0VZm-eaYPX82dBwcQ9608Bgcfl08QXu_HA2bHTDuyCeCpuPQd2wCuLxFg67BoI9sy7wncWzg2j58ACbvvFXi4LpIoAWbUEr0eSvlQYm7vwG69Ko_XznImHqttVKdj0H-Obm3PfWrF6pWMdW-4s5wO8Soj9iaBCZyeowCekOgP5omsKleGzOc8x49KO5eOyB7bqTePTHmzp3HJ6ePxuP3eJxcSQ-e3LKC0FVJXh_atodiiY5EfQjB0jW-PTHGh8PTXqXzgdHp7xEKcEOlaKyPTrUSSS4_Q_PeeuXnWUpilc7q3hiZ6V9JupkIWThrYWQElXzQgahTJAztcuCcUVFT8AL3hGcGbdzeiS53bwqsl9YaohyWjJe2Ixnck0VL2xO-Hsk9Rv31P5JRfEeqRKkLBk_LtJIRZIfdikK1Zh-qLKMCluyn7QnD1va5o2xnZRV31W_WWfJmCCjRFWCyp7KQrec1u_4LXQrn2nzP88hafkqLklGl4fSgXYMAdhDYALYXzm7_522XzttaG3aLtJTm8XO9cWKTZaTY1c8QCu4tRBsKwPY7djaCgti491hI4OllKsxsztV5xgUzWleI89C6CU5ERF3Hu6PdQ098II5GJi_7-7AF_pMc4MXmbxojfd-nRcv87ZpcInTHTukeffNj-CZCqmXBOhtnA0GFgpPSpX15Rf0YKGHI1On6rBJirOFHjLNYg_XcB7q9-cssZsO7X2N1P-jidocmQIHmEYIB34aUnJwUhxEHg6S1Auc1PcSP6IJpSmMPEuXliNzvbG53UoXDGdcBrE_GVv876f9xbuD_pqIKaSFVH90Fk5aoG9qCiaaGFeD5HDWvHDCVJw5KwulYaqhNgiIZgVEEwF7di5zCnSQWugWPN3e3Fw4cITvhonwN2BkvzWTRwDXzxPf4ZFfRqA2pmDurc6gGzofmAlszMRlE3InZs0ZetHiTrW504nvq6uhqbs1YzQF07GEvfh-fxB24tGAK7cThowRhjNt0bQtcGba4BS7wXQMMJwOAkZj6ODJZBq3QN4BzjTPaCDsFcSja1O7V7ZX7onI0-71fq9C-ldF8lgV-ons9sotCRO7P17Z_f29ARhvXqm3pNQZLlPtXk2pWgmK77_tVdhdKYJOvKc5TRSU6tKk3tRvezeGYfy1SJtCM9btjB_rDuTEW5qRKldNZ1r3dl0zd5UaccFgZKwEYUruvhyc--YP3o89MA0ZfxIywTRk_EnIDBOIp8LdcOTfaYL9EBam2VJPy8jn3sWdsIWhmlKn6fRS6oKzDdHRmhdNZdPU214nWx86mmbfBpF-s2_Yve7J7tWcWATnBcElaCPzotaMPDQvbz5Rf1sSOLTqFWcdiB9eRdE0wRyKIn_Xqe67i9K40PIW6Ee52mTw56sOc2QmefCu_GBsUPgugz8qM1H0LsM4UvEF7uB0ckYjxhfwClcnAF-AB-OuBsfz9NN57s5y1me6fYWUMqkYT5Shscte2BvRTxeA_kxkY54aXBRJ-GLCg9Uys30dNGNVMGPVxaXxrrGuutuyzT4TkZwsvCXi_BzZpNl7AftPDOwsI1LVuy0A7LMeDbDtsr56pb9SlhBF7eKZCpuWLC-OFbXwduihuaS2TEhOBgIA7Oy5v19f3zTMc2DveytvMkUF0F7ryfTI6rv3b0nOErB71BUrP1IJVDHckEfQ8m7ZmRxpfdB6sYeoJBV23Ss3zX5CtyQF1xVwu7WACDqhp4uYB4R8jGHkhjZxI-pGOLH9gCLbDVBohxnMbOQRPw1JRhzX3ZTan-0xez0m-Vvtcl3fJiQkOIKhHUQRtV1EDjYJ6MF23YQQTEKUOdHILtO9O5BVQp2oAGUhmWIFpylg9Q3lnfmTCHViEsi6IgHyVFR5Cg7GTx42I2AtfF6l1ziNcESu6DX0gwhDjIPg6nTtpynxPJog308dJ4tQBjHBTogPxI9Ckl6xa-Qg7GDkQOj5MNhE1CcJciiGTuARJ7Fch54Jyzd1pBXieMWkrOi1Dz0XXtWHlLL-qQhCnL6AulOHn7e9Etf1TvFQHaXlOjmTSg5SFFN5_RuTf37PCbe8LdgpCwUSECBVXVaBolTszH4S7bvNVSXy65U9qxbcfnV7Uws91OZICz3U5v5_AAAA__-fOMs0">