<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 - IsPowerOfTwo not treating INT_MIN as a negative number"
   href="https://bugs.llvm.org/show_bug.cgi?id=37569">37569</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>IsPowerOfTwo not treating INT_MIN as a negative number
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </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>normal
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>new bugs
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>pankajgode@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Overview:
Transformation of sdiv to 'shift, add, shift', gives incorrect result for
division by 0x80000000 i.e. INT_MIN (-2147483648).

Specifically for the test code below:

#include <stdio.h>
#include <stdlib.h>
volatile int myInt;
int number[6];

int gen_int (int i) {
  return i + myInt;
}
void init() {
  number[gen_int(4)] = gen_int (0x80000000);
}

int main() {
  register int *p;
  p = number;
  init();

  *(p + 5) = *(p + 4) / (int) 0x80000000;

  if ( *(p+5)==1)
    printf(" \n Answer=%d  Expected.\n", *(p+5));
  else
    printf(" \n Answer=%d . Not Expected! \n", *(p+5));
   return 0;
}

Steps to Reproduce:
Compilation command: clang -O0 t_unit1.c -mllvm -fast-isel=false
 (Disabling -fast-isel to enable converting it to shift and add)
LLVM was compiled for X86 target.
Test was executed on X86_64 Linux machine.

Actual Result: Answer=-1 . Not Expected! 
  i.e. Division operation shows -1 as answer, which is incorrect.

Expected Result: Answer=1  Expected.
  i.e. As it is division by same number so answer should be 1.

Observations:
The division below is essentially 0x80000000/0x80000000
 *(p + 24) = *(p + 4) / (int) 0x80000000;

which gets converted to:
        sarl    $31, %edx
        shrl    %edx
        addl    %edx, %ecx
        sarl    $31, %ecx

The last 'sarl' was introduced with the below commit.

<a href="https://github.com/llvm-mirror/llvm/commit/7ac44f2885a25fad268acae3d3503eb0114d4c83#diff-d818c34776d200e6983e01b0819bb974">https://github.com/llvm-mirror/llvm/commit/7ac44f2885a25fad268acae3d3503eb0114d4c83#diff-d818c34776d200e6983e01b0819bb974</a>
This appears to be relevant code in lib/CodeGen/SelectionDAG/DAGCombiner.cpp:
    SDValue Srl = DAG.getNode(ISD::SRL, DL, VT, Sign, Inexact);
    SDValue Add = DAG.getNode(ISD::ADD, DL, VT, N0, Srl);
    AddToWorklist(Srl.getNode());
    AddToWorklist(Add.getNode()); // Divide by pow2
    SDValue Sra = DAG.getNode(ISD::SRA, DL, VT, Add, C1);

    // If dividing by a positive value, we're done. Otherwise, the result must
    // be negated.
    if (KnownNegatives.none())
      return Sra;</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>