<div dir="ltr">I think this is because branch instructions typically depend on a flag in a condition code or flag register. While an instruction like xor writes its output to a normal register. So the setcc reflects an operation that updates flags.</div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature" data-smartmail="gmail_signature">~Craig</div></div>
<br><div class="gmail_quote">On Fri, Jul 21, 2017 at 12:40 PM, Dilan Manatunga via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Why would converting a setcc to xor or vice versa change the sub-trees at all. The inputs to both instructions remain the same. I looked through the codes where both legalization occurs, and it doesn't seem like any sub-tree modifications should be happening.<div><br></div><div>I guess the thing is I want to understand why this happens. Is there a reason we want all branch inputs to be setcc operations, instead of a simple xor?<br><div><br></div><div><div>-Dilan</div><div><br></div><div>P.S. Still don't get your messages in my inbox.</div><div><div><br></div><div class="gmail_quote"><div dir="ltr">On Fri, Jul 21, 2017 at 11:13 AM Dilan Manatunga <<a href="mailto:manatunga@gmail.com" target="_blank">manatunga@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">But isn't kinda silly that we transform to xor and then we transform it back. What is the advantage in doing so? Also, since we do that method, I now have to introduce setcc patterns for i1 values, instead of being able to just use logical pattern operators like not.</div><div dir="ltr"><div><br></div><div>-Dilan</div></div><br><div class="gmail_quote"><div dir="ltr">On Fri, Jul 21, 2017 at 11:00 AM Dilan Manatunga <<a href="mailto:manatunga@gmail.com" target="_blank">manatunga@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">For some reason I didn't get <span style="color:rgb(33,33,33)">Krzysztof Parzyszek e-mail in my inbox, but thanks for the fact I can override the getSetCCResultType. Didn't even think of that.</span></div><div dir="ltr"><div><span style="color:rgb(33,33,33)"><br></span></div><div><span style="color:rgb(33,33,33)">-Dilan</span></div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Jul 19, 2017 at 7:28 PM Dilan Manatunga <<a href="mailto:manatunga@gmail.com" target="_blank">manatunga@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi,<div><br></div><div>I am having some issues with how some of the instructions are being legalized.</div><div>So this is my intial basic block. The area of concern is the last three instructions. I will pick and choose debug output to keep this small.</div><div><pre style="word-wrap:break-word;white-space:pre-wrap">SelectionDAG has 36 nodes:
  t0: ch = EntryToken
          t6: i32,ch = CopyFromReg t0, Register:i32 %vreg507
              t2: i32,ch = CopyFromReg t0, Register:i32 %vreg17
            t4: i32 = or t2, Constant:i32<256>
          t9: i32 = shl t4, Constant:i32<2>
        t10: i32 = add t6, t9
        t12: i32,ch = CopyFromReg t0, Register:i32 %vreg79
        t15: i32,ch = CopyFromReg t0, Register:i32 %vreg1
      t16: ch = llvm.tpu.dma.write.1KB.async t0, TargetConstant:i32<4602>, t10, t12, t15
              t18: i32,ch = CopyFromReg t0, Register:i32 %vreg166
            t20: i32 = AssertZext t18, ValueType:ch:i1
          t23: i1 = setcc t20, Constant:i32<0>, seteq:ch
            t25: i32,ch = CopyFromReg t0, Register:i32 %vreg396
          t28: i1 = setcc t25, Constant:i32<255>, setugt:ch
        t29: i1 = and t23, t28
      t37: i1 = setcc t29, Constant:i1<-1>, setne:ch
    t33: ch = brcond t16, t37, BasicBlock:ch<if.end65.1 0x7097330>
  t35: ch = br t33, BasicBlock:ch<if.then64.1 0x7097280>

<span style="font-family:sans-serif;white-space:normal"> Here we see that the settcc has been legalized to xor, which I am fine with..</span>
Legalizing: t37: i1 = setcc t29, Constant:i1<-1>, setne:ch

Combining: t37: i1 = setcc t29, Constant:i1<-1>, setne:ch
 ... into: t38: i1 = xor t29, Constant:i1<-1>
<br></pre><pre style="word-wrap:break-word;white-space:pre-wrap"><pre style="word-wrap:break-word;white-space:pre-wrap"><span style="font-family:sans-serif;white-space:normal">However, the issue I have is that we than try to legalize and combin the brcond again.</span></pre>Legalizing: t33: ch = brcond t16, t38, BasicBlock:ch<if.end65.1 0x7097330>

Combining: t33: ch = brcond t16, t38, BasicBlock:ch<if.end65.1 0x7097330>
<br></pre><pre style="word-wrap:break-word"><pre style="white-space:pre-wrap;word-wrap:break-word"><span style="font-family:sans-serif;white-space:normal">What the debug output doesn't show you is that when try to combine the brcond again, we end up modifying the xor we created to setcc again.</span></pre><pre style="word-wrap:break-word"><pre style="white-space:pre-wrap;word-wrap:break-word">      t40: i32 = setcc t29, Constant:i1<-1>, setne:ch</pre><pre style="white-space:pre-wrap;word-wrap:break-word"><span style="font-family:sans-serif;white-space:normal">But the issue is now the setcc returns a 32-bit type. </span></pre><pre style="white-space:pre-wrap;word-wrap:break-word"><span style="font-family:sans-serif;white-space:normal">I did some tracing and from what I can tell the visitBRCOND function in DAGCombiner is responsible for this change. It sees that the brcond has only one use that is an xor. Later on, it also sees that the two operands to the xor are neither setcc, so it converts the xor to setcc again. I would be fine with this, but when it tries to find the output type of the setcc, it chooses i32 instead of i1. Again, it seems this happens from the line of code that is:</span></pre><pre style="word-wrap:break-word"><pre style="white-space:pre-wrap;word-wrap:break-word"> SetCCVT = getSetCCResultType(SetCCVT)</pre><pre style="white-space:pre-wrap;word-wrap:break-word"><span style="font-family:sans-serif;white-space:normal">All that function does though is return the data type for pointers. </span></pre><pre style="white-space:pre-wrap;word-wrap:break-word"><span style="font-family:sans-serif;white-space:normal">Well, to my questions I guess. Why is this happening? Isn't it kinda silly to convert a setcc to an xor, and then convert it back to a slightly different output setcc. And how can I prevent this, or fix it, since my conditional branches only support having single bit inputs.</span></pre><pre style="white-space:pre-wrap;word-wrap:break-word"><span style="font-family:sans-serif;white-space:normal">Thanks,</span></pre><pre style="white-space:pre-wrap;word-wrap:break-word"><span style="font-family:sans-serif;white-space:normal">-Dilan</span></pre><pre style="word-wrap:break-word"><font face="sans-serif"><span style="white-space:normal">PS Here is optimized DAG in case you were wondering.</span></font></pre></pre></pre><span style="white-space:pre-wrap">Combining: t0: ch = EntryToken
Optimized legalized selection DAG: BB#212 'merge_sort:for.cond.<wbr>cleanup39.1'
SelectionDAG has 36 nodes:
  t0: ch = EntryToken
          t6: i32,ch = CopyFromReg t0, Register:i32 %vreg507
              t2: i32,ch = CopyFromReg t0, Register:i32 %vreg17
            t4: i32 = or t2, Constant:i32<256>
          t9: i32 = shl t4, Constant:i32<2>
        t10: i32 = add t6, t9
        t12: i32,ch = CopyFromReg t0, Register:i32 %vreg79
        t15: i32,ch = CopyFromReg t0, Register:i32 %vreg1
      t16: ch = llvm.tpu.dma.write.1KB.async t0, TargetConstant:i32<4602>, t10, t12, t15
              t18: i32,ch = CopyFromReg t0, Register:i32 %vreg166
            t20: i32 = AssertZext t18, ValueType:ch:i1
          t23: i1 = setcc t20, Constant:i32<0>, seteq:ch
            t25: i32,ch = CopyFromReg t0, Register:i32 %vreg396
          t28: i1 = setcc t25, Constant:i32<255>, setugt:ch
        t29: i1 = and t23, t28
      t40: i32 = setcc t29, Constant:i1<-1>, setne:ch
    t33: ch = brcond t16, t40, BasicBlock:ch<if.end65.1 0x7097330>
  t35: ch = br t33, BasicBlock:ch<if.then64.1 0x7097280>
</span></pre></div></div></blockquote></div></blockquote></div></blockquote></div></div></div></div></div>
<br>______________________________<wbr>_________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
<br></blockquote></div><br></div>