llvm.org GIT mirror llvm / c0d2319
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288413 91177308-0d34-0410-b5e6-96231b3b80d8 Philip Reames 3 years ago
4 changed file(s) with 114 addition(s) and 81 deletion(s). Raw diff Collapse all Expand all
232232 ///
233233 ConstantRange unionWith(const ConstantRange &CR) const;
234234
235 /// Return a new range representing the possible values resulting
236 /// from an application of the specified cast operator to this range. \p
237 /// BitWidth is the target bitwidth of the cast. For casts which don't
238 /// change bitwidth, it must be the same as the source bitwidth. For casts
239 /// which do change bitwidth, the bitwidth must be consistent with the
240 /// requested cast and source bitwidth.
241 ConstantRange castOp(Instruction::CastOps CastOp,
242 uint32_t BitWidth) const;
243
235244 /// Return a new range in the specified integer type, which must
236245 /// be strictly larger than the current type. The returned range will
237246 /// correspond to the possible range of values if the source range had been
259268 ConstantRange sextOrTrunc(uint32_t BitWidth) const;
260269
261270 /// Return a new range representing the possible values resulting
271 /// from an application of the specified binary operator to an left hand side
272 /// of this range and a right hand side of \p Other.
273 ConstantRange binaryOp(Instruction::BinaryOps BinOp,
274 const ConstantRange &Other) const;
275
276 /// Return a new range representing the possible values resulting
262277 /// from an addition of a value in this range and a value in \p Other.
263278 ConstantRange add(const ConstantRange &Other) const;
264279
11591159 // can evaluate symbolically. Enhancing that set will allows us to analyze
11601160 // more definitions.
11611161 LVILatticeVal Result;
1162 switch (BBI->getOpcode()) {
1163 case Instruction::Trunc:
1164 Result.markConstantRange(LHSRange.truncate(ResultBitWidth));
1165 break;
1166 case Instruction::SExt:
1167 Result.markConstantRange(LHSRange.signExtend(ResultBitWidth));
1168 break;
1169 case Instruction::ZExt:
1170 Result.markConstantRange(LHSRange.zeroExtend(ResultBitWidth));
1171 break;
1172 case Instruction::BitCast:
1173 Result.markConstantRange(LHSRange);
1174 break;
1175 default:
1176 // Should be dead if the code above is correct
1177 llvm_unreachable("inconsistent with above");
1178 break;
1179 }
1180
1162 auto CastOp = (Instruction::CastOps) BBI->getOpcode();
1163 Result.markConstantRange(LHSRange.castOp(CastOp, ResultBitWidth));
11811164 BBLV = Result;
11821165 return true;
11831166 }
12371220 // can evaluate symbolically. Enhancing that set will allows us to analyze
12381221 // more definitions.
12391222 LVILatticeVal Result;
1240 switch (BBI->getOpcode()) {
1241 case Instruction::Add:
1242 Result.markConstantRange(LHSRange.add(RHSRange));
1243 break;
1244 case Instruction::Sub:
1245 Result.markConstantRange(LHSRange.sub(RHSRange));
1246 break;
1247 case Instruction::Mul:
1248 Result.markConstantRange(LHSRange.multiply(RHSRange));
1249 break;
1250 case Instruction::UDiv:
1251 Result.markConstantRange(LHSRange.udiv(RHSRange));
1252 break;
1253 case Instruction::Shl:
1254 Result.markConstantRange(LHSRange.shl(RHSRange));
1255 break;
1256 case Instruction::LShr:
1257 Result.markConstantRange(LHSRange.lshr(RHSRange));
1258 break;
1259 case Instruction::And:
1260 Result.markConstantRange(LHSRange.binaryAnd(RHSRange));
1261 break;
1262 case Instruction::Or:
1263 Result.markConstantRange(LHSRange.binaryOr(RHSRange));
1264 break;
1265 default:
1266 // Should be dead if the code above is correct
1267 llvm_unreachable("inconsistent with above");
1268 break;
1269 }
1270
1223 auto BinOp = (Instruction::BinaryOps) BBI->getOpcode();
1224 Result.markConstantRange(LHSRange.binaryOp(BinOp, RHSRange));
12711225 BBLV = Result;
12721226 return true;
12731227 }
533533 return ConstantRange(L, U);
534534 }
535535
536 ConstantRange ConstantRange::castOp(Instruction::CastOps CastOp,
537 uint32_t ResultBitWidth) const {
538 switch (CastOp) {
539 default:
540 llvm_unreachable("unsupported cast type");
541 case Instruction::Trunc:
542 return truncate(ResultBitWidth);
543 case Instruction::SExt:
544 return signExtend(ResultBitWidth);
545 case Instruction::ZExt:
546 return zeroExtend(ResultBitWidth);
547 case Instruction::BitCast:
548 return *this;
549 case Instruction::FPToUI:
550 case Instruction::FPToSI:
551 if (getBitWidth() == ResultBitWidth)
552 return *this;
553 else
554 return ConstantRange(getBitWidth(), /*isFullSet=*/true);
555 case Instruction::UIToFP: {
556 // TODO: use input range if available
557 auto BW = getBitWidth();
558 APInt Min = APInt::getMinValue(BW).zextOrSelf(ResultBitWidth);
559 APInt Max = APInt::getMaxValue(BW).zextOrSelf(ResultBitWidth);
560 return ConstantRange(Min, Max);
561 }
562 case Instruction::SIToFP: {
563 // TODO: use input range if available
564 auto BW = getBitWidth();
565 APInt SMin = APInt::getSignedMinValue(BW).sextOrSelf(ResultBitWidth);
566 APInt SMax = APInt::getSignedMaxValue(BW).sextOrSelf(ResultBitWidth);
567 return ConstantRange(SMin, SMax);
568 }
569 case Instruction::FPTrunc:
570 case Instruction::FPExt:
571 case Instruction::IntToPtr:
572 case Instruction::PtrToInt:
573 case Instruction::AddrSpaceCast:
574 // Conservatively return full set.
575 return ConstantRange(getBitWidth(), /*isFullSet=*/true);
576 };
577 }
578
536579 /// zeroExtend - Return a new range in the specified integer type, which must
537580 /// be strictly larger than the current type. The returned range will
538581 /// correspond to the possible range of values as if the source range had been
652695 return *this;
653696 }
654697
698 ConstantRange ConstantRange::binaryOp(Instruction::BinaryOps BinOp,
699 const ConstantRange &Other) const {
700 assert(BinOp >= Instruction::BinaryOpsBegin &&
701 BinOp < Instruction::BinaryOpsEnd && "Binary operators only!");
702
703 switch (BinOp) {
704 case Instruction::Add:
705 return add(Other);
706 case Instruction::Sub:
707 return sub(Other);
708 case Instruction::Mul:
709 return multiply(Other);
710 case Instruction::UDiv:
711 return udiv(Other);
712 case Instruction::Shl:
713 return shl(Other);
714 case Instruction::LShr:
715 return lshr(Other);
716 case Instruction::And:
717 return binaryAnd(Other);
718 case Instruction::Or:
719 return binaryOr(Other);
720 // Note: floating point operations applied to abstract ranges are just
721 // ideal integer operations with a lossy representation
722 case Instruction::FAdd:
723 return add(Other);
724 case Instruction::FSub:
725 return sub(Other);
726 case Instruction::FMul:
727 return multiply(Other);
728 default:
729 // Conservatively return full set.
730 return ConstantRange(getBitWidth(), /*isFullSet=*/true);
731 }
732 }
733
655734 ConstantRange
656735 ConstantRange::add(const ConstantRange &Other) const {
657736 if (isEmptySet() || Other.isEmptySet())
189189 seen(I, badRange());
190190 break;
191191
192 case Instruction::UIToFP: {
193 // Path terminated cleanly.
192 case Instruction::UIToFP:
193 case Instruction::SIToFP: {
194 // Path terminated cleanly - use the type of the integer input to seed
195 // the analysis.
194196 unsigned BW = I->getOperand(0)->getType()->getPrimitiveSizeInBits();
195 APInt Min = APInt::getMinValue(BW).zextOrSelf(MaxIntegerBW+1);
196 APInt Max = APInt::getMaxValue(BW).zextOrSelf(MaxIntegerBW+1);
197 seen(I, validateRange(ConstantRange(Min, Max)));
198 continue;
199 }
200
201 case Instruction::SIToFP: {
202 // Path terminated cleanly.
203 unsigned BW = I->getOperand(0)->getType()->getPrimitiveSizeInBits();
204 APInt SMin = APInt::getSignedMinValue(BW).sextOrSelf(MaxIntegerBW+1);
205 APInt SMax = APInt::getSignedMaxValue(BW).sextOrSelf(MaxIntegerBW+1);
206 seen(I, validateRange(ConstantRange(SMin, SMax)));
197 auto Input = ConstantRange(BW, true);
198 auto CastOp = (Instruction::CastOps)I->getOpcode();
199 seen(I, validateRange(Input.castOp(CastOp, MaxIntegerBW+1)));
207200 continue;
208201 }
209202
248241 llvm_unreachable("Should have been handled in walkForwards!");
249242
250243 case Instruction::FAdd:
251 Op = [](ArrayRef Ops) {
252 assert(Ops.size() == 2 && "FAdd is a binary operator!");
253 return Ops[0].add(Ops[1]);
254 };
255 break;
256
257244 case Instruction::FSub:
258 Op = [](ArrayRef Ops) {
259 assert(Ops.size() == 2 && "FSub is a binary operator!");
260 return Ops[0].sub(Ops[1]);
261 };
262 break;
263
264245 case Instruction::FMul:
265 Op = [](ArrayRef Ops) {
266 assert(Ops.size() == 2 && "FMul is a binary operator!");
267 return Ops[0].multiply(Ops[1]);
246 Op = [I](ArrayRef Ops) {
247 assert(Ops.size() == 2 && "its a binary operator!");
248 auto BinOp = (Instruction::BinaryOps) I->getOpcode();
249 return Ops[0].binaryOp(BinOp, Ops[1]);
268250 };
269251 break;
270252
274256 //
275257 case Instruction::FPToUI:
276258 case Instruction::FPToSI:
277 Op = [](ArrayRef Ops) {
259 Op = [I](ArrayRef Ops) {
278260 assert(Ops.size() == 1 && "FPTo[US]I is a unary operator!");
279 return Ops[0];
261 // Note: We're ignoring the casts output size here as that's what the
262 // caller expects.
263 auto CastOp = (Instruction::CastOps)I->getOpcode();
264 return Ops[0].castOp(CastOp, MaxIntegerBW+1);
280265 };
281266 break;
282267