summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/Float2Int.cpp
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2016-12-01 20:08:47 +0000
committerPhilip Reames <listmail@philipreames.com>2016-12-01 20:08:47 +0000
commit4d00af1bde7a9db210fe80bb7207832112ef9394 (patch)
tree90852477eaa4e8038de7aea741ae1ac4b205b316 /llvm/lib/Transforms/Scalar/Float2Int.cpp
parent2c01af590457dad514c8998f8c950c15319e2077 (diff)
downloadbcm5719-llvm-4d00af1bde7a9db210fe80bb7207832112ef9394.tar.gz
bcm5719-llvm-4d00af1bde7a9db210fe80bb7207832112ef9394.zip
Factor out common parts of LVI and Float2Int into ConstantRange [NFCI]
This just extracts out the transfer rules for constant ranges into a single shared point. As it happens, neither bit of code actually overlaps in terms of the handled operators, but with this change that could easily be tweaked in the future. I also want to have this separated out to make experimenting with a eager value info implementation and possibly a ValueTracking-like fixed depth recursion peephole version. There's no reason all four of these can't share a common implementation which reduces the chances of bugs. Differential Revision: https://reviews.llvm.org/D27294 llvm-svn: 288413
Diffstat (limited to 'llvm/lib/Transforms/Scalar/Float2Int.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/Float2Int.cpp45
1 files changed, 15 insertions, 30 deletions
diff --git a/llvm/lib/Transforms/Scalar/Float2Int.cpp b/llvm/lib/Transforms/Scalar/Float2Int.cpp
index 7aa6dc6992b..545036d724e 100644
--- a/llvm/lib/Transforms/Scalar/Float2Int.cpp
+++ b/llvm/lib/Transforms/Scalar/Float2Int.cpp
@@ -190,21 +190,14 @@ void Float2IntPass::walkBackwards(const SmallPtrSetImpl<Instruction*> &Roots) {
seen(I, badRange());
break;
- case Instruction::UIToFP: {
- // Path terminated cleanly.
- unsigned BW = I->getOperand(0)->getType()->getPrimitiveSizeInBits();
- APInt Min = APInt::getMinValue(BW).zextOrSelf(MaxIntegerBW+1);
- APInt Max = APInt::getMaxValue(BW).zextOrSelf(MaxIntegerBW+1);
- seen(I, validateRange(ConstantRange(Min, Max)));
- continue;
- }
-
+ case Instruction::UIToFP:
case Instruction::SIToFP: {
- // Path terminated cleanly.
+ // Path terminated cleanly - use the type of the integer input to seed
+ // the analysis.
unsigned BW = I->getOperand(0)->getType()->getPrimitiveSizeInBits();
- APInt SMin = APInt::getSignedMinValue(BW).sextOrSelf(MaxIntegerBW+1);
- APInt SMax = APInt::getSignedMaxValue(BW).sextOrSelf(MaxIntegerBW+1);
- seen(I, validateRange(ConstantRange(SMin, SMax)));
+ auto Input = ConstantRange(BW, true);
+ auto CastOp = (Instruction::CastOps)I->getOpcode();
+ seen(I, validateRange(Input.castOp(CastOp, MaxIntegerBW+1)));
continue;
}
@@ -249,23 +242,12 @@ void Float2IntPass::walkForwards() {
llvm_unreachable("Should have been handled in walkForwards!");
case Instruction::FAdd:
- Op = [](ArrayRef<ConstantRange> Ops) {
- assert(Ops.size() == 2 && "FAdd is a binary operator!");
- return Ops[0].add(Ops[1]);
- };
- break;
-
case Instruction::FSub:
- Op = [](ArrayRef<ConstantRange> Ops) {
- assert(Ops.size() == 2 && "FSub is a binary operator!");
- return Ops[0].sub(Ops[1]);
- };
- break;
-
case Instruction::FMul:
- Op = [](ArrayRef<ConstantRange> Ops) {
- assert(Ops.size() == 2 && "FMul is a binary operator!");
- return Ops[0].multiply(Ops[1]);
+ Op = [I](ArrayRef<ConstantRange> Ops) {
+ assert(Ops.size() == 2 && "its a binary operator!");
+ auto BinOp = (Instruction::BinaryOps) I->getOpcode();
+ return Ops[0].binaryOp(BinOp, Ops[1]);
};
break;
@@ -275,9 +257,12 @@ void Float2IntPass::walkForwards() {
//
case Instruction::FPToUI:
case Instruction::FPToSI:
- Op = [](ArrayRef<ConstantRange> Ops) {
+ Op = [I](ArrayRef<ConstantRange> Ops) {
assert(Ops.size() == 1 && "FPTo[US]I is a unary operator!");
- return Ops[0];
+ // Note: We're ignoring the casts output size here as that's what the
+ // caller expects.
+ auto CastOp = (Instruction::CastOps)I->getOpcode();
+ return Ops[0].castOp(CastOp, MaxIntegerBW+1);
};
break;
OpenPOWER on IntegriCloud