Skip to content

Commit 94cc891

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 bfb2620 commit 94cc891

File tree

13 files changed

+227
-110
lines changed

13 files changed

+227
-110
lines changed

llvm/include/llvm/Analysis/InstSimplifyFolder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/ADT/ArrayRef.h"
2323
#include "llvm/Analysis/InstructionSimplify.h"
2424
#include "llvm/Analysis/TargetFolder.h"
25+
#include "llvm/IR/CmpPredicate.h"
2526
#include "llvm/IR/IRBuilderFolder.h"
2627
#include "llvm/IR/Instruction.h"
2728

llvm/include/llvm/Analysis/InstructionSimplify.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class DataLayout;
4444
class DominatorTree;
4545
class Function;
4646
class Instruction;
47+
class CmpPredicate;
4748
class LoadInst;
4849
struct LoopStandardAnalysisResults;
4950
class Pass;
@@ -152,11 +153,11 @@ Value *simplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
152153
Value *simplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
153154

154155
/// Given operands for an ICmpInst, fold the result or return null.
155-
Value *simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
156+
Value *simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS,
156157
const SimplifyQuery &Q);
157158

158159
/// Given operands for an FCmpInst, fold the result or return null.
159-
Value *simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
160+
Value *simplifyFCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS,
160161
FastMathFlags FMF, const SimplifyQuery &Q);
161162

162163
/// Given operands for a SelectInst, fold the result or return null.
@@ -200,7 +201,7 @@ Value *simplifyShuffleVectorInst(Value *Op0, Value *Op1, ArrayRef<int> Mask,
200201
//=== Helper functions for higher up the class hierarchy.
201202

202203
/// Given operands for a CmpInst, fold the result or return null.
203-
Value *simplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
204+
Value *simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS,
204205
const SimplifyQuery &Q);
205206

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

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,8 +1255,7 @@ std::optional<bool> isImpliedCondition(const Value *LHS, const Value *RHS,
12551255
const DataLayout &DL,
12561256
bool LHSIsTrue = true,
12571257
unsigned Depth = 0);
1258-
std::optional<bool> isImpliedCondition(const Value *LHS,
1259-
CmpInst::Predicate RHSPred,
1258+
std::optional<bool> isImpliedCondition(const Value *LHS, CmpPredicate RHSPred,
12601259
const Value *RHSOp0, const Value *RHSOp1,
12611260
const DataLayout &DL,
12621261
bool LHSIsTrue = true,
@@ -1267,8 +1266,8 @@ std::optional<bool> isImpliedCondition(const Value *LHS,
12671266
std::optional<bool> isImpliedByDomCondition(const Value *Cond,
12681267
const Instruction *ContextI,
12691268
const DataLayout &DL);
1270-
std::optional<bool> isImpliedByDomCondition(CmpInst::Predicate Pred,
1271-
const Value *LHS, const Value *RHS,
1269+
std::optional<bool> isImpliedByDomCondition(CmpPredicate Pred, const Value *LHS,
1270+
const Value *RHS,
12721271
const Instruction *ContextI,
12731272
const DataLayout &DL);
12741273

llvm/include/llvm/IR/CmpPredicate.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//===- CmpPredicate.h - CmpInst Predicate with samesign information -------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// A CmpInst::Predicate with any samesign information (applicable to ICmpInst).
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_IR_CMPPREDICATE_H
14+
#define LLVM_IR_CMPPREDICATE_H
15+
16+
#include "llvm/IR/InstrTypes.h"
17+
18+
namespace llvm {
19+
/// An abstraction over a floating-point predicate, and a pack of an integer
20+
/// predicate with samesign information. Some functions in ICmpInst construct
21+
/// and return this type in place of a Predicate.
22+
class CmpPredicate {
23+
CmpInst::Predicate Pred;
24+
bool HasSameSign;
25+
26+
public:
27+
// Constructed implictly with a either Predicate and samesign information, or
28+
// just a Predicate, dropping samesign information.
29+
CmpPredicate(CmpInst::Predicate Pred, bool HasSameSign = false)
30+
: Pred(Pred), HasSameSign(HasSameSign) {
31+
assert(!HasSameSign || CmpInst::isIntPredicate(Pred));
32+
}
33+
34+
// Implictly converts to the underlying Predicate, dropping samesign
35+
// information.
36+
operator CmpInst::Predicate() const { return Pred; }
37+
38+
// Query samesign information, for optimizations.
39+
bool hasSameSign() const { return HasSameSign; }
40+
41+
// Compares two CmpPredicates taking samesign into account and returns the
42+
// canonicalized CmpPredicate if they match. An alternative to operator==.
43+
//
44+
// For example,
45+
// samesign ult + samesign ult -> samesign ult
46+
// samesign ult + ult -> ult
47+
// samesign ult + slt -> slt
48+
// ult + ult -> ult
49+
// ult + slt -> std::nullopt
50+
static std::optional<CmpPredicate> getMatching(CmpPredicate A,
51+
CmpPredicate B);
52+
53+
// An operator== on the underlying Predicate.
54+
bool operator==(CmpInst::Predicate P) const { return Pred == P; }
55+
56+
// There is no operator== defined on CmpPredicate. Use getMatching instead to
57+
// get the canonicalized matching CmpPredicate.
58+
bool operator==(CmpPredicate) const = delete;
59+
};
60+
} // namespace llvm
61+
62+
#endif

llvm/include/llvm/IR/Instructions.h

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "llvm/ADT/iterator.h"
2525
#include "llvm/ADT/iterator_range.h"
2626
#include "llvm/IR/CFG.h"
27+
#include "llvm/IR/CmpPredicate.h"
2728
#include "llvm/IR/Constant.h"
2829
#include "llvm/IR/DerivedTypes.h"
2930
#include "llvm/IR/GEPNoWrapFlags.h"
@@ -1203,6 +1204,33 @@ class ICmpInst: public CmpInst {
12031204
#endif
12041205
}
12051206

1207+
/// @returns the predicate along with samesign information.
1208+
CmpPredicate getCmpPredicate() const {
1209+
return {getPredicate(), hasSameSign()};
1210+
}
1211+
1212+
/// @returns the inverse predicate along with samesign information: static
1213+
/// variant.
1214+
static CmpPredicate getInverseCmpPredicate(CmpPredicate Pred) {
1215+
return {getInversePredicate(Pred), Pred.hasSameSign()};
1216+
}
1217+
1218+
/// @returns the inverse predicate along with samesign information.
1219+
CmpPredicate getInverseCmpPredicate() const {
1220+
return getInverseCmpPredicate(getCmpPredicate());
1221+
}
1222+
1223+
/// @returns the swapped predicate along with samesign information: static
1224+
/// variant.
1225+
static CmpPredicate getSwappedCmpPredicate(CmpPredicate Pred) {
1226+
return {getSwappedPredicate(Pred), Pred.hasSameSign()};
1227+
}
1228+
1229+
/// @returns the swapped predicate.
1230+
Predicate getSwappedCmpPredicate() const {
1231+
return getSwappedPredicate(getCmpPredicate());
1232+
}
1233+
12061234
/// For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
12071235
/// @returns the predicate that would be the result if the operand were
12081236
/// regarded as signed.
@@ -1212,7 +1240,7 @@ class ICmpInst: public CmpInst {
12121240
}
12131241

12141242
/// Return the signed version of the predicate: static variant.
1215-
static Predicate getSignedPredicate(Predicate pred);
1243+
static Predicate getSignedPredicate(Predicate Pred);
12161244

12171245
/// For example, EQ->EQ, SLE->ULE, UGT->UGT, etc.
12181246
/// @returns the predicate that would be the result if the operand were
@@ -1223,14 +1251,15 @@ class ICmpInst: public CmpInst {
12231251
}
12241252

12251253
/// Return the unsigned version of the predicate: static variant.
1226-
static Predicate getUnsignedPredicate(Predicate pred);
1254+
static Predicate getUnsignedPredicate(Predicate Pred);
12271255

1228-
/// For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->Failed assert
1256+
/// For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->EQ
12291257
/// @returns the unsigned version of the signed predicate pred or
12301258
/// the signed version of the signed predicate pred.
1231-
static Predicate getFlippedSignednessPredicate(Predicate pred);
1259+
/// Static variant.
1260+
static Predicate getFlippedSignednessPredicate(Predicate Pred);
12321261

1233-
/// For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->Failed assert
1262+
/// For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->EQ
12341263
/// @returns the unsigned version of the signed predicate pred or
12351264
/// the signed version of the signed predicate pred.
12361265
Predicate getFlippedSignednessPredicate() const {

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

Lines changed: 4 additions & 5 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(CmpPredicate Pred) {
161161
switch (Pred) {
162162
case CmpInst::ICMP_NE:
163163
case CmpInst::ICMP_ULE:
@@ -185,10 +185,9 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
185185
}
186186

187187
std::optional<std::pair<
188-
CmpInst::Predicate,
189-
Constant *>> static getFlippedStrictnessPredicateAndConstant(CmpInst::
190-
Predicate
191-
Pred,
188+
CmpPredicate,
189+
Constant *>> static getFlippedStrictnessPredicateAndConstant(CmpPredicate
190+
Pred,
192191
Constant *C);
193192

194193
static bool shouldAvoidAbsorbingNotIntoSelect(const SelectInst &SI) {

0 commit comments

Comments
 (0)