}
};
- /// This class represents a op.with.overflow intrinsic.
- class WithOverflowInst : public IntrinsicInst {
+ /// This class represents an intrinsic that is based on a binary operation.
+ /// This includes op.with.overflow and saturating add/sub intrinsics.
+ class BinaryOpIntrinsic : public IntrinsicInst {
public:
static bool classof(const IntrinsicInst *I) {
switch (I->getIntrinsicID()) {
case Intrinsic::ssub_with_overflow:
case Intrinsic::umul_with_overflow:
case Intrinsic::smul_with_overflow:
+ case Intrinsic::uadd_sat:
+ case Intrinsic::sadd_sat:
+ case Intrinsic::usub_sat:
+ case Intrinsic::ssub_sat:
return true;
default:
return false;
unsigned getNoWrapKind() const;
};
+ /// Represents an op.with.overflow intrinsic.
+ class WithOverflowInst : public BinaryOpIntrinsic {
+ public:
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::uadd_with_overflow:
+ case Intrinsic::sadd_with_overflow:
+ case Intrinsic::usub_with_overflow:
+ case Intrinsic::ssub_with_overflow:
+ case Intrinsic::umul_with_overflow:
+ case Intrinsic::smul_with_overflow:
+ return true;
+ default:
+ return false;
+ }
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// Represents a saturating add/sub intrinsic.
+ class SaturatingInst : public BinaryOpIntrinsic {
+ public:
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::uadd_sat:
+ case Intrinsic::sadd_sat:
+ case Intrinsic::usub_sat:
+ case Intrinsic::ssub_sat:
+ return true;
+ default:
+ return false;
+ }
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
/// Common base class for all memory intrinsics. Simply provides
/// common methods.
/// Written as CRTP to avoid a common base class amongst the
}
}
-Instruction::BinaryOps WithOverflowInst::getBinaryOp() const {
+Instruction::BinaryOps BinaryOpIntrinsic::getBinaryOp() const {
switch (getIntrinsicID()) {
case Intrinsic::uadd_with_overflow:
case Intrinsic::sadd_with_overflow:
+ case Intrinsic::uadd_sat:
+ case Intrinsic::sadd_sat:
return Instruction::Add;
case Intrinsic::usub_with_overflow:
case Intrinsic::ssub_with_overflow:
+ case Intrinsic::usub_sat:
+ case Intrinsic::ssub_sat:
return Instruction::Sub;
case Intrinsic::umul_with_overflow:
case Intrinsic::smul_with_overflow:
}
}
-bool WithOverflowInst::isSigned() const {
+bool BinaryOpIntrinsic::isSigned() const {
switch (getIntrinsicID()) {
case Intrinsic::sadd_with_overflow:
case Intrinsic::ssub_with_overflow:
case Intrinsic::smul_with_overflow:
+ case Intrinsic::sadd_sat:
+ case Intrinsic::ssub_sat:
return true;
default:
return false;
}
}
-unsigned WithOverflowInst::getNoWrapKind() const {
+unsigned BinaryOpIntrinsic::getNoWrapKind() const {
if (isSigned())
return OverflowingBinaryOperator::NoSignedWrap;
else