[LLVMdev] Probable error in InstCombine

David Menendez davemm at cs.rutgers.edu
Tue Jul 1 14:01:17 PDT 2014


I've found what appears to be a bug in instcombine. Specifically, the transformation of -(X/C) to X/(-C) is invalid if C == INT_MIN.

Specifically, if I have

> define i32 @foo(i32 %x) #0 {
> entry:
>  %div = sdiv i32 %x, -2147483648
>  %sub = sub nsw i32 0, %div
>  ret i32 %sub
> }

then opt -instcombine will produce

> define i32 @foo(i32 %x) #0 {
> entry:
>  %sub = sdiv i32 %x, -2147483648
>  ret i32 %sub
> }


You can observe this with the following test case:

> #include <stdio.h>
> #include <limits.h>
> 
> int foo(int x)
> {
>  return -(x/INT_MIN);
> }
> 
> int main (void)
> {
>  printf ("%d\n", foo(INT_MIN));
> }

This will print -1 or 1, depending on the optimization level.

This appears to be the relevant code:

InstCombineAddSub.cpp:1556
>     // 0 - (X sdiv C)  -> (X sdiv -C)
>     if (match(Op1, m_SDiv(m_Value(X), m_Constant(C))) &&
>         match(Op0, m_Zero()))
>       return BinaryOperator::CreateSDiv(X, ConstantExpr::getNeg(C));

- David Menendez






More information about the llvm-dev mailing list