Skip to content

Commit f040f49

Browse files
committed
IR: introduce ICmpInst::PredicateSign
Introduce CmpInst::PredicateSign, an abstraction over a floating-point predicate, and a pack of an integer predicate with samesign information, in order to ease extending large portions of the codebase that take a CmpInst::Predicate to respect the samesign flag. We have chosen to demonstrate the utility of this new abstraction by migrating ValueTracking, InstructionSimplify, and InstCombine from CmpInst::Predicate to CmpInst::PredicateSign. There should be no functional changes, as we don't perform any extra optimizations with samesign in this patch. The design approach taken by this patch allows for unaudited callers of APIs that take a CmpInst::PredicateSign to silently drop the samesign information; it does not pose a correctness issue, and allows us to migrate the codebase piece-wise.
1 parent cf32c5b commit f040f49

File tree

10 files changed

+129
-87
lines changed

10 files changed

+129
-87
lines changed

llvm/include/llvm/Analysis/InstructionSimplify.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,12 @@ Value *simplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
152152
Value *simplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
153153

154154
/// Given operands for an ICmpInst, fold the result or return null.
155-
Value *simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
155+
Value *simplifyICmpInst(CmpInst::PredicateSign Pred, Value *LHS, Value *RHS,
156156
const SimplifyQuery &Q);
157157

158158
/// Given operands for an FCmpInst, fold the result or return null.
159-
Value *simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
160-
FastMathFlags FMF, const SimplifyQuery &Q);
159+
Value *simplifyFCmpInst(CmpInst::PredicateSign Predicate, Value *LHS,
160+
Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q);
161161

162162
/// Given operands for a SelectInst, fold the result or return null.
163163
Value *simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
@@ -200,7 +200,7 @@ Value *simplifyShuffleVectorInst(Value *Op0, Value *Op1, ArrayRef<int> Mask,
200200
//=== Helper functions for higher up the class hierarchy.
201201

202202
/// Given operands for a CmpInst, fold the result or return null.
203-
Value *simplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
203+
Value *simplifyCmpInst(CmpInst::PredicateSign Predicate, Value *LHS, Value *RHS,
204204
const SimplifyQuery &Q);
205205

206206
/// Given operand for a UnaryOperator, fold the result or return null.

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,7 @@ std::optional<bool> isImpliedCondition(const Value *LHS, const Value *RHS,
12461246
bool LHSIsTrue = true,
12471247
unsigned Depth = 0);
12481248
std::optional<bool> isImpliedCondition(const Value *LHS,
1249-
CmpInst::Predicate RHSPred,
1249+
CmpInst::PredicateSign RHSPred,
12501250
const Value *RHSOp0, const Value *RHSOp1,
12511251
const DataLayout &DL,
12521252
bool LHSIsTrue = true,
@@ -1257,7 +1257,7 @@ std::optional<bool> isImpliedCondition(const Value *LHS,
12571257
std::optional<bool> isImpliedByDomCondition(const Value *Cond,
12581258
const Instruction *ContextI,
12591259
const DataLayout &DL);
1260-
std::optional<bool> isImpliedByDomCondition(CmpInst::Predicate Pred,
1260+
std::optional<bool> isImpliedByDomCondition(CmpInst::PredicateSign Pred,
12611261
const Value *LHS, const Value *RHS,
12621262
const Instruction *ContextI,
12631263
const DataLayout &DL);

llvm/include/llvm/IR/InstrTypes.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,31 @@ class CmpInst : public Instruction {
722722
force_iteration_on_noniterable_enum);
723723
}
724724

725+
/// An abstraction over a floating-point predicate, and a pack of an integer
726+
/// predicate with samesign information. The getPredicateSign() family of
727+
/// functions in ICmpInst construct and return this type. It is also implictly
728+
/// constructed with a Predicate, dropping samesign information.
729+
class PredicateSign {
730+
Predicate Pred;
731+
std::optional<bool> HasSameSign;
732+
733+
public:
734+
PredicateSign(Predicate Pred, bool HasSameSign)
735+
: Pred(Pred), HasSameSign(HasSameSign) {}
736+
737+
PredicateSign(Predicate Pred) : Pred(Pred) {
738+
if (isIntPredicate(Pred))
739+
HasSameSign = false;
740+
}
741+
742+
operator Predicate() { return Pred; }
743+
744+
bool hasSameSign() {
745+
assert(isIntPredicate(Pred) && HasSameSign);
746+
return *HasSameSign;
747+
}
748+
};
749+
725750
protected:
726751
CmpInst(Type *ty, Instruction::OtherOps op, Predicate pred, Value *LHS,
727752
Value *RHS, const Twine &Name = "",

llvm/include/llvm/IR/Instructions.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,18 @@ class ICmpInst: public CmpInst {
12031203
#endif
12041204
}
12051205

1206+
PredicateSign getPredicateSign() const {
1207+
return {getPredicate(), hasSameSign()};
1208+
}
1209+
1210+
PredicateSign getInversePredicateSign() const {
1211+
return {getInversePredicate(), hasSameSign()};
1212+
}
1213+
1214+
PredicateSign getSwappedPredicateSign() const {
1215+
return {getSwappedPredicate(), hasSameSign()};
1216+
}
1217+
12061218
void setSameSign(bool B = true) {
12071219
SubclassOptionalData = (SubclassOptionalData & ~SameSign) | (B * SameSign);
12081220
}

llvm/include/llvm/Transforms/InstCombine/InstCombiner.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
157157
/// conditional branch or select to create a compare with a canonical
158158
/// (inverted) predicate which is then more likely to be matched with other
159159
/// values.
160-
static bool isCanonicalPredicate(CmpInst::Predicate Pred) {
160+
static bool isCanonicalPredicate(CmpInst::PredicateSign Pred) {
161161
switch (Pred) {
162162
case CmpInst::ICMP_NE:
163163
case CmpInst::ICMP_ULE:
@@ -185,11 +185,12 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
185185
}
186186

187187
std::optional<std::pair<
188-
CmpInst::Predicate,
189-
Constant *>> static getFlippedStrictnessPredicateAndConstant(CmpInst::
190-
Predicate
191-
Pred,
192-
Constant *C);
188+
CmpInst::PredicateSign,
189+
Constant
190+
*>> static getFlippedStrictnessPredicateAndConstant(CmpInst::
191+
PredicateSign
192+
Pred,
193+
Constant *C);
193194

194195
static bool shouldAvoidAbsorbingNotIntoSelect(const SelectInst &SI) {
195196
// a ? b : false and a ? true : b are the canonical form of logical and/or.

0 commit comments

Comments
 (0)