5454// | |
5555// | +- ZExtInst
5656// |
57- // +- CallBase -----------+- CallBrInst
58- // | |
59- // +- CmpInst +- CallInst
60- // | |
61- // +- ExtractElementInst +- InvokeInst
57+ // +- CallBase --------+- CallBrInst
58+ // | |
59+ // | +- CallInst
60+ // | |
61+ // | +- InvokeInst
62+ // |
63+ // +- CmpInst ---------+- ICmpInst
64+ // | |
65+ // | +- FCmpInst
66+ // |
67+ // +- ExtractElementInst
6268// |
6369// +- GetElementPtrInst
6470// |
@@ -158,6 +164,9 @@ class BinaryOperator;
158164class PossiblyDisjointInst ;
159165class AtomicRMWInst ;
160166class AtomicCmpXchgInst ;
167+ class CmpInst ;
168+ class ICmpInst ;
169+ class FCmpInst ;
161170
162171// / Iterator for the `Use` edges of a User's operands.
163172// / \Returns the operand `Use` when dereferenced.
@@ -304,6 +313,7 @@ class Value {
304313 friend class PHINode ; // For getting `Val`.
305314 friend class UnreachableInst ; // For getting `Val`.
306315 friend class CatchSwitchAddHandler ; // For `Val`.
316+ friend class CmpInst ; // For getting `Val`.
307317 friend class ConstantArray ; // For `Val`.
308318 friend class ConstantStruct ; // For `Val`.
309319
@@ -1076,6 +1086,7 @@ class Instruction : public sandboxir::User {
10761086 friend class CastInst ; // For getTopmostLLVMInstruction().
10771087 friend class PHINode ; // For getTopmostLLVMInstruction().
10781088 friend class UnreachableInst ; // For getTopmostLLVMInstruction().
1089+ friend class CmpInst ; // For getTopmostLLVMInstruction().
10791090
10801091 // / \Returns the LLVM IR Instructions that this SandboxIR maps to in program
10811092 // / order.
@@ -1232,6 +1243,7 @@ template <typename LLVMT> class SingleLLVMInstructionImpl : public Instruction {
12321243 friend class UnaryInstruction ;
12331244 friend class CallBase ;
12341245 friend class FuncletPadInst ;
1246+ friend class CmpInst ;
12351247
12361248 Use getOperandUseInternal (unsigned OpIdx, bool Verify) const final {
12371249 return getOperandUseDefault (OpIdx, Verify);
@@ -3425,6 +3437,151 @@ class PHINode final : public SingleLLVMInstructionImpl<llvm::PHINode> {
34253437 // uint32_t ToIdx = 0)
34263438};
34273439
3440+ // Wraps a static function that takes a single Predicate parameter
3441+ // LLVMValType should be the type of the wrapped class
3442+ #define WRAP_STATIC_PREDICATE (FunctionName ) \
3443+ static auto FunctionName (Predicate P) { return LLVMValType::FunctionName (P); }
3444+ // Wraps a member function that takes no parameters
3445+ // LLVMValType should be the type of the wrapped class
3446+ #define WRAP_MEMBER (FunctionName ) \
3447+ auto FunctionName () const { return cast<LLVMValType>(Val)->FunctionName (); }
3448+ // Wraps both--a common idiom in the CmpInst classes
3449+ #define WRAP_BOTH (FunctionName ) \
3450+ WRAP_STATIC_PREDICATE (FunctionName) \
3451+ WRAP_MEMBER(FunctionName)
3452+
3453+ class CmpInst : public SingleLLVMInstructionImpl<llvm::CmpInst> {
3454+ protected:
3455+ using LLVMValType = llvm::CmpInst;
3456+ // / Use Context::createCmpInst(). Don't call the constructor directly.
3457+ CmpInst (llvm::CmpInst *CI, Context &Ctx, ClassID Id, Opcode Opc)
3458+ : SingleLLVMInstructionImpl (Id, Opc, CI, Ctx) {}
3459+ friend Context; // for CmpInst()
3460+ static Value *createCommon (Value *Cond, Value *True, Value *False,
3461+ const Twine &Name, IRBuilder<> &Builder,
3462+ Context &Ctx);
3463+
3464+ public:
3465+ using Predicate = llvm::CmpInst::Predicate;
3466+
3467+ static CmpInst *create (Predicate Pred, Value *S1, Value *S2,
3468+ Instruction *InsertBefore, Context &Ctx,
3469+ const Twine &Name = " " );
3470+ static CmpInst *createWithCopiedFlags (Predicate Pred, Value *S1, Value *S2,
3471+ const Instruction *FlagsSource,
3472+ Instruction *InsertBefore, Context &Ctx,
3473+ const Twine &Name = " " );
3474+ void setPredicate (Predicate P);
3475+ void swapOperands ();
3476+
3477+ WRAP_MEMBER (getPredicate);
3478+ WRAP_BOTH (isFPPredicate);
3479+ WRAP_BOTH (isIntPredicate);
3480+ WRAP_STATIC_PREDICATE (getPredicateName);
3481+ WRAP_BOTH (getInversePredicate);
3482+ WRAP_BOTH (getOrderedPredicate);
3483+ WRAP_BOTH (getUnorderedPredicate);
3484+ WRAP_BOTH (getSwappedPredicate);
3485+ WRAP_BOTH (isStrictPredicate);
3486+ WRAP_BOTH (isNonStrictPredicate);
3487+ WRAP_BOTH (getStrictPredicate);
3488+ WRAP_BOTH (getNonStrictPredicate);
3489+ WRAP_BOTH (getFlippedStrictnessPredicate);
3490+ WRAP_MEMBER (isCommutative);
3491+ WRAP_BOTH (isEquality);
3492+ WRAP_BOTH (isRelational);
3493+ WRAP_BOTH (isSigned);
3494+ WRAP_BOTH (getSignedPredicate);
3495+ WRAP_BOTH (getUnsignedPredicate);
3496+ WRAP_BOTH (getFlippedSignednessPredicate);
3497+ WRAP_BOTH (isTrueWhenEqual);
3498+ WRAP_BOTH (isFalseWhenEqual);
3499+ WRAP_BOTH (isUnsigned);
3500+ WRAP_STATIC_PREDICATE (isOrdered);
3501+ WRAP_STATIC_PREDICATE (isUnordered);
3502+
3503+ static bool isImpliedTrueByMatchingCmp (Predicate Pred1, Predicate Pred2) {
3504+ return llvm::CmpInst::isImpliedTrueByMatchingCmp (Pred1, Pred2);
3505+ }
3506+ static bool isImpliedFalseByMatchingCmp (Predicate Pred1, Predicate Pred2) {
3507+ return llvm::CmpInst::isImpliedFalseByMatchingCmp (Pred1, Pred2);
3508+ }
3509+
3510+ // / Method for support type inquiry through isa, cast, and dyn_cast:
3511+ static bool classof (const Value *From) {
3512+ return From->getSubclassID () == ClassID::ICmp ||
3513+ From->getSubclassID () == ClassID::FCmp;
3514+ }
3515+
3516+ // / Create a result type for fcmp/icmp
3517+ static Type *makeCmpResultType (Type *OpndType);
3518+
3519+ #ifndef NDEBUG
3520+ void dumpOS (raw_ostream &OS) const override ;
3521+ LLVM_DUMP_METHOD void dump () const ;
3522+ #endif
3523+ };
3524+
3525+ class ICmpInst : public CmpInst {
3526+ // / Use Context::createICmpInst(). Don't call the constructor directly.
3527+ ICmpInst (llvm::ICmpInst *CI, Context &Ctx)
3528+ : CmpInst(CI, Ctx, ClassID::ICmp, Opcode::ICmp) {}
3529+ friend class Context ; // For constructor.
3530+ using LLVMValType = llvm::ICmpInst;
3531+
3532+ public:
3533+ void swapOperands ();
3534+
3535+ WRAP_BOTH (getSignedPredicate);
3536+ WRAP_BOTH (getUnsignedPredicate);
3537+ WRAP_BOTH (isEquality);
3538+ WRAP_MEMBER (isCommutative);
3539+ WRAP_MEMBER (isRelational);
3540+ WRAP_STATIC_PREDICATE (isGT);
3541+ WRAP_STATIC_PREDICATE (isLT);
3542+ WRAP_STATIC_PREDICATE (isGE);
3543+ WRAP_STATIC_PREDICATE (isLE);
3544+
3545+ static auto predicates () { return llvm::ICmpInst::predicates (); }
3546+ static bool compare (const APInt &LHS, const APInt &RHS,
3547+ ICmpInst::Predicate Pred) {
3548+ return llvm::ICmpInst::compare (LHS, RHS, Pred);
3549+ }
3550+
3551+ static bool classof (const Value *From) {
3552+ return From->getSubclassID () == ClassID::ICmp;
3553+ }
3554+ };
3555+
3556+ class FCmpInst : public CmpInst {
3557+ // / Use Context::createFCmpInst(). Don't call the constructor directly.
3558+ FCmpInst (llvm::FCmpInst *CI, Context &Ctx)
3559+ : CmpInst(CI, Ctx, ClassID::FCmp, Opcode::FCmp) {}
3560+ friend class Context ; // For constructor.
3561+ using LLVMValType = llvm::FCmpInst;
3562+
3563+ public:
3564+ void swapOperands ();
3565+
3566+ WRAP_BOTH (isEquality);
3567+ WRAP_MEMBER (isCommutative);
3568+ WRAP_MEMBER (isRelational);
3569+
3570+ static auto predicates () { return llvm::FCmpInst::predicates (); }
3571+ static bool compare (const APFloat &LHS, const APFloat &RHS,
3572+ FCmpInst::Predicate Pred) {
3573+ return llvm::FCmpInst::compare (LHS, RHS, Pred);
3574+ }
3575+
3576+ static bool classof (const Value *From) {
3577+ return From->getSubclassID () == ClassID::FCmp;
3578+ }
3579+ };
3580+
3581+ #undef WRAP_STATIC_PREDICATE
3582+ #undef WRAP_MEMBER
3583+ #undef WRAP_BOTH
3584+
34283585// / An LLLVM Instruction that has no SandboxIR equivalent class gets mapped to
34293586// / an OpaqueInstr.
34303587class OpaqueInst : public SingleLLVMInstructionImpl <llvm::Instruction> {
@@ -3445,6 +3602,8 @@ class Context {
34453602 LLVMContext &LLVMCtx;
34463603 friend class Type ; // For LLVMCtx.
34473604 friend class PointerType ; // For LLVMCtx.
3605+ friend class CmpInst ; // For LLVMCtx. TODO: cleanup when sandboxir::VectorType
3606+ // is complete
34483607 friend class IntegerType ; // For LLVMCtx.
34493608 friend class StructType ; // For LLVMCtx.
34503609 Tracker IRTracker;
@@ -3572,6 +3731,12 @@ class Context {
35723731 friend PHINode; // For createPHINode()
35733732 UnreachableInst *createUnreachableInst (llvm::UnreachableInst *UI);
35743733 friend UnreachableInst; // For createUnreachableInst()
3734+ CmpInst *createCmpInst (llvm::CmpInst *I);
3735+ friend CmpInst; // For createCmpInst()
3736+ ICmpInst *createICmpInst (llvm::ICmpInst *I);
3737+ friend ICmpInst; // For createICmpInst()
3738+ FCmpInst *createFCmpInst (llvm::FCmpInst *I);
3739+ friend FCmpInst; // For createFCmpInst()
35753740
35763741public:
35773742 Context (LLVMContext &LLVMCtx)
0 commit comments