<div dir="ltr">Hi,<div><br></div><div>When doing bitcast from vectors of small element size in LLVM IR, we will get wrong results.</div><div><br></div><div>For example, <font face="courier new, monospace">%a = bitcast <2 x i1><i1 0, i1 1> to i2 </font>will set %a to 0 after bitcast.</div>


<div><br></div><div>The cause of this bug is that in LLVM, the above bitcast is accomplished by store and load. It first store the vector v2i1 to memory then load from memory as an i2 type. But during the LegalizeVectorOps phase, it will store each element of the vector separately. </div>


<div>When the element size is smaller than 8 bits, as in our case i1, it will store each element in the **same** location. The code that cause this problem is at  <font face="courier new, monospace">LegalizeVectorOps.cpp::ExpandStore</font>:</div>


<div><br></div><div><div><font face="courier new, monospace">// Store Stride in bytes</font></div><div><font face="courier new, monospace">unsigned Stride = ScalarSize/8;</font></div><div><font face="courier new, monospace">// Extract each of the elements from the original vector</font></div>


<div><font face="courier new, monospace">// and save them into memory individually.</font></div><div><font face="courier new, monospace">SmallVector<SDValue, 8> Stores;</font></div><div><font face="courier new, monospace">for (unsigned Idx = 0; Idx < NumElem; Idx++) {</font></div>


<div><font face="courier new, monospace">  SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,</font></div><div><font face="courier new, monospace">   RegSclVT, Value, DAG.getConstant(Idx, TLI.getVectorIdxTy()));</font></div>


<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">  // This scalar TruncStore may be illegal, but we legalize it later.</font></div><div><font face="courier new, monospace">  SDValue Store = DAG.getTruncStore(Chain, dl, Ex, BasePTR,</font></div>


<div><font face="courier new, monospace">   ST->getPointerInfo().getWithOffset(Idx*Stride), MemSclVT,</font></div><div><font face="courier new, monospace">   isVolatile, isNonTemporal, Alignment, TBAAInfo);</font></div>


<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">  BasePTR = DAG.getNode(ISD::ADD, dl, BasePTR.getValueType(), BasePTR,</font></div><div><font face="courier new, monospace"><br>


</font></div><div><font face="courier new, monospace">         DAG.getConstant(Stride, BasePTR.getValueType()));</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">  Stores.push_back(Store);</font></div>


<div><font face="courier new, monospace">}</font></div></div><div><br></div><div>If <font face="courier new, monospace">ScalarSize</font> is less than 8, the <font face="courier new, monospace">Stride</font> is 0, </div>

<div>
<font face="courier new, monospace">ST->getPointerInfo().getWithOffset(Idx*Stride)</font> will always get the same offset.</div><div><br></div><div><br></div><div>The patch first convert vector of small element size to an integer using shift and or before it is saved to the memory. Please see the attachment for detail.</div>


<div><br></div><div>Thanks for your reviews.<br></div><div><div><br></div><div>Best Regards,</div><div>Qiping<br></div><div><br></div>-- <br><div dir="ltr">Qiping Li, Programmer<div>Email: <a href="mailto:liqiping1991@gmail.com" target="_blank">liqiping1991@gmail.com</a></div>


<div>Mobile: 15700080842</div></div>
</div></div>