+ case Instruction::Mul: {
+ ExprType Left (ClassifyExpression(I->getOperand(0)));
+ ExprType Right(ClassifyExpression(I->getOperand(1)));
+ if (Left.ExprTy > Right.ExprTy)
+ swap(Left, Right); // Make left be simpler than right
+
+ if (Left.ExprTy != ExprType::Constant) // RHS must be > constant
+ return I; // Quadratic eqn! :(
+
+ const ConstPoolInt *Offs = Left.Offset;
+ if (Offs == 0) return ExprType();
+ return ExprType(DefOne(Right.Scale, CP, Ty) * Offs,
+ Right.Var,
+ DefZero(Right.Offset, CP, Ty) * Offs);
+ } // end case Instruction::Mul
+
+ case Instruction::Cast: {
+ ExprType Src(ClassifyExpression(I->getOperand(0)));
+ if (Src.ExprTy != ExprType::Constant)
+ return I;
+ const ConstPoolInt *Offs = Src.Offset;
+ if (Offs == 0) return ExprType();
+
+ if (I->getType()->isPointerType())
+ return Offs; // Pointer types do not lose precision
+
+ assert(I->getType()->isIntegral() && "Can only handle integral types!");
+
+ const ConstPoolVal *CPV = ConstRules::get(*Offs)->castTo(Offs, I->getType());
+ if (!CPV) return I;
+ assert(CPV->getType()->isIntegral() && "Must have an integral type!");
+ return (ConstPoolInt*)CPV;
+ } // end case Instruction::Cast
+ // TODO: Handle SUB (at least!)