<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Legalisation of smulo can end up oscillating between two legalisations infinitely"
   href="https://bugs.llvm.org/show_bug.cgi?id=39277">39277</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Legalisation of smulo can end up oscillating between two legalisations infinitely
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Backend: ARM
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>simonas+llvm.org@kazlauskas.me
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=21004" name="attach_21004" title="Reproduction file">attachment 21004</a> <a href="attachment.cgi?id=21004&action=edit" title="Reproduction file">[details]</a></span>
Reproduction file

On the ARM backend, when the attached file is compiled with following command
(the file necessary to reproduce is attached):

    llc lib.ll -O0

It is possible for the SelectionDAG Combiner to keep oscillating between two
instructions infinitely. 

This is still reproducible at revision D53067.

---

Following is an explanation of what happens:

Everything begins with SelectionDAG attempting to leaglise `smulo`:

    Legalizing: t11: i32,i32 = smulo t2, Constant:i32<0>
    <...>
    Succesfully expanded node
     ... replacing: t11: i32,i32 = smulo t2, Constant:i32<0>
         with:      t12: i32 = mul t2, Constant:i32<0>
          and:      t17: i32 = setcc t13, t15, setne:ch

    Legalizing: t17: i32 = setcc t13, t15, setne:ch
    <...>
    Succesfully expanded node
     ... replacing: t17: i32 = setcc t13, t15, setne:ch
         with:      t19: i32 = select_cc t13, t15, Constant:i32<1>,
Constant:i32<0>, setne:ch

    Legalizing: t19: i32 = select_cc t13, t15, Constant:i32<1>,
Constant:i32<0>, setne:ch
    <...>
    Successfully custom legalized node
     ... replacing: t19: i32 = select_cc t13, t15, Constant:i32<1>,
Constant:i32<0>, setne:ch
         with:      t22: i32 = ARMISD::CMOV Constant:i32<0>, Constant:i32<1>,
Constant:i32<1>, Register:i32 $cpsr, t21

Ending up with the following DAG:

      t0: ch = EntryToken
      t2: i32,ch = CopyFromReg t0, Register:i32 %7
      t12: i32 = mul t2, Constant:i32<0>
        t7: ch = CopyToReg t0, Register:i32 %17, t12
              t13: i32 = mulhs t2, Constant:i32<0>
              t15: i32 = sra t12, Constant:i32<31>
            t21: glue = ARMISD::CMPZ t13, t15
          t22: i32 = ARMISD::CMOV Constant:i32<0>, Constant:i32<1>,
Constant:i32<1>, Register:i32 $cpsr, t21
        t9: ch = CopyToReg t0, Register:i32 %18, t22
      t10: ch = TokenFactor t7, t9

So far, so good. Then, LLVM "combines the CMOV into something else:

    Combining: t22: i32 = ARMISD::CMOV Constant:i32<0>, Constant:i32<1>,
Constant:i32<1>, Register:i32 $cpsr, t21
    Creating new node: t23: i32 = sub t13, t15
    Creating new node: t24: i32 = ARMISD::CMOV t23, Constant:i32<1>,
Constant:i32<1>, Register:i32 $cpsr, t21
    Creating new node: t26: i32 = AssertZext t24, ValueType:ch:i1
     ... into: t26: i32 = AssertZext t24, ValueType:ch:i1

Ending up with (I believe, constructed by hand)

      t0: ch = EntryToken
      t2: i32,ch = CopyFromReg t0, Register:i32 %7
      t12: i32 = mul t2, Constant:i32<0>
        t7: ch = CopyToReg t0, Register:i32 %17, t12
              t13: i32 = mulhs t2, Constant:i32<0>
              t15: i32 = sra t12, Constant:i32<31>
            t21: glue = ARMISD::CMPZ t13, t15
            t23: i32 = sub t13, t15
           t24: i32 = ARMISD::CMOV t23, Constant:i32<1>, Constant:i32<1>,
Register:i32 $cpsr, t21
          t26: i32 = AssertZext t24, ValueType:ch:i1
        t9: ch = CopyToReg t0, Register:i32 %18, t26
      t10: ch = TokenFactor t7, t9

Then:

    Combining: t15: i32 = sra t12, Constant:i32<31>
     ... into: t12: i32 = mul t2, Constant:i32<0>
    Combining: t13: i32 = mulhs t2, Constant:i32<0>
     ... into: t3: i32 = Constant<0>
    Combining: t23: i32 = sub Constant:i32<0>, t12
     ... into: t12: i32 = mul t2, Constant:i32<0>
    Combining: t24: i32 = ARMISD::CMOV t12, Constant:i32<1>, Constant:i32<1>,
Register:i32 $cpsr, t21
    Creating new node: t27: i32 = ARMISD::CMOV Constant:i32<0>,
Constant:i32<1>, Constant:i32<1>, Register:i32 $cpsr, t21
    Creating new node: t28: i32 = AssertZext t27, ValueType:ch:i1
     ... into: t28: i32 = AssertZext t27, ValueType:ch:i1

Going the full circle back to the original DAG, which it inspects again and...

    Combining: t27: i32 = ARMISD::CMOV Constant:i32<0>, Constant:i32<1>,
Constant:i32<1>, Register:i32 $cpsr, t21
    Creating new node: t29: i32 = sub Constant:i32<0>, t12
    Creating new node: t30: i32 = ARMISD::CMOV t29, Constant:i32<1>,
Constant:i32<1>, Register:i32 $cpsr, t21
    Creating new node: t31: i32 = AssertZext t30, ValueType:ch:i1
     ... into: t31: i32 = AssertZext t30, ValueType:ch:i1

ad nauseam.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>