Skip to content

Commit 51a895a

Browse files
authored
IR: introduce struct with CmpInst::Predicate and samesign (#116867)
Introduce llvm::CmpPredicate, 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 parts of ValueTracking, InstructionSimplify, and InstCombine from CmpInst::Predicate to llvm::CmpPredicate. There should be no functional changes, as we don't perform any extra optimizations with samesign in this patch, or use CmpPredicate::getMatching. The design approach taken by this patch allows for unaudited callers of APIs that take a llvm::CmpPredicate to silently drop the samesign information; it does not pose a correctness issue, and allows us to migrate the codebase piece-wise.
1 parent f335364 commit 51a895a

File tree

13 files changed

+228
-111
lines changed

13 files changed

+228
-111
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)