<div dir="ltr">Hi all,<div><br></div><div>Some update about the RFC. We use TypeSize for MemberOffsets now. We only permit all scalable types or all scalar types for the struct members. Use TypeSize is enough for the purpose.</div><div><br></div><div>I uploaded some patches related to the RFC.</div><div><br></div><div>The use cases for the scalable struct types in RISC-V segment load/store builtins:</div><div><a href="https://reviews.llvm.org/D99593">https://reviews.llvm.org/D99593</a></div><div><br></div><div>To use RecordType to model segment load/store types in Clang:</div><div><a href="https://reviews.llvm.org/D97264">https://reviews.llvm.org/D97264</a><br></div><div><br></div><div>We do not know the exact size of scalable struct. Do not use memcpy for struct copy in Clang:</div><div><a href="https://reviews.llvm.org/D99590">https://reviews.llvm.org/D99590</a><br></div><div><br></div><div>Do not use getelementptr for scalable struct types in Clang:</div><div><a href="https://reviews.llvm.org/D99482">https://reviews.llvm.org/D99482</a><br></div><div><br></div><div>Please help us to review these patches. Thanks a lot.</div><div><br></div><div>- Kai</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Mar 19, 2021 at 11:41 AM Kai Wang <<a href="mailto:kai.wang@sifive.com">kai.wang@sifive.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">Hi all,</p><p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue""><br></p><p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">We have a proposal to support load/store/alloca for struct containing all scalable vectors. Please help us to review it and give us your suggestions.</p><p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">Thanks a lot.</p><p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue""><br></p><p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">Introduction</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">=======</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">In RISC-V V-extension, we have a sub-extension, Zvlsseg, that could move multiple contiguous fields in memory to and from consecutively numbered vector registers. In our intrinsic document[1], we define a set of types for these segment load/store intrinsics. We have two additional parameters attached on the Zvlsseg types, the number of fields(NF) and LMUL[2]. NF could be 2 to 8 and LMUL could be 1/8, 1/4, 1/2, 1, 2, 4, 8.</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">We have tried to use primitive builtin types to model Zvlsseg types. That is, we have <vscale x 2 x i32> for LMUL = 1, int32 vector type. We use <vscale x 4 x i32> for NF = 2, LMUL = 1, int32 Zvlsseg type. However, <vscale x 4 x i32> is also a legal type for LMUL = 2, int32 vector type. They are both legal types. There is no way to distinguish them in the type legalizer.</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">To address the issue, we use the struct type to model Zvlsseg types in our downstream version. We use {<vscale x 2 x i32>, <vscale x 2 x i32>} for NF = 2, LMUL = 1, int32 Zvlsseg type. There is no ambiguous between these scalable vector types for RISC-V V-extension. However, we have to support load/store/alloca for scalable struct to model Zvlsseg types in this way.</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">[1]. <a href="https://github.com/riscv/rvv-intrinsic-doc/blob/master/intrinsic_funcs/03_vector_load_store_segment_instructions_zvlsseg.md" target="_blank">https://github.com/riscv/rvv-intrinsic-doc/blob/master/intrinsic_funcs/03_vector_load_store_segment_instructions_zvlsseg.md</a></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">[2]. The vector length multiplier, <i>LMUL</i>, when greater than 1, represents the default number of vector registers that are combined to form a vector register group.</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">Implementation</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">=======</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">In the current StructLayout implementation, it uses uint64_t to represent the size of struct and offsets of struct members. We use TypeSize for the size of struct and StackOffset for the offsets of elements. In this way, we could record the correct information in the StructLayout when it contains scalable elements. However, TypeSize is a one-dimension polynomial type. To minimize the impact to the current implementation and to fit our requirements, we only permit load/store/alloca all scalable types in a struct or all fixed length types in a struct. That is, TypeSize is either scalable size or fixed size.</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">Impact on other passes</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">=======</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">I have reviewed all uses of StructLayout. A large part of uses are related to ConstantStruct. There should be no use cases for scalable ConstantStruct. Another large part of uses are related to GetElementPtrInst. We only need to support load/store/alloca to fit our requirements. We prefer not to support getelementptr for scalable struct. We could add an assertion in the constructor of GetElementPtrInst to inhibit struct containing scalable vectors. It is a manageable work to change the internal representation of StructLayout.</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">How to avoid using getelementptr for scalable struct</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">=======</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">We could avoid using getelementptr by using insertvalue/extractvalue then load/store the whole structure. For example, instead of</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">%0 = getelementptr %struct.type, %struct.type* %val, i32 0, i32 0</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">store <vscale x 2 x i32> %v.coerce0, <vscale x 2 x i32>* %0</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">%1 = getelementptr %struct.type, %struct.type* %val, i32 0, i32 1</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">store <vscale x 2 x i32> %v.coerce1, <vscale x 2 x i32>* %1</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">We could use</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">%0 = insertvalue %struct.type undef, <vscale x 2 x i32> %v.coerce0, 0</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">%1 = insertvalue %struct.type %0, <vscale x 2 x i32> %v.coerce1, 1</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">store %struct.type %1, %struct.type* %val</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">to avoid using getelementptr for scalable struct.</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">How to deal with multiple returns with scalable vectors and fixed length objects?</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">=======</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">In D94142, it permits to put scalable vectors and fixed length objects in struct as multiple return values of intrinsic calls, but inhibits load/store/alloca for them. In this proposal, we still inhibit load/store/alloca for these struct. How do we deal with it when the return values are struct with scalable vectors and fixed length objects?</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">We extract the values into the struct with all scalable vectors and extract scalar values as needed.</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">For example,</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">%struct.type = type { <vscale x 2 x i32>, <vscale x 2 x i32> }</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">%3 = call { <vscale x 2 x i32>, <vscale x 2 x i32>, i64 } @llvm.riscv.test(i32* %0)</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">%4 = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i32>, i64 } %3, 0</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">%5 = insertvalue %struct.type undef, <vscale x 2 x i32> %4, 0</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">%6 = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i32>, i64 } %3, 1</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">%7 = insertvalue %struct.type %5, <vscale x 2 x i32> %6, 1</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">%8 = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i32>, i64 } %3, 2</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">store i64 %8, i64* %1, align 8</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">ret %struct.type %7</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";min-height:15px"><br></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">Related patches</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">=======</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">[NFC][IR] Replace isa<ScalableVectorType> with a predicator function.</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";color:rgb(220,161,13)"><a href="https://reviews.llvm.org/D98161" target="_blank">https://reviews.llvm.org/D98161</a></p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue"">[PoC][IR] Permit load/store/alloca for struct with the same scalable vectors.</p>
<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";color:rgb(220,161,13)"><a href="https://reviews.llvm.org/D98169" target="_blank">https://reviews.llvm.org/D98169</a></p><p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue";color:rgb(220,161,13)"><br></p><p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:13px;line-height:normal;font-family:"Helvetica Neue""><font color="#000000">- Kai</font></p></div>
</blockquote></div>