[llvm-bugs] [Bug 37569] New: IsPowerOfTwo not treating INT_MIN as a negative number

via llvm-bugs llvm-bugs at lists.llvm.org
Wed May 23 10:29:02 PDT 2018


https://bugs.llvm.org/show_bug.cgi?id=37569

            Bug ID: 37569
           Summary: IsPowerOfTwo not treating INT_MIN as a negative number
           Product: new-bugs
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: pankajgode at gmail.com
                CC: llvm-bugs at lists.llvm.org

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.

https://github.com/llvm-mirror/llvm/commit/7ac44f2885a25fad268acae3d3503eb0114d4c83#diff-d818c34776d200e6983e01b0819bb974
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;

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20180523/27635987/attachment.html>


More information about the llvm-bugs mailing list