aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/Expressions.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-03-14 22:35:50 +0000
committerChris Lattner <sabre@nondot.org>2002-03-14 22:35:50 +0000
commit9b534266f030f22a0a5fc00ad5cc19a53aa31c88 (patch)
treec7c989e48fe235fd58c3f6702e9fcc8a4d7186eb /lib/Analysis/Expressions.cpp
parent3df17fe7a8811e4cd0df1c2d4ea95c9e5396b4eb (diff)
Fix test/Regression/Other/2002-03-14-ValueToLarge.ll. Note that this
fix could be better, but we don't have the infrastructure to find out what size types are yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1876 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/Expressions.cpp')
-rw-r--r--lib/Analysis/Expressions.cpp33
1 files changed, 30 insertions, 3 deletions
diff --git a/lib/Analysis/Expressions.cpp b/lib/Analysis/Expressions.cpp
index 9ccd685797..00a8307143 100644
--- a/lib/Analysis/Expressions.cpp
+++ b/lib/Analysis/Expressions.cpp
@@ -71,10 +71,24 @@ struct DefOne : public DefVal {
};
+// getUnsignedConstant - Return a constant value of the specified type. If the
+// constant value is not valid for the specified type, return null. This cannot
+// happen for values in the range of 0 to 127.
+//
static ConstantInt *getUnsignedConstant(uint64_t V, const Type *Ty) {
if (Ty->isPointerType()) Ty = Type::ULongTy;
- return Ty->isSigned() ? (ConstantInt*)ConstantSInt::get(Ty, V)
- : (ConstantInt*)ConstantUInt::get(Ty, V);
+ if (Ty->isSigned()) {
+ // If this value is not a valid unsigned value for this type, return null!
+ if (V > 127 && ((int64_t)V < 0 ||
+ !ConstantSInt::isValueValidForType(Ty, (int64_t)V)))
+ return 0;
+ return ConstantSInt::get(Ty, V);
+ } else {
+ // If this value is not a valid unsigned value for this type, return null!
+ if (V > 255 && !ConstantUInt::isValueValidForType(Ty, V))
+ return 0;
+ return ConstantUInt::get(Ty, V);
+ }
}
// Add - Helper function to make later code simpler. Basically it just adds
@@ -270,7 +284,20 @@ ExprType analysis::ClassifyExpression(Value *Expr) {
"Shift amount must always be a unsigned byte!");
uint64_t ShiftAmount = ((ConstantUInt*)Right.Offset)->getValue();
ConstantInt *Multiplier = getUnsignedConstant(1ULL << ShiftAmount, Ty);
-
+
+ // We don't know how to classify it if they are shifting by more than what
+ // is reasonable. In most cases, the result will be zero, but there is one
+ // class of cases where it is not, so we cannot optimize without checking
+ // for it. The case is when you are shifting a signed value by 1 less than
+ // the number of bits in the value. For example:
+ // %X = shl sbyte %Y, ubyte 7
+ // will try to form an sbyte multiplier of 128, which will give a null
+ // multiplier, even though the result is not 0. Until we can check for this
+ // case, be conservative. TODO.
+ //
+ if (Multiplier == 0)
+ return Expr;
+
return ExprType(DefOne(Left.Scale, Ty) * Multiplier, Left.Var,
DefZero(Left.Offset, Ty) * Multiplier);
} // end case Instruction::Shl