Skip to content

Commit

Permalink
[IR] Add SaturatingInst and BinaryOpIntrinsic classes
Browse files Browse the repository at this point in the history
Based on the suggestion in D62447, this adds a SaturatingInst class
that represents the saturating add/sub family of intrinsics. It
exposes the same interface as WithOverflowInst, for this reason I
have also added a common base class BinaryOpIntrinsic that holds the
actual implementation code and will be useful in some places handling
both overflowing and saturating math.

Differential Revision: https://reviews.llvm.org/D62466

llvm-svn: 361857
  • Loading branch information
nikic committed May 28, 2019
1 parent 7669665 commit 2fb0a82
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 5 deletions.
49 changes: 47 additions & 2 deletions llvm/include/llvm/IR/IntrinsicInst.h
Expand Up @@ -267,8 +267,9 @@ namespace llvm {
}
};

/// 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()) {
Expand All @@ -278,6 +279,10 @@ namespace llvm {
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;
Expand All @@ -300,6 +305,46 @@ namespace llvm {
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
Expand Down
12 changes: 9 additions & 3 deletions llvm/lib/IR/IntrinsicInst.cpp
Expand Up @@ -171,13 +171,17 @@ bool ConstrainedFPIntrinsic::isTernaryOp() const {
}
}

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:
Expand All @@ -187,18 +191,20 @@ Instruction::BinaryOps WithOverflowInst::getBinaryOp() const {
}
}

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
Expand Down

0 comments on commit 2fb0a82

Please sign in to comment.