54
54
// | |
55
55
// | +- ZExtInst
56
56
// |
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
62
68
// |
63
69
// +- GetElementPtrInst
64
70
// |
@@ -158,6 +164,9 @@ class BinaryOperator;
158
164
class PossiblyDisjointInst ;
159
165
class AtomicRMWInst ;
160
166
class AtomicCmpXchgInst ;
167
+ class CmpInst ;
168
+ class ICmpInst ;
169
+ class FCmpInst ;
161
170
162
171
// / Iterator for the `Use` edges of a User's operands.
163
172
// / \Returns the operand `Use` when dereferenced.
@@ -304,6 +313,7 @@ class Value {
304
313
friend class PHINode ; // For getting `Val`.
305
314
friend class UnreachableInst ; // For getting `Val`.
306
315
friend class CatchSwitchAddHandler ; // For `Val`.
316
+ friend class CmpInst ; // For getting `Val`.
307
317
friend class ConstantArray ; // For `Val`.
308
318
friend class ConstantStruct ; // For `Val`.
309
319
@@ -1076,6 +1086,7 @@ class Instruction : public sandboxir::User {
1076
1086
friend class CastInst ; // For getTopmostLLVMInstruction().
1077
1087
friend class PHINode ; // For getTopmostLLVMInstruction().
1078
1088
friend class UnreachableInst ; // For getTopmostLLVMInstruction().
1089
+ friend class CmpInst ; // For getTopmostLLVMInstruction().
1079
1090
1080
1091
// / \Returns the LLVM IR Instructions that this SandboxIR maps to in program
1081
1092
// / order.
@@ -1232,6 +1243,7 @@ template <typename LLVMT> class SingleLLVMInstructionImpl : public Instruction {
1232
1243
friend class UnaryInstruction ;
1233
1244
friend class CallBase ;
1234
1245
friend class FuncletPadInst ;
1246
+ friend class CmpInst ;
1235
1247
1236
1248
Use getOperandUseInternal (unsigned OpIdx, bool Verify) const final {
1237
1249
return getOperandUseDefault (OpIdx, Verify);
@@ -3425,6 +3437,151 @@ class PHINode final : public SingleLLVMInstructionImpl<llvm::PHINode> {
3425
3437
// uint32_t ToIdx = 0)
3426
3438
};
3427
3439
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
+
3428
3585
// / An LLLVM Instruction that has no SandboxIR equivalent class gets mapped to
3429
3586
// / an OpaqueInstr.
3430
3587
class OpaqueInst : public SingleLLVMInstructionImpl <llvm::Instruction> {
@@ -3445,6 +3602,8 @@ class Context {
3445
3602
LLVMContext &LLVMCtx;
3446
3603
friend class Type ; // For LLVMCtx.
3447
3604
friend class PointerType ; // For LLVMCtx.
3605
+ friend class CmpInst ; // For LLVMCtx. TODO: cleanup when sandboxir::VectorType
3606
+ // is complete
3448
3607
friend class IntegerType ; // For LLVMCtx.
3449
3608
friend class StructType ; // For LLVMCtx.
3450
3609
Tracker IRTracker;
@@ -3572,6 +3731,12 @@ class Context {
3572
3731
friend PHINode; // For createPHINode()
3573
3732
UnreachableInst *createUnreachableInst (llvm::UnreachableInst *UI);
3574
3733
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()
3575
3740
3576
3741
public:
3577
3742
Context (LLVMContext &LLVMCtx)
0 commit comments