Skip to content

Commit 73b4623

Browse files
committed
[IR] Add samesign flag to icmp instruction
1 parent 0dbc85a commit 73b4623

File tree

16 files changed

+112
-2
lines changed

16 files changed

+112
-2
lines changed

llvm/docs/LangRef.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12329,6 +12329,7 @@ Syntax:
1232912329
::
1233012330

1233112331
<result> = icmp <cond> <ty> <op1>, <op2> ; yields i1 or <N x i1>:result
12332+
<result> = icmp samesign <cond> <ty> <op1>, <op2> ; yields i1 or <N x i1>:result
1233212333

1233312334
Overview:
1233412335
"""""""""
@@ -12398,6 +12399,9 @@ If the operands are integer vectors, then they are compared element by
1239812399
element. The result is an ``i1`` vector with the same number of elements
1239912400
as the values being compared. Otherwise, the result is an ``i1``.
1240012401

12402+
If the ``samesign`` keyword is present and the operands are not of the
12403+
same sign then the result is a :ref:`poison value <poisonvalues>`.
12404+
1240112405
Example:
1240212406
""""""""
1240312407

llvm/include/llvm/AsmParser/LLToken.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ enum Kind {
114114
kw_disjoint,
115115
kw_inbounds,
116116
kw_nneg,
117+
kw_samesign,
117118
kw_inrange,
118119
kw_addrspace,
119120
kw_section,

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,10 @@ enum GetElementPtrOptionalFlags {
540540
GEP_NUW = 2,
541541
};
542542

543+
/// PossiblySameSignOptionalFlags - Flags for serializing
544+
/// PossiblySameSignInst's SubclassOptionalData contents.
545+
enum PossiblySameSignInstOptionalFlags { PSSI_SAME_SIGN = 0 };
546+
543547
/// Encoded AtomicOrdering values.
544548
enum AtomicOrderingCodes {
545549
ORDERING_NOTATOMIC = 0,

llvm/include/llvm/IR/Instructions.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,17 @@ class ICmpInst: public CmpInst {
12241224
/// Return the unsigned version of the predicate.
12251225
static Predicate getUnsignedPredicate(Predicate pred);
12261226

1227+
/// An icmp instruction, which can be marked as "samesign", indicating that
1228+
/// the two operands have the same sign. This means that we can convert
1229+
/// "slt/ult" to "ult", which enables more optimizations.
1230+
enum { SameSign = (1 << 0) };
1231+
1232+
void setSameSign(bool B) {
1233+
SubclassOptionalData = (SubclassOptionalData & ~SameSign) | (B * SameSign);
1234+
}
1235+
1236+
bool hasSameSign() const { return SubclassOptionalData & SameSign; }
1237+
12271238
/// Return true if this predicate is either EQ or NE. This also
12281239
/// tests for commutativity.
12291240
static bool isEquality(Predicate P) {

llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct PoisonFlags {
4747
unsigned Exact : 1;
4848
unsigned Disjoint : 1;
4949
unsigned NNeg : 1;
50+
unsigned SameSign : 1;
5051
GEPNoWrapFlags GEPNW;
5152

5253
PoisonFlags(const Instruction *I);

llvm/lib/AsmParser/LLLexer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@ lltok::Kind LLLexer::LexIdentifier() {
583583
KEYWORD(disjoint);
584584
KEYWORD(inbounds);
585585
KEYWORD(nneg);
586+
KEYWORD(samesign);
586587
KEYWORD(inrange);
587588
KEYWORD(addrspace);
588589
KEYWORD(section);

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6952,8 +6952,14 @@ int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB,
69526952
case lltok::kw_and:
69536953
case lltok::kw_xor:
69546954
return parseLogical(Inst, PFS, KeywordVal);
6955-
case lltok::kw_icmp:
6956-
return parseCompare(Inst, PFS, KeywordVal);
6955+
case lltok::kw_icmp: {
6956+
bool SameSign = EatIfPresent(lltok::kw_samesign);
6957+
if (parseCompare(Inst, PFS, KeywordVal))
6958+
return true;
6959+
if (SameSign)
6960+
cast<ICmpInst>(Inst)->setSameSign(true);
6961+
return false;
6962+
}
69576963
case lltok::kw_fcmp: {
69586964
FastMathFlags FMF = EatFastMathFlagsIfPresent();
69596965
int Res = parseCompare(Inst, PFS, KeywordVal);

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5482,6 +5482,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
54825482
if (!CmpInst::isIntPredicate(PredVal))
54835483
return error("Invalid icmp predicate");
54845484
I = new ICmpInst(PredVal, LHS, RHS);
5485+
if (Record[OpNum] & (1 << bitc::PSSI_SAME_SIGN))
5486+
cast<ICmpInst>(I)->setSameSign(true);
54855487
}
54865488

54875489
ResTypeID = getVirtualTypeID(I->getType()->getScalarType());

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,6 +1718,9 @@ static uint64_t getOptimizationFlags(const Value *V) {
17181718
Flags |= 1 << bitc::GEP_NUSW;
17191719
if (GEP->hasNoUnsignedWrap())
17201720
Flags |= 1 << bitc::GEP_NUW;
1721+
} else if (const auto *ICmp = dyn_cast<ICmpInst>(V)) {
1722+
if (ICmp->hasSameSign())
1723+
Flags |= 1 << bitc::PSSI_SAME_SIGN;
17211724
}
17221725

17231726
return Flags;

llvm/lib/IR/AsmWriter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,6 +1433,9 @@ static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
14331433
Out << " nuw";
14341434
if (TI->hasNoSignedWrap())
14351435
Out << " nsw";
1436+
} else if (const auto *ICmp = dyn_cast<ICmpInst>(U)) {
1437+
if (ICmp->hasSameSign())
1438+
Out << " samesign";
14361439
}
14371440
}
14381441

0 commit comments

Comments
 (0)