Fix integer undefined behavior due to signed left shift overflow in LLVM.

Reviewed offline by chandlerc.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162623 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Smith
2012-08-24 23:29:28 +00:00
parent cac59d8ae8
commit 1144af3c9b
19 changed files with 59 additions and 56 deletions

View File

@ -1410,19 +1410,13 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
// Make sure that the value is representable for this type.
if (Size >= 32) return MadeChange;
int Val = (II->getValue() << (32-Size)) >> (32-Size);
if (Val == II->getValue()) return MadeChange;
// If sign-extended doesn't fit, does it fit as unsigned?
unsigned ValueMask;
unsigned UnsignedVal;
ValueMask = unsigned(~uint32_t(0UL) >> (32-Size));
UnsignedVal = unsigned(II->getValue());
if ((ValueMask & UnsignedVal) == UnsignedVal)
// Check that the value doesn't use more bits than we have. It must either
// be a sign- or zero-extended equivalent of the original.
int64_t SignBitAndAbove = II->getValue() >> (Size - 1);
if (SignBitAndAbove == -1 || SignBitAndAbove == 0 || SignBitAndAbove == 1)
return MadeChange;
TP.error("Integer value '" + itostr(II->getValue())+
TP.error("Integer value '" + itostr(II->getValue()) +
"' is out of range for type '" + getEnumName(getType(0)) + "'!");
return MadeChange;
}
@ -3400,4 +3394,3 @@ void CodeGenDAGPatterns::GenerateVariants() {
DEBUG(errs() << "\n");
}
}