mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
[IR] Add SaturatingInst and BinaryOpIntrinsic classes
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
This commit is contained in:
parent
1cdac3fa17
commit
3a98741a79
@ -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()) {
|
||||
@ -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;
|
||||
@ -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
|
||||
|
@ -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:
|
||||
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user