Skip to content

Commit d68ef90

Browse files
authored
Merge pull request rust-lang#120 from vext01/icmp-with-pred
Include the predicate in the ICmp lowering.
2 parents c24768e + 0668c58 commit d68ef90

File tree

1 file changed

+81
-1
lines changed

1 file changed

+81
-1
lines changed

llvm/lib/YkIR/YkIRWriter.cpp

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ enum OperandKind {
7676
Block,
7777
Arg,
7878
Global,
79+
Predicate,
7980
UnimplementedOperand = 255,
8081
};
8182

@@ -88,6 +89,20 @@ enum TypeKind {
8889
UnimplementedType = 255, // YKFIXME: Will eventually be deleted.
8990
};
9091

92+
// A predicate used in a numeric comparison.
93+
enum CmpPredicate {
94+
PredEqual = 0,
95+
PredNotEqual,
96+
PredUnsignedGreater,
97+
PredUnsignedGreaterEqual,
98+
PredUnsignedLess,
99+
PredUnsignedLessEqual,
100+
PredSignedGreater,
101+
PredSignedGreaterEqual,
102+
PredSignedLess,
103+
PredSignedLessEqual,
104+
};
105+
91106
template <class T> string toString(T *X) {
92107
string S;
93108
raw_string_ostream SS(S);
@@ -466,6 +481,71 @@ class YkIRWriter {
466481
InstIdx++;
467482
}
468483

484+
// Serialise an LLVM predicate.
485+
//
486+
// Note that this can't be handled by `serialiseOperand()` as in LLVM a
487+
// `Predicate` isn't a `Value`.
488+
void serialisePredicateOperand(llvm::CmpInst::Predicate P) {
489+
std::optional<CmpPredicate> LP = std::nullopt;
490+
switch (P) {
491+
case llvm::CmpInst::ICMP_EQ:
492+
LP = PredEqual;
493+
break;
494+
case llvm::CmpInst::ICMP_NE:
495+
LP = PredNotEqual;
496+
break;
497+
case llvm::CmpInst::ICMP_UGT:
498+
LP = PredUnsignedGreater;
499+
break;
500+
case llvm::CmpInst::ICMP_UGE:
501+
LP = PredUnsignedGreaterEqual;
502+
break;
503+
case llvm::CmpInst::ICMP_ULT:
504+
LP = PredUnsignedLess;
505+
break;
506+
case llvm::CmpInst::ICMP_ULE:
507+
LP = PredUnsignedLessEqual;
508+
break;
509+
case llvm::CmpInst::ICMP_SGT:
510+
LP = PredSignedGreater;
511+
break;
512+
case llvm::CmpInst::ICMP_SGE:
513+
LP = PredSignedGreaterEqual;
514+
break;
515+
case llvm::CmpInst::ICMP_SLT:
516+
LP = PredSignedLess;
517+
break;
518+
case llvm::CmpInst::ICMP_SLE:
519+
LP = PredSignedLessEqual;
520+
break;
521+
default:
522+
abort(); // TODO: floating point predicates.
523+
}
524+
OutStreamer.emitInt8(OperandKind::Predicate);
525+
OutStreamer.emitInt8(LP.value());
526+
}
527+
528+
// We use a custom lowering for ICmp, as a generic lowering misses
529+
// the predicate.
530+
void serialiseICmpInst(ICmpInst *I, ValueLoweringMap &VLMap, unsigned BBIdx,
531+
unsigned &InstIdx) {
532+
// type_index:
533+
OutStreamer.emitSizeT(typeIndex(I->getType()));
534+
// opcode:
535+
serialiseOpcode(OpCode::ICmp);
536+
// num_operands:
537+
OutStreamer.emitInt32(3);
538+
// op1:
539+
serialiseOperand(I, VLMap, I->getOperand(0));
540+
// predicate:
541+
serialisePredicateOperand(I->getPredicate());
542+
// op2:
543+
serialiseOperand(I, VLMap, I->getOperand(1));
544+
545+
VLMap[I] = {BBIdx, InstIdx};
546+
InstIdx++;
547+
}
548+
469549
void serialiseInst(Instruction *I, ValueLoweringMap &VLMap, unsigned BBIdx,
470550
unsigned &InstIdx) {
471551
// Macros to help dispatch to serialisers.
@@ -484,7 +564,6 @@ class YkIRWriter {
484564

485565
GENERIC_INST_SERIALISE(I, LoadInst, Load)
486566
GENERIC_INST_SERIALISE(I, StoreInst, Store)
487-
GENERIC_INST_SERIALISE(I, ICmpInst, ICmp)
488567
GENERIC_INST_SERIALISE(I, ReturnInst, Ret)
489568
GENERIC_INST_SERIALISE(I, llvm::InsertValueInst, InsertValue)
490569
GENERIC_INST_SERIALISE(I, StoreInst, Store)
@@ -494,6 +573,7 @@ class YkIRWriter {
494573
CUSTOM_INST_SERIALISE(I, BranchInst, serialiseBranchInst)
495574
CUSTOM_INST_SERIALISE(I, GetElementPtrInst, serialiseGetElementPtr)
496575
CUSTOM_INST_SERIALISE(I, llvm::BinaryOperator, serialiseBinaryOperation)
576+
CUSTOM_INST_SERIALISE(I, ICmpInst, serialiseICmpInst)
497577

498578
// GENERIC_INST_SERIALISE and CUSTOM_INST_SERIALISE do an early return upon
499579
// a match, so if we get here then the instruction wasn't handled.

0 commit comments

Comments
 (0)