Index: include/llvm/IR/ConstantRange.h =================================================================== --- include/llvm/IR/ConstantRange.h +++ include/llvm/IR/ConstantRange.h @@ -208,11 +208,18 @@ ConstantRange sub(const ConstantRange &Other) const; /// Return a new range representing the possible values resulting - /// from a multiplication of a value in this range and a value in \p Other. + /// from a multiplication of a value in this range and a value in \p Other, + /// treating both this and \p Other as unsigned ranges. /// TODO: This isn't fully implemented yet. ConstantRange multiply(const ConstantRange &Other) const; /// Return a new range representing the possible values resulting + /// from a multiplication of a value in this range and a value in \p Other, + /// treating both this and \p Other as signed ranges. + /// TODO: This isn't fully implemented yet. + ConstantRange smultiply(const ConstantRange &Other) const; + + /// Return a new range representing the possible values resulting /// from a signed maximum of a value in this range and a value in \p Other. ConstantRange smax(const ConstantRange &Other) const; Index: lib/IR/ConstantRange.cpp =================================================================== --- lib/IR/ConstantRange.cpp +++ lib/IR/ConstantRange.cpp @@ -598,6 +598,26 @@ } ConstantRange +ConstantRange::smultiply(const ConstantRange &Other) const { + // TODO: If either operand is a single element and the multiply is known to + // be non-wrapping, round the result min and max value to the appropriate + // multiple of that element. If wrapping is possible, at least adjust the + // range according to the greatest power-of-two factor of the single element. + + if (isEmptySet() || Other.isEmptySet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/false); + + APInt this_min = getSignedMin().sext(getBitWidth() * 2); + APInt this_max = getSignedMax().sext(getBitWidth() * 2); + APInt Other_min = Other.getSignedMin().sext(getBitWidth() * 2); + APInt Other_max = Other.getSignedMax().sext(getBitWidth() * 2); + + ConstantRange Result_zext = ConstantRange(this_min * Other_min, + this_max * Other_max + 1); + return Result_zext.truncate(getBitWidth()); +} + +ConstantRange ConstantRange::smax(const ConstantRange &Other) const { // X smax Y is: range(smax(X_smin, Y_smin), // smax(X_smax, Y_smax))