Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Analysis/CmpInstAnalysis.cpp
35234 views
1
//===- CmpInstAnalysis.cpp - Utils to help fold compares ---------------===//
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
// This file holds routines to help analyse compare instructions
10
// and fold them into constants or other compare instructions
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "llvm/Analysis/CmpInstAnalysis.h"
15
#include "llvm/IR/Constants.h"
16
#include "llvm/IR/Instructions.h"
17
#include "llvm/IR/PatternMatch.h"
18
19
using namespace llvm;
20
21
unsigned llvm::getICmpCode(CmpInst::Predicate Pred) {
22
switch (Pred) {
23
// False -> 0
24
case ICmpInst::ICMP_UGT: return 1; // 001
25
case ICmpInst::ICMP_SGT: return 1; // 001
26
case ICmpInst::ICMP_EQ: return 2; // 010
27
case ICmpInst::ICMP_UGE: return 3; // 011
28
case ICmpInst::ICMP_SGE: return 3; // 011
29
case ICmpInst::ICMP_ULT: return 4; // 100
30
case ICmpInst::ICMP_SLT: return 4; // 100
31
case ICmpInst::ICMP_NE: return 5; // 101
32
case ICmpInst::ICMP_ULE: return 6; // 110
33
case ICmpInst::ICMP_SLE: return 6; // 110
34
// True -> 7
35
default:
36
llvm_unreachable("Invalid ICmp predicate!");
37
}
38
}
39
40
Constant *llvm::getPredForICmpCode(unsigned Code, bool Sign, Type *OpTy,
41
CmpInst::Predicate &Pred) {
42
switch (Code) {
43
default: llvm_unreachable("Illegal ICmp code!");
44
case 0: // False.
45
return ConstantInt::get(CmpInst::makeCmpResultType(OpTy), 0);
46
case 1: Pred = Sign ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break;
47
case 2: Pred = ICmpInst::ICMP_EQ; break;
48
case 3: Pred = Sign ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break;
49
case 4: Pred = Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break;
50
case 5: Pred = ICmpInst::ICMP_NE; break;
51
case 6: Pred = Sign ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break;
52
case 7: // True.
53
return ConstantInt::get(CmpInst::makeCmpResultType(OpTy), 1);
54
}
55
return nullptr;
56
}
57
58
bool llvm::predicatesFoldable(ICmpInst::Predicate P1, ICmpInst::Predicate P2) {
59
return (CmpInst::isSigned(P1) == CmpInst::isSigned(P2)) ||
60
(CmpInst::isSigned(P1) && ICmpInst::isEquality(P2)) ||
61
(CmpInst::isSigned(P2) && ICmpInst::isEquality(P1));
62
}
63
64
Constant *llvm::getPredForFCmpCode(unsigned Code, Type *OpTy,
65
CmpInst::Predicate &Pred) {
66
Pred = static_cast<FCmpInst::Predicate>(Code);
67
assert(FCmpInst::FCMP_FALSE <= Pred && Pred <= FCmpInst::FCMP_TRUE &&
68
"Unexpected FCmp predicate!");
69
if (Pred == FCmpInst::FCMP_FALSE)
70
return ConstantInt::get(CmpInst::makeCmpResultType(OpTy), 0);
71
if (Pred == FCmpInst::FCMP_TRUE)
72
return ConstantInt::get(CmpInst::makeCmpResultType(OpTy), 1);
73
return nullptr;
74
}
75
76
bool llvm::decomposeBitTestICmp(Value *LHS, Value *RHS,
77
CmpInst::Predicate &Pred,
78
Value *&X, APInt &Mask, bool LookThruTrunc) {
79
using namespace PatternMatch;
80
81
const APInt *C;
82
if (!match(RHS, m_APIntAllowPoison(C)))
83
return false;
84
85
switch (Pred) {
86
default:
87
return false;
88
case ICmpInst::ICMP_SLT:
89
// X < 0 is equivalent to (X & SignMask) != 0.
90
if (!C->isZero())
91
return false;
92
Mask = APInt::getSignMask(C->getBitWidth());
93
Pred = ICmpInst::ICMP_NE;
94
break;
95
case ICmpInst::ICMP_SLE:
96
// X <= -1 is equivalent to (X & SignMask) != 0.
97
if (!C->isAllOnes())
98
return false;
99
Mask = APInt::getSignMask(C->getBitWidth());
100
Pred = ICmpInst::ICMP_NE;
101
break;
102
case ICmpInst::ICMP_SGT:
103
// X > -1 is equivalent to (X & SignMask) == 0.
104
if (!C->isAllOnes())
105
return false;
106
Mask = APInt::getSignMask(C->getBitWidth());
107
Pred = ICmpInst::ICMP_EQ;
108
break;
109
case ICmpInst::ICMP_SGE:
110
// X >= 0 is equivalent to (X & SignMask) == 0.
111
if (!C->isZero())
112
return false;
113
Mask = APInt::getSignMask(C->getBitWidth());
114
Pred = ICmpInst::ICMP_EQ;
115
break;
116
case ICmpInst::ICMP_ULT:
117
// X <u 2^n is equivalent to (X & ~(2^n-1)) == 0.
118
if (!C->isPowerOf2())
119
return false;
120
Mask = -*C;
121
Pred = ICmpInst::ICMP_EQ;
122
break;
123
case ICmpInst::ICMP_ULE:
124
// X <=u 2^n-1 is equivalent to (X & ~(2^n-1)) == 0.
125
if (!(*C + 1).isPowerOf2())
126
return false;
127
Mask = ~*C;
128
Pred = ICmpInst::ICMP_EQ;
129
break;
130
case ICmpInst::ICMP_UGT:
131
// X >u 2^n-1 is equivalent to (X & ~(2^n-1)) != 0.
132
if (!(*C + 1).isPowerOf2())
133
return false;
134
Mask = ~*C;
135
Pred = ICmpInst::ICMP_NE;
136
break;
137
case ICmpInst::ICMP_UGE:
138
// X >=u 2^n is equivalent to (X & ~(2^n-1)) != 0.
139
if (!C->isPowerOf2())
140
return false;
141
Mask = -*C;
142
Pred = ICmpInst::ICMP_NE;
143
break;
144
}
145
146
if (LookThruTrunc && match(LHS, m_Trunc(m_Value(X)))) {
147
Mask = Mask.zext(X->getType()->getScalarSizeInBits());
148
} else {
149
X = LHS;
150
}
151
152
return true;
153
}
154
155