1 //===- lib/CodeGen/GlobalISel/GISelKnownBits.cpp --------------*- C++ *-===//
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
7 //===----------------------------------------------------------------------===//
9 /// Provides analysis for querying information about KnownBits during GISel
12 //===------------------
13 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
14 #include "llvm/Analysis/ValueTracking.h"
15 #include "llvm/CodeGen/GlobalISel/Utils.h"
16 #include "llvm/CodeGen/MachineFrameInfo.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/CodeGen/TargetLowering.h"
19 #include "llvm/CodeGen/TargetOpcodes.h"
21 #define DEBUG_TYPE "gisel-known-bits"
25 char llvm::GISelKnownBitsAnalysis::ID
= 0;
27 INITIALIZE_PASS_BEGIN(GISelKnownBitsAnalysis
, DEBUG_TYPE
,
28 "Analysis for ComputingKnownBits", false, true)
29 INITIALIZE_PASS_END(GISelKnownBitsAnalysis
, DEBUG_TYPE
,
30 "Analysis for ComputingKnownBits", false, true)
32 GISelKnownBits::GISelKnownBits(MachineFunction
&MF
)
33 : MF(MF
), MRI(MF
.getRegInfo()), TL(*MF
.getSubtarget().getTargetLowering()),
34 DL(MF
.getFunction().getParent()->getDataLayout()) {}
36 unsigned GISelKnownBits::inferAlignmentForFrameIdx(int FrameIdx
, int Offset
,
37 const MachineFunction
&MF
) {
38 const MachineFrameInfo
&MFI
= MF
.getFrameInfo();
39 return MinAlign(Offset
, MFI
.getObjectAlignment(FrameIdx
));
40 // TODO: How to handle cases with Base + Offset?
43 unsigned GISelKnownBits::inferPtrAlignment(const MachineInstr
&MI
) {
44 if (MI
.getOpcode() == TargetOpcode::G_FRAME_INDEX
) {
45 int FrameIdx
= MI
.getOperand(1).getIndex();
46 return inferAlignmentForFrameIdx(FrameIdx
, 0, *MI
.getMF());
51 void GISelKnownBits::computeKnownBitsForFrameIndex(Register R
, KnownBits
&Known
,
52 const APInt
&DemandedElts
,
54 const MachineInstr
&MI
= *MRI
.getVRegDef(R
);
55 computeKnownBitsForAlignment(Known
, inferPtrAlignment(MI
));
58 void GISelKnownBits::computeKnownBitsForAlignment(KnownBits
&Known
,
61 // The low bits are known zero if the pointer is aligned.
62 Known
.Zero
.setLowBits(Log2_32(Align
));
65 KnownBits
GISelKnownBits::getKnownBits(MachineInstr
&MI
) {
66 return getKnownBits(MI
.getOperand(0).getReg());
69 KnownBits
GISelKnownBits::getKnownBits(Register R
) {
71 LLT Ty
= MRI
.getType(R
);
73 Ty
.isVector() ? APInt::getAllOnesValue(Ty
.getNumElements()) : APInt(1, 1);
74 computeKnownBitsImpl(R
, Known
, DemandedElts
);
78 APInt
GISelKnownBits::getKnownZeroes(Register R
) {
79 return getKnownBits(R
).Zero
;
82 APInt
GISelKnownBits::getKnownOnes(Register R
) { return getKnownBits(R
).One
; }
84 void GISelKnownBits::computeKnownBitsImpl(Register R
, KnownBits
&Known
,
85 const APInt
&DemandedElts
,
87 MachineInstr
&MI
= *MRI
.getVRegDef(R
);
88 unsigned Opcode
= MI
.getOpcode();
89 LLT DstTy
= MRI
.getType(R
);
91 unsigned BitWidth
= DstTy
.getSizeInBits();
92 Known
= KnownBits(BitWidth
); // Don't know anything
95 return; // TODO: Handle vectors.
97 if (Depth
== getMaxDepth())
101 return; // No demanded elts, better to assume we don't know anything.
107 TL
.computeKnownBitsForTargetInstr(R
, Known
, DemandedElts
, MRI
, Depth
);
109 case TargetOpcode::G_CONSTANT
: {
110 auto CstVal
= getConstantVRegVal(R
, MRI
);
112 Known
.Zero
= ~Known
.One
;
115 case TargetOpcode::G_FRAME_INDEX
: {
116 computeKnownBitsForFrameIndex(R
, Known
, DemandedElts
);
119 case TargetOpcode::G_SUB
: {
120 // If low bits are known to be zero in both operands, then we know they are
121 // going to be 0 in the result. Both addition and complement operations
122 // preserve the low zero bits.
123 computeKnownBitsImpl(MI
.getOperand(1).getReg(), Known2
, DemandedElts
,
125 unsigned KnownZeroLow
= Known2
.countMinTrailingZeros();
126 if (KnownZeroLow
== 0)
128 computeKnownBitsImpl(MI
.getOperand(2).getReg(), Known2
, DemandedElts
,
130 KnownZeroLow
= std::min(KnownZeroLow
, Known2
.countMinTrailingZeros());
131 Known
.Zero
.setLowBits(KnownZeroLow
);
134 case TargetOpcode::G_XOR
: {
135 computeKnownBitsImpl(MI
.getOperand(2).getReg(), Known
, DemandedElts
,
137 computeKnownBitsImpl(MI
.getOperand(1).getReg(), Known2
, DemandedElts
,
140 // Output known-0 bits are known if clear or set in both the LHS & RHS.
141 APInt KnownZeroOut
= (Known
.Zero
& Known2
.Zero
) | (Known
.One
& Known2
.One
);
142 // Output known-1 are known to be set if set in only one of the LHS, RHS.
143 Known
.One
= (Known
.Zero
& Known2
.One
) | (Known
.One
& Known2
.Zero
);
144 Known
.Zero
= KnownZeroOut
;
147 // G_GEP is like G_ADD. FIXME: Is this true for all targets?
148 case TargetOpcode::G_GEP
:
149 case TargetOpcode::G_ADD
: {
150 // Output known-0 bits are known if clear or set in both the low clear bits
151 // common to both LHS & RHS. For example, 8+(X<<3) is known to have the
153 // Output known-0 bits are also known if the top bits of each input are
154 // known to be clear. For example, if one input has the top 10 bits clear
155 // and the other has the top 8 bits clear, we know the top 7 bits of the
156 // output must be clear.
157 computeKnownBitsImpl(MI
.getOperand(1).getReg(), Known2
, DemandedElts
,
159 unsigned KnownZeroHigh
= Known2
.countMinLeadingZeros();
160 unsigned KnownZeroLow
= Known2
.countMinTrailingZeros();
161 computeKnownBitsImpl(MI
.getOperand(2).getReg(), Known2
, DemandedElts
,
163 KnownZeroHigh
= std::min(KnownZeroHigh
, Known2
.countMinLeadingZeros());
164 KnownZeroLow
= std::min(KnownZeroLow
, Known2
.countMinTrailingZeros());
165 Known
.Zero
.setLowBits(KnownZeroLow
);
166 if (KnownZeroHigh
> 1)
167 Known
.Zero
.setHighBits(KnownZeroHigh
- 1);
170 case TargetOpcode::G_AND
: {
171 // If either the LHS or the RHS are Zero, the result is zero.
172 computeKnownBitsImpl(MI
.getOperand(2).getReg(), Known
, DemandedElts
,
174 computeKnownBitsImpl(MI
.getOperand(1).getReg(), Known2
, DemandedElts
,
177 // Output known-1 bits are only known if set in both the LHS & RHS.
178 Known
.One
&= Known2
.One
;
179 // Output known-0 are known to be clear if zero in either the LHS | RHS.
180 Known
.Zero
|= Known2
.Zero
;
183 case TargetOpcode::G_OR
: {
184 // If either the LHS or the RHS are Zero, the result is zero.
185 computeKnownBitsImpl(MI
.getOperand(2).getReg(), Known
, DemandedElts
,
187 computeKnownBitsImpl(MI
.getOperand(1).getReg(), Known2
, DemandedElts
,
190 // Output known-0 bits are only known if clear in both the LHS & RHS.
191 Known
.Zero
&= Known2
.Zero
;
192 // Output known-1 are known to be set if set in either the LHS | RHS.
193 Known
.One
|= Known2
.One
;
196 case TargetOpcode::G_MUL
: {
197 computeKnownBitsImpl(MI
.getOperand(2).getReg(), Known
, DemandedElts
,
199 computeKnownBitsImpl(MI
.getOperand(1).getReg(), Known2
, DemandedElts
,
201 // If low bits are zero in either operand, output low known-0 bits.
202 // Also compute a conservative estimate for high known-0 bits.
203 // More trickiness is possible, but this is sufficient for the
204 // interesting case of alignment computation.
206 Known
.countMinTrailingZeros() + Known2
.countMinTrailingZeros();
208 std::max(Known
.countMinLeadingZeros() + Known2
.countMinLeadingZeros(),
213 Known
.Zero
.setLowBits(std::min(TrailZ
, BitWidth
));
214 Known
.Zero
.setHighBits(std::min(LeadZ
, BitWidth
));
217 case TargetOpcode::G_SELECT
: {
218 computeKnownBitsImpl(MI
.getOperand(3).getReg(), Known
, DemandedElts
,
220 // If we don't know any bits, early out.
221 if (Known
.isUnknown())
223 computeKnownBitsImpl(MI
.getOperand(2).getReg(), Known2
, DemandedElts
,
225 // Only known if known in both the LHS and RHS.
226 Known
.One
&= Known2
.One
;
227 Known
.Zero
&= Known2
.Zero
;
230 case TargetOpcode::G_FCMP
:
231 case TargetOpcode::G_ICMP
: {
232 if (TL
.getBooleanContents(DstTy
.isVector(),
233 Opcode
== TargetOpcode::G_FCMP
) ==
234 TargetLowering::ZeroOrOneBooleanContent
&&
236 Known
.Zero
.setBitsFrom(1);
239 case TargetOpcode::G_SEXT
: {
240 computeKnownBitsImpl(MI
.getOperand(1).getReg(), Known
, DemandedElts
,
242 // If the sign bit is known to be zero or one, then sext will extend
243 // it to the top bits, else it will just zext.
244 Known
= Known
.sext(BitWidth
);
247 case TargetOpcode::G_ANYEXT
: {
248 computeKnownBitsImpl(MI
.getOperand(1).getReg(), Known
, DemandedElts
,
250 Known
= Known
.zext(BitWidth
, true /* ExtendedBitsAreKnownZero */);
253 case TargetOpcode::G_LOAD
: {
254 if (MI
.hasOneMemOperand()) {
255 const MachineMemOperand
*MMO
= *MI
.memoperands_begin();
256 if (const MDNode
*Ranges
= MMO
->getRanges()) {
257 computeKnownBitsFromRangeMetadata(*Ranges
, Known
);
262 case TargetOpcode::G_ZEXTLOAD
: {
263 // Everything above the retrieved bits is zero
264 if (MI
.hasOneMemOperand())
265 Known
.Zero
.setBitsFrom((*MI
.memoperands_begin())->getSizeInBits());
268 case TargetOpcode::G_ASHR
:
269 case TargetOpcode::G_LSHR
:
270 case TargetOpcode::G_SHL
: {
272 computeKnownBitsImpl(MI
.getOperand(2).getReg(), RHSKnown
, DemandedElts
,
274 if (!RHSKnown
.isConstant()) {
276 MachineInstr
*RHSMI
= MRI
.getVRegDef(MI
.getOperand(2).getReg());
277 dbgs() << '[' << Depth
<< "] Shift not known constant: " << *RHSMI
);
280 uint64_t Shift
= RHSKnown
.getConstant().getZExtValue();
281 LLVM_DEBUG(dbgs() << '[' << Depth
<< "] Shift is " << Shift
<< '\n');
283 computeKnownBitsImpl(MI
.getOperand(1).getReg(), Known
, DemandedElts
,
287 case TargetOpcode::G_ASHR
:
288 Known
.Zero
= Known
.Zero
.ashr(Shift
);
289 Known
.One
= Known
.One
.ashr(Shift
);
291 case TargetOpcode::G_LSHR
:
292 Known
.Zero
= Known
.Zero
.lshr(Shift
);
293 Known
.One
= Known
.One
.lshr(Shift
);
294 Known
.Zero
.setBitsFrom(Known
.Zero
.getBitWidth() - Shift
);
296 case TargetOpcode::G_SHL
:
297 Known
.Zero
= Known
.Zero
.shl(Shift
);
298 Known
.One
= Known
.One
.shl(Shift
);
299 Known
.Zero
.setBits(0, Shift
);
304 case TargetOpcode::G_INTTOPTR
:
305 case TargetOpcode::G_PTRTOINT
:
306 // Fall through and handle them the same as zext/trunc.
308 case TargetOpcode::G_ZEXT
:
309 case TargetOpcode::G_TRUNC
: {
310 Register SrcReg
= MI
.getOperand(1).getReg();
311 LLT SrcTy
= MRI
.getType(SrcReg
);
312 unsigned SrcBitWidth
= SrcTy
.isPointer()
313 ? DL
.getIndexSizeInBits(SrcTy
.getAddressSpace())
314 : SrcTy
.getSizeInBits();
315 assert(SrcBitWidth
&& "SrcBitWidth can't be zero");
316 Known
= Known
.zextOrTrunc(SrcBitWidth
, true);
317 computeKnownBitsImpl(SrcReg
, Known
, DemandedElts
, Depth
+ 1);
318 Known
= Known
.zextOrTrunc(BitWidth
, true);
319 if (BitWidth
> SrcBitWidth
)
320 Known
.Zero
.setBitsFrom(SrcBitWidth
);
325 assert(!Known
.hasConflict() && "Bits known to be one AND zero?");
326 LLVM_DEBUG(dbgs() << "[" << Depth
<< "] Compute known bits: " << MI
<< "["
327 << Depth
<< "] Computed for: " << MI
<< "[" << Depth
329 << (Known
.Zero
| Known
.One
).toString(16, false) << "\n"
330 << "[" << Depth
<< "] Zero: 0x"
331 << Known
.Zero
.toString(16, false) << "\n"
332 << "[" << Depth
<< "] One: 0x"
333 << Known
.One
.toString(16, false) << "\n");
336 void GISelKnownBitsAnalysis::getAnalysisUsage(AnalysisUsage
&AU
) const {
337 AU
.setPreservesAll();
338 MachineFunctionPass::getAnalysisUsage(AU
);
341 bool GISelKnownBitsAnalysis::runOnMachineFunction(MachineFunction
&MF
) {