<div dir="ltr"><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">Hello,</span></p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US"><br></span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">I was testing the vector divide on a RISCV
target simulator and found out there is a problem if the element type of vector
is unsigned char. Strangely, it works out fine if the type is signed char.</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US"> </span></p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">Below is the reduced code of the problem: </span></p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US"> <br></span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">-------------------------------------------------------------------------------------------------------------</span><span style="font-size:12pt"> </span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">typedef unsigned char uint8x2_t
__attribute__((vector_size(2)));</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">uint8x2_t div(uint8x2_t a, uint8x2_t b) {</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">
return a / b;</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">}</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">int main() {</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">
uint8x2_t a = {2, 2};</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">
uint8x2_t b = {0, 1};</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">
uint8x2_t c = div(a, b);</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US"> if
(c[1] != 2)</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">
return 1;</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">
return 0;</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">}</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">------------------------------------------------------------------------------------------------------------</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US"> </span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">I checked the assembly code and found the
difference between the two types is the absence of an AND instruction in
unsigned char.</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US"> </span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">The purpose of AND instruction is rebuilding the
vector after two elements being divided separately. The rebuilding process is shifting one
element 8 bits to the left, then uses AND instruction to mask out unnecessary data
beyond 8<sup>th</sup> digit of the other element. At last, there is an OR
instruction to combine two elements into one vector.</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US"> </span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">It seems that DAGCombiner in LLVM considers
the result produced by unsigned divide will always be zero beyond the 8<sup>th</sup>
digit and deems the AND instruction is unnecessary. As a result, it was
removed.</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US"> </span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">It is a valid move under most circumstances
but there is a division by zero case in my code. The simulator returns
0xfffffff when it occurs. If the element type is char, there will be an AND
instruction to truncate data into 8 bits (0xff), so it can get the correct
result while using OR to build the vector. However if the element type is
unsigned char, the AND will be removed. The other element in the vector will be
affected by 0xffffffff while using OR. Hence causes the problem.</span></p><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US"><br></span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">Is there any way to prevent DAGCombiner
from removing AND in this case?</span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US"> </span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span lang="EN-US">Thanks!</span></p></div>