We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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));
The text was updated successfully, but these errors were encountered:
assigned to @majnemer
Sorry, something went wrong.
I checked this against a recent LLVM on x86-64 and believe it is a real bug.
We should transform X/INT_MIN to X==INT_MIN instead.
Fixed in r212164.
majnemer
No branches or pull requests
Extended Description
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));
The text was updated successfully, but these errors were encountered: