Bug Summary

File:build/source/llvm/include/llvm/ADT/APInt.h
Warning:line 169, column 7
Attempt to free released memory

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name CombinerHelper.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/source/build-llvm -resource-dir /usr/lib/llvm-17/lib/clang/17 -I lib/CodeGen/GlobalISel -I /build/source/llvm/lib/CodeGen/GlobalISel -I include -I /build/source/llvm/include -D _DEBUG -D _GLIBCXX_ASSERTIONS -D _GNU_SOURCE -D _LIBCPP_ENABLE_ASSERTIONS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-17/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/source/build-llvm=build-llvm -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm=build-llvm -fcoverage-prefix-map=/build/source/= -O3 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-misleading-indentation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/source/build-llvm -fdebug-prefix-map=/build/source/build-llvm=build-llvm -fdebug-prefix-map=/build/source/= -fdebug-prefix-map=/build/source/build-llvm=build-llvm -fdebug-prefix-map=/build/source/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2023-05-10-133810-16478-1 -x c++ /build/source/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

/build/source/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

1//===-- lib/CodeGen/GlobalISel/GICombinerHelper.cpp -----------------------===//
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#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
9#include "llvm/ADT/SetVector.h"
10#include "llvm/ADT/SmallBitVector.h"
11#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
12#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
13#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
14#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
15#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
16#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
17#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
18#include "llvm/CodeGen/GlobalISel/Utils.h"
19#include "llvm/CodeGen/LowLevelTypeUtils.h"
20#include "llvm/CodeGen/MachineBasicBlock.h"
21#include "llvm/CodeGen/MachineDominators.h"
22#include "llvm/CodeGen/MachineInstr.h"
23#include "llvm/CodeGen/MachineMemOperand.h"
24#include "llvm/CodeGen/MachineRegisterInfo.h"
25#include "llvm/CodeGen/RegisterBankInfo.h"
26#include "llvm/CodeGen/TargetInstrInfo.h"
27#include "llvm/CodeGen/TargetLowering.h"
28#include "llvm/CodeGen/TargetOpcodes.h"
29#include "llvm/IR/DataLayout.h"
30#include "llvm/IR/InstrTypes.h"
31#include "llvm/Support/Casting.h"
32#include "llvm/Support/DivisionByConstantInfo.h"
33#include "llvm/Support/MathExtras.h"
34#include "llvm/Target/TargetMachine.h"
35#include <cmath>
36#include <optional>
37#include <tuple>
38
39#define DEBUG_TYPE"gi-combiner" "gi-combiner"
40
41using namespace llvm;
42using namespace MIPatternMatch;
43
44// Option to allow testing of the combiner while no targets know about indexed
45// addressing.
46static cl::opt<bool>
47 ForceLegalIndexing("force-legal-indexing", cl::Hidden, cl::init(false),
48 cl::desc("Force all indexed operations to be "
49 "legal for the GlobalISel combiner"));
50
51CombinerHelper::CombinerHelper(GISelChangeObserver &Observer,
52 MachineIRBuilder &B, bool IsPreLegalize,
53 GISelKnownBits *KB, MachineDominatorTree *MDT,
54 const LegalizerInfo *LI)
55 : Builder(B), MRI(Builder.getMF().getRegInfo()), Observer(Observer), KB(KB),
56 MDT(MDT), IsPreLegalize(IsPreLegalize), LI(LI),
57 RBI(Builder.getMF().getSubtarget().getRegBankInfo()),
58 TRI(Builder.getMF().getSubtarget().getRegisterInfo()) {
59 (void)this->KB;
60}
61
62const TargetLowering &CombinerHelper::getTargetLowering() const {
63 return *Builder.getMF().getSubtarget().getTargetLowering();
64}
65
66/// \returns The little endian in-memory byte position of byte \p I in a
67/// \p ByteWidth bytes wide type.
68///
69/// E.g. Given a 4-byte type x, x[0] -> byte 0
70static unsigned littleEndianByteAt(const unsigned ByteWidth, const unsigned I) {
71 assert(I < ByteWidth && "I must be in [0, ByteWidth)")(static_cast <bool> (I < ByteWidth && "I must be in [0, ByteWidth)"
) ? void (0) : __assert_fail ("I < ByteWidth && \"I must be in [0, ByteWidth)\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 71, __extension__
__PRETTY_FUNCTION__))
;
72 return I;
73}
74
75/// Determines the LogBase2 value for a non-null input value using the
76/// transform: LogBase2(V) = (EltBits - 1) - ctlz(V).
77static Register buildLogBase2(Register V, MachineIRBuilder &MIB) {
78 auto &MRI = *MIB.getMRI();
79 LLT Ty = MRI.getType(V);
80 auto Ctlz = MIB.buildCTLZ(Ty, V);
81 auto Base = MIB.buildConstant(Ty, Ty.getScalarSizeInBits() - 1);
82 return MIB.buildSub(Ty, Base, Ctlz).getReg(0);
83}
84
85/// \returns The big endian in-memory byte position of byte \p I in a
86/// \p ByteWidth bytes wide type.
87///
88/// E.g. Given a 4-byte type x, x[0] -> byte 3
89static unsigned bigEndianByteAt(const unsigned ByteWidth, const unsigned I) {
90 assert(I < ByteWidth && "I must be in [0, ByteWidth)")(static_cast <bool> (I < ByteWidth && "I must be in [0, ByteWidth)"
) ? void (0) : __assert_fail ("I < ByteWidth && \"I must be in [0, ByteWidth)\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 90, __extension__
__PRETTY_FUNCTION__))
;
91 return ByteWidth - I - 1;
92}
93
94/// Given a map from byte offsets in memory to indices in a load/store,
95/// determine if that map corresponds to a little or big endian byte pattern.
96///
97/// \param MemOffset2Idx maps memory offsets to address offsets.
98/// \param LowestIdx is the lowest index in \p MemOffset2Idx.
99///
100/// \returns true if the map corresponds to a big endian byte pattern, false if
101/// it corresponds to a little endian byte pattern, and std::nullopt otherwise.
102///
103/// E.g. given a 32-bit type x, and x[AddrOffset], the in-memory byte patterns
104/// are as follows:
105///
106/// AddrOffset Little endian Big endian
107/// 0 0 3
108/// 1 1 2
109/// 2 2 1
110/// 3 3 0
111static std::optional<bool>
112isBigEndian(const SmallDenseMap<int64_t, int64_t, 8> &MemOffset2Idx,
113 int64_t LowestIdx) {
114 // Need at least two byte positions to decide on endianness.
115 unsigned Width = MemOffset2Idx.size();
116 if (Width < 2)
117 return std::nullopt;
118 bool BigEndian = true, LittleEndian = true;
119 for (unsigned MemOffset = 0; MemOffset < Width; ++ MemOffset) {
120 auto MemOffsetAndIdx = MemOffset2Idx.find(MemOffset);
121 if (MemOffsetAndIdx == MemOffset2Idx.end())
122 return std::nullopt;
123 const int64_t Idx = MemOffsetAndIdx->second - LowestIdx;
124 assert(Idx >= 0 && "Expected non-negative byte offset?")(static_cast <bool> (Idx >= 0 && "Expected non-negative byte offset?"
) ? void (0) : __assert_fail ("Idx >= 0 && \"Expected non-negative byte offset?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 124, __extension__
__PRETTY_FUNCTION__))
;
125 LittleEndian &= Idx == littleEndianByteAt(Width, MemOffset);
126 BigEndian &= Idx == bigEndianByteAt(Width, MemOffset);
127 if (!BigEndian && !LittleEndian)
128 return std::nullopt;
129 }
130
131 assert((BigEndian != LittleEndian) &&(static_cast <bool> ((BigEndian != LittleEndian) &&
"Pattern cannot be both big and little endian!") ? void (0) :
__assert_fail ("(BigEndian != LittleEndian) && \"Pattern cannot be both big and little endian!\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 132, __extension__
__PRETTY_FUNCTION__))
132 "Pattern cannot be both big and little endian!")(static_cast <bool> ((BigEndian != LittleEndian) &&
"Pattern cannot be both big and little endian!") ? void (0) :
__assert_fail ("(BigEndian != LittleEndian) && \"Pattern cannot be both big and little endian!\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 132, __extension__
__PRETTY_FUNCTION__))
;
133 return BigEndian;
134}
135
136bool CombinerHelper::isPreLegalize() const { return IsPreLegalize; }
137
138bool CombinerHelper::isLegal(const LegalityQuery &Query) const {
139 assert(LI && "Must have LegalizerInfo to query isLegal!")(static_cast <bool> (LI && "Must have LegalizerInfo to query isLegal!"
) ? void (0) : __assert_fail ("LI && \"Must have LegalizerInfo to query isLegal!\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 139, __extension__
__PRETTY_FUNCTION__))
;
140 return LI->getAction(Query).Action == LegalizeActions::Legal;
141}
142
143bool CombinerHelper::isLegalOrBeforeLegalizer(
144 const LegalityQuery &Query) const {
145 return isPreLegalize() || isLegal(Query);
146}
147
148bool CombinerHelper::isConstantLegalOrBeforeLegalizer(const LLT Ty) const {
149 if (!Ty.isVector())
150 return isLegalOrBeforeLegalizer({TargetOpcode::G_CONSTANT, {Ty}});
151 // Vector constants are represented as a G_BUILD_VECTOR of scalar G_CONSTANTs.
152 if (isPreLegalize())
153 return true;
154 LLT EltTy = Ty.getElementType();
155 return isLegal({TargetOpcode::G_BUILD_VECTOR, {Ty, EltTy}}) &&
156 isLegal({TargetOpcode::G_CONSTANT, {EltTy}});
157}
158
159void CombinerHelper::replaceRegWith(MachineRegisterInfo &MRI, Register FromReg,
160 Register ToReg) const {
161 Observer.changingAllUsesOfReg(MRI, FromReg);
162
163 if (MRI.constrainRegAttrs(ToReg, FromReg))
164 MRI.replaceRegWith(FromReg, ToReg);
165 else
166 Builder.buildCopy(ToReg, FromReg);
167
168 Observer.finishedChangingAllUsesOfReg();
169}
170
171void CombinerHelper::replaceRegOpWith(MachineRegisterInfo &MRI,
172 MachineOperand &FromRegOp,
173 Register ToReg) const {
174 assert(FromRegOp.getParent() && "Expected an operand in an MI")(static_cast <bool> (FromRegOp.getParent() && "Expected an operand in an MI"
) ? void (0) : __assert_fail ("FromRegOp.getParent() && \"Expected an operand in an MI\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 174, __extension__
__PRETTY_FUNCTION__))
;
175 Observer.changingInstr(*FromRegOp.getParent());
176
177 FromRegOp.setReg(ToReg);
178
179 Observer.changedInstr(*FromRegOp.getParent());
180}
181
182void CombinerHelper::replaceOpcodeWith(MachineInstr &FromMI,
183 unsigned ToOpcode) const {
184 Observer.changingInstr(FromMI);
185
186 FromMI.setDesc(Builder.getTII().get(ToOpcode));
187
188 Observer.changedInstr(FromMI);
189}
190
191const RegisterBank *CombinerHelper::getRegBank(Register Reg) const {
192 return RBI->getRegBank(Reg, MRI, *TRI);
193}
194
195void CombinerHelper::setRegBank(Register Reg, const RegisterBank *RegBank) {
196 if (RegBank)
197 MRI.setRegBank(Reg, *RegBank);
198}
199
200bool CombinerHelper::tryCombineCopy(MachineInstr &MI) {
201 if (matchCombineCopy(MI)) {
202 applyCombineCopy(MI);
203 return true;
204 }
205 return false;
206}
207bool CombinerHelper::matchCombineCopy(MachineInstr &MI) {
208 if (MI.getOpcode() != TargetOpcode::COPY)
209 return false;
210 Register DstReg = MI.getOperand(0).getReg();
211 Register SrcReg = MI.getOperand(1).getReg();
212 return canReplaceReg(DstReg, SrcReg, MRI);
213}
214void CombinerHelper::applyCombineCopy(MachineInstr &MI) {
215 Register DstReg = MI.getOperand(0).getReg();
216 Register SrcReg = MI.getOperand(1).getReg();
217 MI.eraseFromParent();
218 replaceRegWith(MRI, DstReg, SrcReg);
219}
220
221bool CombinerHelper::tryCombineConcatVectors(MachineInstr &MI) {
222 bool IsUndef = false;
223 SmallVector<Register, 4> Ops;
224 if (matchCombineConcatVectors(MI, IsUndef, Ops)) {
225 applyCombineConcatVectors(MI, IsUndef, Ops);
226 return true;
227 }
228 return false;
229}
230
231bool CombinerHelper::matchCombineConcatVectors(MachineInstr &MI, bool &IsUndef,
232 SmallVectorImpl<Register> &Ops) {
233 assert(MI.getOpcode() == TargetOpcode::G_CONCAT_VECTORS &&(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_CONCAT_VECTORS
&& "Invalid instruction") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_CONCAT_VECTORS && \"Invalid instruction\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 234, __extension__
__PRETTY_FUNCTION__))
234 "Invalid instruction")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_CONCAT_VECTORS
&& "Invalid instruction") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_CONCAT_VECTORS && \"Invalid instruction\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 234, __extension__
__PRETTY_FUNCTION__))
;
235 IsUndef = true;
236 MachineInstr *Undef = nullptr;
237
238 // Walk over all the operands of concat vectors and check if they are
239 // build_vector themselves or undef.
240 // Then collect their operands in Ops.
241 for (const MachineOperand &MO : MI.uses()) {
242 Register Reg = MO.getReg();
243 MachineInstr *Def = MRI.getVRegDef(Reg);
244 assert(Def && "Operand not defined")(static_cast <bool> (Def && "Operand not defined"
) ? void (0) : __assert_fail ("Def && \"Operand not defined\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 244, __extension__
__PRETTY_FUNCTION__))
;
245 switch (Def->getOpcode()) {
246 case TargetOpcode::G_BUILD_VECTOR:
247 IsUndef = false;
248 // Remember the operands of the build_vector to fold
249 // them into the yet-to-build flattened concat vectors.
250 for (const MachineOperand &BuildVecMO : Def->uses())
251 Ops.push_back(BuildVecMO.getReg());
252 break;
253 case TargetOpcode::G_IMPLICIT_DEF: {
254 LLT OpType = MRI.getType(Reg);
255 // Keep one undef value for all the undef operands.
256 if (!Undef) {
257 Builder.setInsertPt(*MI.getParent(), MI);
258 Undef = Builder.buildUndef(OpType.getScalarType());
259 }
260 assert(MRI.getType(Undef->getOperand(0).getReg()) ==(static_cast <bool> (MRI.getType(Undef->getOperand(0
).getReg()) == OpType.getScalarType() && "All undefs should have the same type"
) ? void (0) : __assert_fail ("MRI.getType(Undef->getOperand(0).getReg()) == OpType.getScalarType() && \"All undefs should have the same type\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 262, __extension__
__PRETTY_FUNCTION__))
261 OpType.getScalarType() &&(static_cast <bool> (MRI.getType(Undef->getOperand(0
).getReg()) == OpType.getScalarType() && "All undefs should have the same type"
) ? void (0) : __assert_fail ("MRI.getType(Undef->getOperand(0).getReg()) == OpType.getScalarType() && \"All undefs should have the same type\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 262, __extension__
__PRETTY_FUNCTION__))
262 "All undefs should have the same type")(static_cast <bool> (MRI.getType(Undef->getOperand(0
).getReg()) == OpType.getScalarType() && "All undefs should have the same type"
) ? void (0) : __assert_fail ("MRI.getType(Undef->getOperand(0).getReg()) == OpType.getScalarType() && \"All undefs should have the same type\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 262, __extension__
__PRETTY_FUNCTION__))
;
263 // Break the undef vector in as many scalar elements as needed
264 // for the flattening.
265 for (unsigned EltIdx = 0, EltEnd = OpType.getNumElements();
266 EltIdx != EltEnd; ++EltIdx)
267 Ops.push_back(Undef->getOperand(0).getReg());
268 break;
269 }
270 default:
271 return false;
272 }
273 }
274 return true;
275}
276void CombinerHelper::applyCombineConcatVectors(
277 MachineInstr &MI, bool IsUndef, const ArrayRef<Register> Ops) {
278 // We determined that the concat_vectors can be flatten.
279 // Generate the flattened build_vector.
280 Register DstReg = MI.getOperand(0).getReg();
281 Builder.setInsertPt(*MI.getParent(), MI);
282 Register NewDstReg = MRI.cloneVirtualRegister(DstReg);
283
284 // Note: IsUndef is sort of redundant. We could have determine it by
285 // checking that at all Ops are undef. Alternatively, we could have
286 // generate a build_vector of undefs and rely on another combine to
287 // clean that up. For now, given we already gather this information
288 // in tryCombineConcatVectors, just save compile time and issue the
289 // right thing.
290 if (IsUndef)
291 Builder.buildUndef(NewDstReg);
292 else
293 Builder.buildBuildVector(NewDstReg, Ops);
294 MI.eraseFromParent();
295 replaceRegWith(MRI, DstReg, NewDstReg);
296}
297
298bool CombinerHelper::tryCombineShuffleVector(MachineInstr &MI) {
299 SmallVector<Register, 4> Ops;
300 if (matchCombineShuffleVector(MI, Ops)) {
301 applyCombineShuffleVector(MI, Ops);
302 return true;
303 }
304 return false;
305}
306
307bool CombinerHelper::matchCombineShuffleVector(MachineInstr &MI,
308 SmallVectorImpl<Register> &Ops) {
309 assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR &&(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR
&& "Invalid instruction kind") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR && \"Invalid instruction kind\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 310, __extension__
__PRETTY_FUNCTION__))
310 "Invalid instruction kind")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR
&& "Invalid instruction kind") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR && \"Invalid instruction kind\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 310, __extension__
__PRETTY_FUNCTION__))
;
311 LLT DstType = MRI.getType(MI.getOperand(0).getReg());
312 Register Src1 = MI.getOperand(1).getReg();
313 LLT SrcType = MRI.getType(Src1);
314 // As bizarre as it may look, shuffle vector can actually produce
315 // scalar! This is because at the IR level a <1 x ty> shuffle
316 // vector is perfectly valid.
317 unsigned DstNumElts = DstType.isVector() ? DstType.getNumElements() : 1;
318 unsigned SrcNumElts = SrcType.isVector() ? SrcType.getNumElements() : 1;
319
320 // If the resulting vector is smaller than the size of the source
321 // vectors being concatenated, we won't be able to replace the
322 // shuffle vector into a concat_vectors.
323 //
324 // Note: We may still be able to produce a concat_vectors fed by
325 // extract_vector_elt and so on. It is less clear that would
326 // be better though, so don't bother for now.
327 //
328 // If the destination is a scalar, the size of the sources doesn't
329 // matter. we will lower the shuffle to a plain copy. This will
330 // work only if the source and destination have the same size. But
331 // that's covered by the next condition.
332 //
333 // TODO: If the size between the source and destination don't match
334 // we could still emit an extract vector element in that case.
335 if (DstNumElts < 2 * SrcNumElts && DstNumElts != 1)
336 return false;
337
338 // Check that the shuffle mask can be broken evenly between the
339 // different sources.
340 if (DstNumElts % SrcNumElts != 0)
341 return false;
342
343 // Mask length is a multiple of the source vector length.
344 // Check if the shuffle is some kind of concatenation of the input
345 // vectors.
346 unsigned NumConcat = DstNumElts / SrcNumElts;
347 SmallVector<int, 8> ConcatSrcs(NumConcat, -1);
348 ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
349 for (unsigned i = 0; i != DstNumElts; ++i) {
350 int Idx = Mask[i];
351 // Undef value.
352 if (Idx < 0)
353 continue;
354 // Ensure the indices in each SrcType sized piece are sequential and that
355 // the same source is used for the whole piece.
356 if ((Idx % SrcNumElts != (i % SrcNumElts)) ||
357 (ConcatSrcs[i / SrcNumElts] >= 0 &&
358 ConcatSrcs[i / SrcNumElts] != (int)(Idx / SrcNumElts)))
359 return false;
360 // Remember which source this index came from.
361 ConcatSrcs[i / SrcNumElts] = Idx / SrcNumElts;
362 }
363
364 // The shuffle is concatenating multiple vectors together.
365 // Collect the different operands for that.
366 Register UndefReg;
367 Register Src2 = MI.getOperand(2).getReg();
368 for (auto Src : ConcatSrcs) {
369 if (Src < 0) {
370 if (!UndefReg) {
371 Builder.setInsertPt(*MI.getParent(), MI);
372 UndefReg = Builder.buildUndef(SrcType).getReg(0);
373 }
374 Ops.push_back(UndefReg);
375 } else if (Src == 0)
376 Ops.push_back(Src1);
377 else
378 Ops.push_back(Src2);
379 }
380 return true;
381}
382
383void CombinerHelper::applyCombineShuffleVector(MachineInstr &MI,
384 const ArrayRef<Register> Ops) {
385 Register DstReg = MI.getOperand(0).getReg();
386 Builder.setInsertPt(*MI.getParent(), MI);
387 Register NewDstReg = MRI.cloneVirtualRegister(DstReg);
388
389 if (Ops.size() == 1)
390 Builder.buildCopy(NewDstReg, Ops[0]);
391 else
392 Builder.buildMergeLikeInstr(NewDstReg, Ops);
393
394 MI.eraseFromParent();
395 replaceRegWith(MRI, DstReg, NewDstReg);
396}
397
398namespace {
399
400/// Select a preference between two uses. CurrentUse is the current preference
401/// while *ForCandidate is attributes of the candidate under consideration.
402PreferredTuple ChoosePreferredUse(MachineInstr &LoadMI,
403 PreferredTuple &CurrentUse,
404 const LLT TyForCandidate,
405 unsigned OpcodeForCandidate,
406 MachineInstr *MIForCandidate) {
407 if (!CurrentUse.Ty.isValid()) {
408 if (CurrentUse.ExtendOpcode == OpcodeForCandidate ||
409 CurrentUse.ExtendOpcode == TargetOpcode::G_ANYEXT)
410 return {TyForCandidate, OpcodeForCandidate, MIForCandidate};
411 return CurrentUse;
412 }
413
414 // We permit the extend to hoist through basic blocks but this is only
415 // sensible if the target has extending loads. If you end up lowering back
416 // into a load and extend during the legalizer then the end result is
417 // hoisting the extend up to the load.
418
419 // Prefer defined extensions to undefined extensions as these are more
420 // likely to reduce the number of instructions.
421 if (OpcodeForCandidate == TargetOpcode::G_ANYEXT &&
422 CurrentUse.ExtendOpcode != TargetOpcode::G_ANYEXT)
423 return CurrentUse;
424 else if (CurrentUse.ExtendOpcode == TargetOpcode::G_ANYEXT &&
425 OpcodeForCandidate != TargetOpcode::G_ANYEXT)
426 return {TyForCandidate, OpcodeForCandidate, MIForCandidate};
427
428 // Prefer sign extensions to zero extensions as sign-extensions tend to be
429 // more expensive. Don't do this if the load is already a zero-extend load
430 // though, otherwise we'll rewrite a zero-extend load into a sign-extend
431 // later.
432 if (!isa<GZExtLoad>(LoadMI) && CurrentUse.Ty == TyForCandidate) {
433 if (CurrentUse.ExtendOpcode == TargetOpcode::G_SEXT &&
434 OpcodeForCandidate == TargetOpcode::G_ZEXT)
435 return CurrentUse;
436 else if (CurrentUse.ExtendOpcode == TargetOpcode::G_ZEXT &&
437 OpcodeForCandidate == TargetOpcode::G_SEXT)
438 return {TyForCandidate, OpcodeForCandidate, MIForCandidate};
439 }
440
441 // This is potentially target specific. We've chosen the largest type
442 // because G_TRUNC is usually free. One potential catch with this is that
443 // some targets have a reduced number of larger registers than smaller
444 // registers and this choice potentially increases the live-range for the
445 // larger value.
446 if (TyForCandidate.getSizeInBits() > CurrentUse.Ty.getSizeInBits()) {
447 return {TyForCandidate, OpcodeForCandidate, MIForCandidate};
448 }
449 return CurrentUse;
450}
451
452/// Find a suitable place to insert some instructions and insert them. This
453/// function accounts for special cases like inserting before a PHI node.
454/// The current strategy for inserting before PHI's is to duplicate the
455/// instructions for each predecessor. However, while that's ok for G_TRUNC
456/// on most targets since it generally requires no code, other targets/cases may
457/// want to try harder to find a dominating block.
458static void InsertInsnsWithoutSideEffectsBeforeUse(
459 MachineIRBuilder &Builder, MachineInstr &DefMI, MachineOperand &UseMO,
460 std::function<void(MachineBasicBlock *, MachineBasicBlock::iterator,
461 MachineOperand &UseMO)>
462 Inserter) {
463 MachineInstr &UseMI = *UseMO.getParent();
464
465 MachineBasicBlock *InsertBB = UseMI.getParent();
466
467 // If the use is a PHI then we want the predecessor block instead.
468 if (UseMI.isPHI()) {
469 MachineOperand *PredBB = std::next(&UseMO);
470 InsertBB = PredBB->getMBB();
471 }
472
473 // If the block is the same block as the def then we want to insert just after
474 // the def instead of at the start of the block.
475 if (InsertBB == DefMI.getParent()) {
476 MachineBasicBlock::iterator InsertPt = &DefMI;
477 Inserter(InsertBB, std::next(InsertPt), UseMO);
478 return;
479 }
480
481 // Otherwise we want the start of the BB
482 Inserter(InsertBB, InsertBB->getFirstNonPHI(), UseMO);
483}
484} // end anonymous namespace
485
486bool CombinerHelper::tryCombineExtendingLoads(MachineInstr &MI) {
487 PreferredTuple Preferred;
488 if (matchCombineExtendingLoads(MI, Preferred)) {
489 applyCombineExtendingLoads(MI, Preferred);
490 return true;
491 }
492 return false;
493}
494
495static unsigned getExtLoadOpcForExtend(unsigned ExtOpc) {
496 unsigned CandidateLoadOpc;
497 switch (ExtOpc) {
498 case TargetOpcode::G_ANYEXT:
499 CandidateLoadOpc = TargetOpcode::G_LOAD;
500 break;
501 case TargetOpcode::G_SEXT:
502 CandidateLoadOpc = TargetOpcode::G_SEXTLOAD;
503 break;
504 case TargetOpcode::G_ZEXT:
505 CandidateLoadOpc = TargetOpcode::G_ZEXTLOAD;
506 break;
507 default:
508 llvm_unreachable("Unexpected extend opc")::llvm::llvm_unreachable_internal("Unexpected extend opc", "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp"
, 508)
;
509 }
510 return CandidateLoadOpc;
511}
512
513bool CombinerHelper::matchCombineExtendingLoads(MachineInstr &MI,
514 PreferredTuple &Preferred) {
515 // We match the loads and follow the uses to the extend instead of matching
516 // the extends and following the def to the load. This is because the load
517 // must remain in the same position for correctness (unless we also add code
518 // to find a safe place to sink it) whereas the extend is freely movable.
519 // It also prevents us from duplicating the load for the volatile case or just
520 // for performance.
521 GAnyLoad *LoadMI = dyn_cast<GAnyLoad>(&MI);
522 if (!LoadMI)
523 return false;
524
525 Register LoadReg = LoadMI->getDstReg();
526
527 LLT LoadValueTy = MRI.getType(LoadReg);
528 if (!LoadValueTy.isScalar())
529 return false;
530
531 // Most architectures are going to legalize <s8 loads into at least a 1 byte
532 // load, and the MMOs can only describe memory accesses in multiples of bytes.
533 // If we try to perform extload combining on those, we can end up with
534 // %a(s8) = extload %ptr (load 1 byte from %ptr)
535 // ... which is an illegal extload instruction.
536 if (LoadValueTy.getSizeInBits() < 8)
537 return false;
538
539 // For non power-of-2 types, they will very likely be legalized into multiple
540 // loads. Don't bother trying to match them into extending loads.
541 if (!llvm::has_single_bit<uint32_t>(LoadValueTy.getSizeInBits()))
542 return false;
543
544 // Find the preferred type aside from the any-extends (unless it's the only
545 // one) and non-extending ops. We'll emit an extending load to that type and
546 // and emit a variant of (extend (trunc X)) for the others according to the
547 // relative type sizes. At the same time, pick an extend to use based on the
548 // extend involved in the chosen type.
549 unsigned PreferredOpcode =
550 isa<GLoad>(&MI)
551 ? TargetOpcode::G_ANYEXT
552 : isa<GSExtLoad>(&MI) ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT;
553 Preferred = {LLT(), PreferredOpcode, nullptr};
554 for (auto &UseMI : MRI.use_nodbg_instructions(LoadReg)) {
555 if (UseMI.getOpcode() == TargetOpcode::G_SEXT ||
556 UseMI.getOpcode() == TargetOpcode::G_ZEXT ||
557 (UseMI.getOpcode() == TargetOpcode::G_ANYEXT)) {
558 const auto &MMO = LoadMI->getMMO();
559 // For atomics, only form anyextending loads.
560 if (MMO.isAtomic() && UseMI.getOpcode() != TargetOpcode::G_ANYEXT)
561 continue;
562 // Check for legality.
563 if (!isPreLegalize()) {
564 LegalityQuery::MemDesc MMDesc(MMO);
565 unsigned CandidateLoadOpc = getExtLoadOpcForExtend(UseMI.getOpcode());
566 LLT UseTy = MRI.getType(UseMI.getOperand(0).getReg());
567 LLT SrcTy = MRI.getType(LoadMI->getPointerReg());
568 if (LI->getAction({CandidateLoadOpc, {UseTy, SrcTy}, {MMDesc}})
569 .Action != LegalizeActions::Legal)
570 continue;
571 }
572 Preferred = ChoosePreferredUse(MI, Preferred,
573 MRI.getType(UseMI.getOperand(0).getReg()),
574 UseMI.getOpcode(), &UseMI);
575 }
576 }
577
578 // There were no extends
579 if (!Preferred.MI)
580 return false;
581 // It should be impossible to chose an extend without selecting a different
582 // type since by definition the result of an extend is larger.
583 assert(Preferred.Ty != LoadValueTy && "Extending to same type?")(static_cast <bool> (Preferred.Ty != LoadValueTy &&
"Extending to same type?") ? void (0) : __assert_fail ("Preferred.Ty != LoadValueTy && \"Extending to same type?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 583, __extension__
__PRETTY_FUNCTION__))
;
584
585 LLVM_DEBUG(dbgs() << "Preferred use is: " << *Preferred.MI)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << "Preferred use is: " <<
*Preferred.MI; } } while (false)
;
586 return true;
587}
588
589void CombinerHelper::applyCombineExtendingLoads(MachineInstr &MI,
590 PreferredTuple &Preferred) {
591 // Rewrite the load to the chosen extending load.
592 Register ChosenDstReg = Preferred.MI->getOperand(0).getReg();
593
594 // Inserter to insert a truncate back to the original type at a given point
595 // with some basic CSE to limit truncate duplication to one per BB.
596 DenseMap<MachineBasicBlock *, MachineInstr *> EmittedInsns;
597 auto InsertTruncAt = [&](MachineBasicBlock *InsertIntoBB,
598 MachineBasicBlock::iterator InsertBefore,
599 MachineOperand &UseMO) {
600 MachineInstr *PreviouslyEmitted = EmittedInsns.lookup(InsertIntoBB);
601 if (PreviouslyEmitted) {
602 Observer.changingInstr(*UseMO.getParent());
603 UseMO.setReg(PreviouslyEmitted->getOperand(0).getReg());
604 Observer.changedInstr(*UseMO.getParent());
605 return;
606 }
607
608 Builder.setInsertPt(*InsertIntoBB, InsertBefore);
609 Register NewDstReg = MRI.cloneVirtualRegister(MI.getOperand(0).getReg());
610 MachineInstr *NewMI = Builder.buildTrunc(NewDstReg, ChosenDstReg);
611 EmittedInsns[InsertIntoBB] = NewMI;
612 replaceRegOpWith(MRI, UseMO, NewDstReg);
613 };
614
615 Observer.changingInstr(MI);
616 unsigned LoadOpc = getExtLoadOpcForExtend(Preferred.ExtendOpcode);
617 MI.setDesc(Builder.getTII().get(LoadOpc));
618
619 // Rewrite all the uses to fix up the types.
620 auto &LoadValue = MI.getOperand(0);
621 SmallVector<MachineOperand *, 4> Uses;
622 for (auto &UseMO : MRI.use_operands(LoadValue.getReg()))
623 Uses.push_back(&UseMO);
624
625 for (auto *UseMO : Uses) {
626 MachineInstr *UseMI = UseMO->getParent();
627
628 // If the extend is compatible with the preferred extend then we should fix
629 // up the type and extend so that it uses the preferred use.
630 if (UseMI->getOpcode() == Preferred.ExtendOpcode ||
631 UseMI->getOpcode() == TargetOpcode::G_ANYEXT) {
632 Register UseDstReg = UseMI->getOperand(0).getReg();
633 MachineOperand &UseSrcMO = UseMI->getOperand(1);
634 const LLT UseDstTy = MRI.getType(UseDstReg);
635 if (UseDstReg != ChosenDstReg) {
636 if (Preferred.Ty == UseDstTy) {
637 // If the use has the same type as the preferred use, then merge
638 // the vregs and erase the extend. For example:
639 // %1:_(s8) = G_LOAD ...
640 // %2:_(s32) = G_SEXT %1(s8)
641 // %3:_(s32) = G_ANYEXT %1(s8)
642 // ... = ... %3(s32)
643 // rewrites to:
644 // %2:_(s32) = G_SEXTLOAD ...
645 // ... = ... %2(s32)
646 replaceRegWith(MRI, UseDstReg, ChosenDstReg);
647 Observer.erasingInstr(*UseMO->getParent());
648 UseMO->getParent()->eraseFromParent();
649 } else if (Preferred.Ty.getSizeInBits() < UseDstTy.getSizeInBits()) {
650 // If the preferred size is smaller, then keep the extend but extend
651 // from the result of the extending load. For example:
652 // %1:_(s8) = G_LOAD ...
653 // %2:_(s32) = G_SEXT %1(s8)
654 // %3:_(s64) = G_ANYEXT %1(s8)
655 // ... = ... %3(s64)
656 /// rewrites to:
657 // %2:_(s32) = G_SEXTLOAD ...
658 // %3:_(s64) = G_ANYEXT %2:_(s32)
659 // ... = ... %3(s64)
660 replaceRegOpWith(MRI, UseSrcMO, ChosenDstReg);
661 } else {
662 // If the preferred size is large, then insert a truncate. For
663 // example:
664 // %1:_(s8) = G_LOAD ...
665 // %2:_(s64) = G_SEXT %1(s8)
666 // %3:_(s32) = G_ZEXT %1(s8)
667 // ... = ... %3(s32)
668 /// rewrites to:
669 // %2:_(s64) = G_SEXTLOAD ...
670 // %4:_(s8) = G_TRUNC %2:_(s32)
671 // %3:_(s64) = G_ZEXT %2:_(s8)
672 // ... = ... %3(s64)
673 InsertInsnsWithoutSideEffectsBeforeUse(Builder, MI, *UseMO,
674 InsertTruncAt);
675 }
676 continue;
677 }
678 // The use is (one of) the uses of the preferred use we chose earlier.
679 // We're going to update the load to def this value later so just erase
680 // the old extend.
681 Observer.erasingInstr(*UseMO->getParent());
682 UseMO->getParent()->eraseFromParent();
683 continue;
684 }
685
686 // The use isn't an extend. Truncate back to the type we originally loaded.
687 // This is free on many targets.
688 InsertInsnsWithoutSideEffectsBeforeUse(Builder, MI, *UseMO, InsertTruncAt);
689 }
690
691 MI.getOperand(0).setReg(ChosenDstReg);
692 Observer.changedInstr(MI);
693}
694
695bool CombinerHelper::matchCombineLoadWithAndMask(MachineInstr &MI,
696 BuildFnTy &MatchInfo) {
697 assert(MI.getOpcode() == TargetOpcode::G_AND)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_AND
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_AND"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 697, __extension__
__PRETTY_FUNCTION__))
;
698
699 // If we have the following code:
700 // %mask = G_CONSTANT 255
701 // %ld = G_LOAD %ptr, (load s16)
702 // %and = G_AND %ld, %mask
703 //
704 // Try to fold it into
705 // %ld = G_ZEXTLOAD %ptr, (load s8)
706
707 Register Dst = MI.getOperand(0).getReg();
708 if (MRI.getType(Dst).isVector())
709 return false;
710
711 auto MaybeMask =
712 getIConstantVRegValWithLookThrough(MI.getOperand(2).getReg(), MRI);
713 if (!MaybeMask)
714 return false;
715
716 APInt MaskVal = MaybeMask->Value;
717
718 if (!MaskVal.isMask())
719 return false;
720
721 Register SrcReg = MI.getOperand(1).getReg();
722 // Don't use getOpcodeDef() here since intermediate instructions may have
723 // multiple users.
724 GAnyLoad *LoadMI = dyn_cast<GAnyLoad>(MRI.getVRegDef(SrcReg));
725 if (!LoadMI || !MRI.hasOneNonDBGUse(LoadMI->getDstReg()))
726 return false;
727
728 Register LoadReg = LoadMI->getDstReg();
729 LLT RegTy = MRI.getType(LoadReg);
730 Register PtrReg = LoadMI->getPointerReg();
731 unsigned RegSize = RegTy.getSizeInBits();
732 uint64_t LoadSizeBits = LoadMI->getMemSizeInBits();
733 unsigned MaskSizeBits = MaskVal.countr_one();
734
735 // The mask may not be larger than the in-memory type, as it might cover sign
736 // extended bits
737 if (MaskSizeBits > LoadSizeBits)
738 return false;
739
740 // If the mask covers the whole destination register, there's nothing to
741 // extend
742 if (MaskSizeBits >= RegSize)
743 return false;
744
745 // Most targets cannot deal with loads of size < 8 and need to re-legalize to
746 // at least byte loads. Avoid creating such loads here
747 if (MaskSizeBits < 8 || !isPowerOf2_32(MaskSizeBits))
748 return false;
749
750 const MachineMemOperand &MMO = LoadMI->getMMO();
751 LegalityQuery::MemDesc MemDesc(MMO);
752
753 // Don't modify the memory access size if this is atomic/volatile, but we can
754 // still adjust the opcode to indicate the high bit behavior.
755 if (LoadMI->isSimple())
756 MemDesc.MemoryTy = LLT::scalar(MaskSizeBits);
757 else if (LoadSizeBits > MaskSizeBits || LoadSizeBits == RegSize)
758 return false;
759
760 // TODO: Could check if it's legal with the reduced or original memory size.
761 if (!isLegalOrBeforeLegalizer(
762 {TargetOpcode::G_ZEXTLOAD, {RegTy, MRI.getType(PtrReg)}, {MemDesc}}))
763 return false;
764
765 MatchInfo = [=](MachineIRBuilder &B) {
766 B.setInstrAndDebugLoc(*LoadMI);
767 auto &MF = B.getMF();
768 auto PtrInfo = MMO.getPointerInfo();
769 auto *NewMMO = MF.getMachineMemOperand(&MMO, PtrInfo, MemDesc.MemoryTy);
770 B.buildLoadInstr(TargetOpcode::G_ZEXTLOAD, Dst, PtrReg, *NewMMO);
771 LoadMI->eraseFromParent();
772 };
773 return true;
774}
775
776bool CombinerHelper::isPredecessor(const MachineInstr &DefMI,
777 const MachineInstr &UseMI) {
778 assert(!DefMI.isDebugInstr() && !UseMI.isDebugInstr() &&(static_cast <bool> (!DefMI.isDebugInstr() && !
UseMI.isDebugInstr() && "shouldn't consider debug uses"
) ? void (0) : __assert_fail ("!DefMI.isDebugInstr() && !UseMI.isDebugInstr() && \"shouldn't consider debug uses\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 779, __extension__
__PRETTY_FUNCTION__))
779 "shouldn't consider debug uses")(static_cast <bool> (!DefMI.isDebugInstr() && !
UseMI.isDebugInstr() && "shouldn't consider debug uses"
) ? void (0) : __assert_fail ("!DefMI.isDebugInstr() && !UseMI.isDebugInstr() && \"shouldn't consider debug uses\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 779, __extension__
__PRETTY_FUNCTION__))
;
780 assert(DefMI.getParent() == UseMI.getParent())(static_cast <bool> (DefMI.getParent() == UseMI.getParent
()) ? void (0) : __assert_fail ("DefMI.getParent() == UseMI.getParent()"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 780, __extension__
__PRETTY_FUNCTION__))
;
781 if (&DefMI == &UseMI)
782 return true;
783 const MachineBasicBlock &MBB = *DefMI.getParent();
784 auto DefOrUse = find_if(MBB, [&DefMI, &UseMI](const MachineInstr &MI) {
785 return &MI == &DefMI || &MI == &UseMI;
786 });
787 if (DefOrUse == MBB.end())
788 llvm_unreachable("Block must contain both DefMI and UseMI!")::llvm::llvm_unreachable_internal("Block must contain both DefMI and UseMI!"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 788)
;
789 return &*DefOrUse == &DefMI;
790}
791
792bool CombinerHelper::dominates(const MachineInstr &DefMI,
793 const MachineInstr &UseMI) {
794 assert(!DefMI.isDebugInstr() && !UseMI.isDebugInstr() &&(static_cast <bool> (!DefMI.isDebugInstr() && !
UseMI.isDebugInstr() && "shouldn't consider debug uses"
) ? void (0) : __assert_fail ("!DefMI.isDebugInstr() && !UseMI.isDebugInstr() && \"shouldn't consider debug uses\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 795, __extension__
__PRETTY_FUNCTION__))
795 "shouldn't consider debug uses")(static_cast <bool> (!DefMI.isDebugInstr() && !
UseMI.isDebugInstr() && "shouldn't consider debug uses"
) ? void (0) : __assert_fail ("!DefMI.isDebugInstr() && !UseMI.isDebugInstr() && \"shouldn't consider debug uses\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 795, __extension__
__PRETTY_FUNCTION__))
;
796 if (MDT)
797 return MDT->dominates(&DefMI, &UseMI);
798 else if (DefMI.getParent() != UseMI.getParent())
799 return false;
800
801 return isPredecessor(DefMI, UseMI);
802}
803
804bool CombinerHelper::matchSextTruncSextLoad(MachineInstr &MI) {
805 assert(MI.getOpcode() == TargetOpcode::G_SEXT_INREG)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SEXT_INREG
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_SEXT_INREG"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 805, __extension__
__PRETTY_FUNCTION__))
;
806 Register SrcReg = MI.getOperand(1).getReg();
807 Register LoadUser = SrcReg;
808
809 if (MRI.getType(SrcReg).isVector())
810 return false;
811
812 Register TruncSrc;
813 if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc))))
814 LoadUser = TruncSrc;
815
816 uint64_t SizeInBits = MI.getOperand(2).getImm();
817 // If the source is a G_SEXTLOAD from the same bit width, then we don't
818 // need any extend at all, just a truncate.
819 if (auto *LoadMI = getOpcodeDef<GSExtLoad>(LoadUser, MRI)) {
820 // If truncating more than the original extended value, abort.
821 auto LoadSizeBits = LoadMI->getMemSizeInBits();
822 if (TruncSrc && MRI.getType(TruncSrc).getSizeInBits() < LoadSizeBits)
823 return false;
824 if (LoadSizeBits == SizeInBits)
825 return true;
826 }
827 return false;
828}
829
830void CombinerHelper::applySextTruncSextLoad(MachineInstr &MI) {
831 assert(MI.getOpcode() == TargetOpcode::G_SEXT_INREG)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SEXT_INREG
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_SEXT_INREG"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 831, __extension__
__PRETTY_FUNCTION__))
;
832 Builder.setInstrAndDebugLoc(MI);
833 Builder.buildCopy(MI.getOperand(0).getReg(), MI.getOperand(1).getReg());
834 MI.eraseFromParent();
835}
836
837bool CombinerHelper::matchSextInRegOfLoad(
838 MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo) {
839 assert(MI.getOpcode() == TargetOpcode::G_SEXT_INREG)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SEXT_INREG
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_SEXT_INREG"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 839, __extension__
__PRETTY_FUNCTION__))
;
840
841 Register DstReg = MI.getOperand(0).getReg();
842 LLT RegTy = MRI.getType(DstReg);
843
844 // Only supports scalars for now.
845 if (RegTy.isVector())
846 return false;
847
848 Register SrcReg = MI.getOperand(1).getReg();
849 auto *LoadDef = getOpcodeDef<GLoad>(SrcReg, MRI);
850 if (!LoadDef || !MRI.hasOneNonDBGUse(DstReg))
851 return false;
852
853 uint64_t MemBits = LoadDef->getMemSizeInBits();
854
855 // If the sign extend extends from a narrower width than the load's width,
856 // then we can narrow the load width when we combine to a G_SEXTLOAD.
857 // Avoid widening the load at all.
858 unsigned NewSizeBits = std::min((uint64_t)MI.getOperand(2).getImm(), MemBits);
859
860 // Don't generate G_SEXTLOADs with a < 1 byte width.
861 if (NewSizeBits < 8)
862 return false;
863 // Don't bother creating a non-power-2 sextload, it will likely be broken up
864 // anyway for most targets.
865 if (!isPowerOf2_32(NewSizeBits))
866 return false;
867
868 const MachineMemOperand &MMO = LoadDef->getMMO();
869 LegalityQuery::MemDesc MMDesc(MMO);
870
871 // Don't modify the memory access size if this is atomic/volatile, but we can
872 // still adjust the opcode to indicate the high bit behavior.
873 if (LoadDef->isSimple())
874 MMDesc.MemoryTy = LLT::scalar(NewSizeBits);
875 else if (MemBits > NewSizeBits || MemBits == RegTy.getSizeInBits())
876 return false;
877
878 // TODO: Could check if it's legal with the reduced or original memory size.
879 if (!isLegalOrBeforeLegalizer({TargetOpcode::G_SEXTLOAD,
880 {MRI.getType(LoadDef->getDstReg()),
881 MRI.getType(LoadDef->getPointerReg())},
882 {MMDesc}}))
883 return false;
884
885 MatchInfo = std::make_tuple(LoadDef->getDstReg(), NewSizeBits);
886 return true;
887}
888
889void CombinerHelper::applySextInRegOfLoad(
890 MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo) {
891 assert(MI.getOpcode() == TargetOpcode::G_SEXT_INREG)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SEXT_INREG
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_SEXT_INREG"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 891, __extension__
__PRETTY_FUNCTION__))
;
892 Register LoadReg;
893 unsigned ScalarSizeBits;
894 std::tie(LoadReg, ScalarSizeBits) = MatchInfo;
895 GLoad *LoadDef = cast<GLoad>(MRI.getVRegDef(LoadReg));
896
897 // If we have the following:
898 // %ld = G_LOAD %ptr, (load 2)
899 // %ext = G_SEXT_INREG %ld, 8
900 // ==>
901 // %ld = G_SEXTLOAD %ptr (load 1)
902
903 auto &MMO = LoadDef->getMMO();
904 Builder.setInstrAndDebugLoc(*LoadDef);
905 auto &MF = Builder.getMF();
906 auto PtrInfo = MMO.getPointerInfo();
907 auto *NewMMO = MF.getMachineMemOperand(&MMO, PtrInfo, ScalarSizeBits / 8);
908 Builder.buildLoadInstr(TargetOpcode::G_SEXTLOAD, MI.getOperand(0).getReg(),
909 LoadDef->getPointerReg(), *NewMMO);
910 MI.eraseFromParent();
911}
912
913bool CombinerHelper::findPostIndexCandidate(MachineInstr &MI, Register &Addr,
914 Register &Base, Register &Offset) {
915 auto &MF = *MI.getParent()->getParent();
916 const auto &TLI = *MF.getSubtarget().getTargetLowering();
917
918#ifndef NDEBUG
919 unsigned Opcode = MI.getOpcode();
920 assert(Opcode == TargetOpcode::G_LOAD || Opcode == TargetOpcode::G_SEXTLOAD ||(static_cast <bool> (Opcode == TargetOpcode::G_LOAD || Opcode
== TargetOpcode::G_SEXTLOAD || Opcode == TargetOpcode::G_ZEXTLOAD
|| Opcode == TargetOpcode::G_STORE) ? void (0) : __assert_fail
("Opcode == TargetOpcode::G_LOAD || Opcode == TargetOpcode::G_SEXTLOAD || Opcode == TargetOpcode::G_ZEXTLOAD || Opcode == TargetOpcode::G_STORE"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 921, __extension__
__PRETTY_FUNCTION__))
921 Opcode == TargetOpcode::G_ZEXTLOAD || Opcode == TargetOpcode::G_STORE)(static_cast <bool> (Opcode == TargetOpcode::G_LOAD || Opcode
== TargetOpcode::G_SEXTLOAD || Opcode == TargetOpcode::G_ZEXTLOAD
|| Opcode == TargetOpcode::G_STORE) ? void (0) : __assert_fail
("Opcode == TargetOpcode::G_LOAD || Opcode == TargetOpcode::G_SEXTLOAD || Opcode == TargetOpcode::G_ZEXTLOAD || Opcode == TargetOpcode::G_STORE"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 921, __extension__
__PRETTY_FUNCTION__))
;
922#endif
923
924 Base = MI.getOperand(1).getReg();
925 MachineInstr *BaseDef = MRI.getUniqueVRegDef(Base);
926 if (BaseDef && BaseDef->getOpcode() == TargetOpcode::G_FRAME_INDEX)
927 return false;
928
929 LLVM_DEBUG(dbgs() << "Searching for post-indexing opportunity for: " << MI)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << "Searching for post-indexing opportunity for: "
<< MI; } } while (false)
;
930 // FIXME: The following use traversal needs a bail out for patholigical cases.
931 for (auto &Use : MRI.use_nodbg_instructions(Base)) {
932 if (Use.getOpcode() != TargetOpcode::G_PTR_ADD)
933 continue;
934
935 Offset = Use.getOperand(2).getReg();
936 if (!ForceLegalIndexing &&
937 !TLI.isIndexingLegal(MI, Base, Offset, /*IsPre*/ false, MRI)) {
938 LLVM_DEBUG(dbgs() << " Ignoring candidate with illegal addrmode: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << " Ignoring candidate with illegal addrmode: "
<< Use; } } while (false)
939 << Use)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << " Ignoring candidate with illegal addrmode: "
<< Use; } } while (false)
;
940 continue;
941 }
942
943 // Make sure the offset calculation is before the potentially indexed op.
944 // FIXME: we really care about dependency here. The offset calculation might
945 // be movable.
946 MachineInstr *OffsetDef = MRI.getUniqueVRegDef(Offset);
947 if (!OffsetDef || !dominates(*OffsetDef, MI)) {
948 LLVM_DEBUG(dbgs() << " Ignoring candidate with offset after mem-op: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << " Ignoring candidate with offset after mem-op: "
<< Use; } } while (false)
949 << Use)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << " Ignoring candidate with offset after mem-op: "
<< Use; } } while (false)
;
950 continue;
951 }
952
953 // FIXME: check whether all uses of Base are load/store with foldable
954 // addressing modes. If so, using the normal addr-modes is better than
955 // forming an indexed one.
956
957 bool MemOpDominatesAddrUses = true;
958 for (auto &PtrAddUse :
959 MRI.use_nodbg_instructions(Use.getOperand(0).getReg())) {
960 if (!dominates(MI, PtrAddUse)) {
961 MemOpDominatesAddrUses = false;
962 break;
963 }
964 }
965
966 if (!MemOpDominatesAddrUses) {
967 LLVM_DEBUG(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << " Ignoring candidate as memop does not dominate uses: "
<< Use; } } while (false)
968 dbgs() << " Ignoring candidate as memop does not dominate uses: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << " Ignoring candidate as memop does not dominate uses: "
<< Use; } } while (false)
969 << Use)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << " Ignoring candidate as memop does not dominate uses: "
<< Use; } } while (false)
;
970 continue;
971 }
972
973 LLVM_DEBUG(dbgs() << " Found match: " << Use)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << " Found match: " <<
Use; } } while (false)
;
974 Addr = Use.getOperand(0).getReg();
975 return true;
976 }
977
978 return false;
979}
980
981bool CombinerHelper::findPreIndexCandidate(MachineInstr &MI, Register &Addr,
982 Register &Base, Register &Offset) {
983 auto &MF = *MI.getParent()->getParent();
984 const auto &TLI = *MF.getSubtarget().getTargetLowering();
985
986#ifndef NDEBUG
987 unsigned Opcode = MI.getOpcode();
988 assert(Opcode == TargetOpcode::G_LOAD || Opcode == TargetOpcode::G_SEXTLOAD ||(static_cast <bool> (Opcode == TargetOpcode::G_LOAD || Opcode
== TargetOpcode::G_SEXTLOAD || Opcode == TargetOpcode::G_ZEXTLOAD
|| Opcode == TargetOpcode::G_STORE) ? void (0) : __assert_fail
("Opcode == TargetOpcode::G_LOAD || Opcode == TargetOpcode::G_SEXTLOAD || Opcode == TargetOpcode::G_ZEXTLOAD || Opcode == TargetOpcode::G_STORE"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 989, __extension__
__PRETTY_FUNCTION__))
989 Opcode == TargetOpcode::G_ZEXTLOAD || Opcode == TargetOpcode::G_STORE)(static_cast <bool> (Opcode == TargetOpcode::G_LOAD || Opcode
== TargetOpcode::G_SEXTLOAD || Opcode == TargetOpcode::G_ZEXTLOAD
|| Opcode == TargetOpcode::G_STORE) ? void (0) : __assert_fail
("Opcode == TargetOpcode::G_LOAD || Opcode == TargetOpcode::G_SEXTLOAD || Opcode == TargetOpcode::G_ZEXTLOAD || Opcode == TargetOpcode::G_STORE"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 989, __extension__
__PRETTY_FUNCTION__))
;
990#endif
991
992 Addr = MI.getOperand(1).getReg();
993 MachineInstr *AddrDef = getOpcodeDef(TargetOpcode::G_PTR_ADD, Addr, MRI);
994 if (!AddrDef || MRI.hasOneNonDBGUse(Addr))
995 return false;
996
997 Base = AddrDef->getOperand(1).getReg();
998 Offset = AddrDef->getOperand(2).getReg();
999
1000 LLVM_DEBUG(dbgs() << "Found potential pre-indexed load_store: " << MI)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << "Found potential pre-indexed load_store: "
<< MI; } } while (false)
;
1001
1002 if (!ForceLegalIndexing &&
1003 !TLI.isIndexingLegal(MI, Base, Offset, /*IsPre*/ true, MRI)) {
1004 LLVM_DEBUG(dbgs() << " Skipping, not legal for target")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << " Skipping, not legal for target"
; } } while (false)
;
1005 return false;
1006 }
1007
1008 MachineInstr *BaseDef = getDefIgnoringCopies(Base, MRI);
1009 if (BaseDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) {
1010 LLVM_DEBUG(dbgs() << " Skipping, frame index would need copy anyway.")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << " Skipping, frame index would need copy anyway."
; } } while (false)
;
1011 return false;
1012 }
1013
1014 if (MI.getOpcode() == TargetOpcode::G_STORE) {
1015 // Would require a copy.
1016 if (Base == MI.getOperand(0).getReg()) {
1017 LLVM_DEBUG(dbgs() << " Skipping, storing base so need copy anyway.")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << " Skipping, storing base so need copy anyway."
; } } while (false)
;
1018 return false;
1019 }
1020
1021 // We're expecting one use of Addr in MI, but it could also be the
1022 // value stored, which isn't actually dominated by the instruction.
1023 if (MI.getOperand(0).getReg() == Addr) {
1024 LLVM_DEBUG(dbgs() << " Skipping, does not dominate all addr uses")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << " Skipping, does not dominate all addr uses"
; } } while (false)
;
1025 return false;
1026 }
1027 }
1028
1029 // FIXME: check whether all uses of the base pointer are constant PtrAdds.
1030 // That might allow us to end base's liveness here by adjusting the constant.
1031
1032 for (auto &UseMI : MRI.use_nodbg_instructions(Addr)) {
1033 if (!dominates(MI, UseMI)) {
1034 LLVM_DEBUG(dbgs() << " Skipping, does not dominate all addr uses.")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << " Skipping, does not dominate all addr uses."
; } } while (false)
;
1035 return false;
1036 }
1037 }
1038
1039 return true;
1040}
1041
1042bool CombinerHelper::tryCombineIndexedLoadStore(MachineInstr &MI) {
1043 IndexedLoadStoreMatchInfo MatchInfo;
1044 if (matchCombineIndexedLoadStore(MI, MatchInfo)) {
1045 applyCombineIndexedLoadStore(MI, MatchInfo);
1046 return true;
1047 }
1048 return false;
1049}
1050
1051bool CombinerHelper::matchCombineIndexedLoadStore(MachineInstr &MI, IndexedLoadStoreMatchInfo &MatchInfo) {
1052 unsigned Opcode = MI.getOpcode();
1053 if (Opcode != TargetOpcode::G_LOAD && Opcode != TargetOpcode::G_SEXTLOAD &&
1054 Opcode != TargetOpcode::G_ZEXTLOAD && Opcode != TargetOpcode::G_STORE)
1055 return false;
1056
1057 // For now, no targets actually support these opcodes so don't waste time
1058 // running these unless we're forced to for testing.
1059 if (!ForceLegalIndexing)
1060 return false;
1061
1062 MatchInfo.IsPre = findPreIndexCandidate(MI, MatchInfo.Addr, MatchInfo.Base,
1063 MatchInfo.Offset);
1064 if (!MatchInfo.IsPre &&
1065 !findPostIndexCandidate(MI, MatchInfo.Addr, MatchInfo.Base,
1066 MatchInfo.Offset))
1067 return false;
1068
1069 return true;
1070}
1071
1072void CombinerHelper::applyCombineIndexedLoadStore(
1073 MachineInstr &MI, IndexedLoadStoreMatchInfo &MatchInfo) {
1074 MachineInstr &AddrDef = *MRI.getUniqueVRegDef(MatchInfo.Addr);
1075 MachineIRBuilder MIRBuilder(MI);
1076 unsigned Opcode = MI.getOpcode();
1077 bool IsStore = Opcode == TargetOpcode::G_STORE;
1078 unsigned NewOpcode;
1079 switch (Opcode) {
1080 case TargetOpcode::G_LOAD:
1081 NewOpcode = TargetOpcode::G_INDEXED_LOAD;
1082 break;
1083 case TargetOpcode::G_SEXTLOAD:
1084 NewOpcode = TargetOpcode::G_INDEXED_SEXTLOAD;
1085 break;
1086 case TargetOpcode::G_ZEXTLOAD:
1087 NewOpcode = TargetOpcode::G_INDEXED_ZEXTLOAD;
1088 break;
1089 case TargetOpcode::G_STORE:
1090 NewOpcode = TargetOpcode::G_INDEXED_STORE;
1091 break;
1092 default:
1093 llvm_unreachable("Unknown load/store opcode")::llvm::llvm_unreachable_internal("Unknown load/store opcode"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1093)
;
1094 }
1095
1096 auto MIB = MIRBuilder.buildInstr(NewOpcode);
1097 if (IsStore) {
1098 MIB.addDef(MatchInfo.Addr);
1099 MIB.addUse(MI.getOperand(0).getReg());
1100 } else {
1101 MIB.addDef(MI.getOperand(0).getReg());
1102 MIB.addDef(MatchInfo.Addr);
1103 }
1104
1105 MIB.addUse(MatchInfo.Base);
1106 MIB.addUse(MatchInfo.Offset);
1107 MIB.addImm(MatchInfo.IsPre);
1108 MI.eraseFromParent();
1109 AddrDef.eraseFromParent();
1110
1111 LLVM_DEBUG(dbgs() << " Combinined to indexed operation")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("gi-combiner")) { dbgs() << " Combinined to indexed operation"
; } } while (false)
;
1112}
1113
1114bool CombinerHelper::matchCombineDivRem(MachineInstr &MI,
1115 MachineInstr *&OtherMI) {
1116 unsigned Opcode = MI.getOpcode();
1117 bool IsDiv, IsSigned;
1118
1119 switch (Opcode) {
1120 default:
1121 llvm_unreachable("Unexpected opcode!")::llvm::llvm_unreachable_internal("Unexpected opcode!", "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp"
, 1121)
;
1122 case TargetOpcode::G_SDIV:
1123 case TargetOpcode::G_UDIV: {
1124 IsDiv = true;
1125 IsSigned = Opcode == TargetOpcode::G_SDIV;
1126 break;
1127 }
1128 case TargetOpcode::G_SREM:
1129 case TargetOpcode::G_UREM: {
1130 IsDiv = false;
1131 IsSigned = Opcode == TargetOpcode::G_SREM;
1132 break;
1133 }
1134 }
1135
1136 Register Src1 = MI.getOperand(1).getReg();
1137 unsigned DivOpcode, RemOpcode, DivremOpcode;
1138 if (IsSigned) {
1139 DivOpcode = TargetOpcode::G_SDIV;
1140 RemOpcode = TargetOpcode::G_SREM;
1141 DivremOpcode = TargetOpcode::G_SDIVREM;
1142 } else {
1143 DivOpcode = TargetOpcode::G_UDIV;
1144 RemOpcode = TargetOpcode::G_UREM;
1145 DivremOpcode = TargetOpcode::G_UDIVREM;
1146 }
1147
1148 if (!isLegalOrBeforeLegalizer({DivremOpcode, {MRI.getType(Src1)}}))
1149 return false;
1150
1151 // Combine:
1152 // %div:_ = G_[SU]DIV %src1:_, %src2:_
1153 // %rem:_ = G_[SU]REM %src1:_, %src2:_
1154 // into:
1155 // %div:_, %rem:_ = G_[SU]DIVREM %src1:_, %src2:_
1156
1157 // Combine:
1158 // %rem:_ = G_[SU]REM %src1:_, %src2:_
1159 // %div:_ = G_[SU]DIV %src1:_, %src2:_
1160 // into:
1161 // %div:_, %rem:_ = G_[SU]DIVREM %src1:_, %src2:_
1162
1163 for (auto &UseMI : MRI.use_nodbg_instructions(Src1)) {
1164 if (MI.getParent() == UseMI.getParent() &&
1165 ((IsDiv && UseMI.getOpcode() == RemOpcode) ||
1166 (!IsDiv && UseMI.getOpcode() == DivOpcode)) &&
1167 matchEqualDefs(MI.getOperand(2), UseMI.getOperand(2)) &&
1168 matchEqualDefs(MI.getOperand(1), UseMI.getOperand(1))) {
1169 OtherMI = &UseMI;
1170 return true;
1171 }
1172 }
1173
1174 return false;
1175}
1176
1177void CombinerHelper::applyCombineDivRem(MachineInstr &MI,
1178 MachineInstr *&OtherMI) {
1179 unsigned Opcode = MI.getOpcode();
1180 assert(OtherMI && "OtherMI shouldn't be empty.")(static_cast <bool> (OtherMI && "OtherMI shouldn't be empty."
) ? void (0) : __assert_fail ("OtherMI && \"OtherMI shouldn't be empty.\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1180, __extension__
__PRETTY_FUNCTION__))
;
1181
1182 Register DestDivReg, DestRemReg;
1183 if (Opcode == TargetOpcode::G_SDIV || Opcode == TargetOpcode::G_UDIV) {
1184 DestDivReg = MI.getOperand(0).getReg();
1185 DestRemReg = OtherMI->getOperand(0).getReg();
1186 } else {
1187 DestDivReg = OtherMI->getOperand(0).getReg();
1188 DestRemReg = MI.getOperand(0).getReg();
1189 }
1190
1191 bool IsSigned =
1192 Opcode == TargetOpcode::G_SDIV || Opcode == TargetOpcode::G_SREM;
1193
1194 // Check which instruction is first in the block so we don't break def-use
1195 // deps by "moving" the instruction incorrectly.
1196 if (dominates(MI, *OtherMI))
1197 Builder.setInstrAndDebugLoc(MI);
1198 else
1199 Builder.setInstrAndDebugLoc(*OtherMI);
1200
1201 Builder.buildInstr(IsSigned ? TargetOpcode::G_SDIVREM
1202 : TargetOpcode::G_UDIVREM,
1203 {DestDivReg, DestRemReg},
1204 {MI.getOperand(1).getReg(), MI.getOperand(2).getReg()});
1205 MI.eraseFromParent();
1206 OtherMI->eraseFromParent();
1207}
1208
1209bool CombinerHelper::matchOptBrCondByInvertingCond(MachineInstr &MI,
1210 MachineInstr *&BrCond) {
1211 assert(MI.getOpcode() == TargetOpcode::G_BR)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_BR
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_BR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1211, __extension__
__PRETTY_FUNCTION__))
;
1212
1213 // Try to match the following:
1214 // bb1:
1215 // G_BRCOND %c1, %bb2
1216 // G_BR %bb3
1217 // bb2:
1218 // ...
1219 // bb3:
1220
1221 // The above pattern does not have a fall through to the successor bb2, always
1222 // resulting in a branch no matter which path is taken. Here we try to find
1223 // and replace that pattern with conditional branch to bb3 and otherwise
1224 // fallthrough to bb2. This is generally better for branch predictors.
1225
1226 MachineBasicBlock *MBB = MI.getParent();
1227 MachineBasicBlock::iterator BrIt(MI);
1228 if (BrIt == MBB->begin())
1229 return false;
1230 assert(std::next(BrIt) == MBB->end() && "expected G_BR to be a terminator")(static_cast <bool> (std::next(BrIt) == MBB->end() &&
"expected G_BR to be a terminator") ? void (0) : __assert_fail
("std::next(BrIt) == MBB->end() && \"expected G_BR to be a terminator\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1230, __extension__
__PRETTY_FUNCTION__))
;
1231
1232 BrCond = &*std::prev(BrIt);
1233 if (BrCond->getOpcode() != TargetOpcode::G_BRCOND)
1234 return false;
1235
1236 // Check that the next block is the conditional branch target. Also make sure
1237 // that it isn't the same as the G_BR's target (otherwise, this will loop.)
1238 MachineBasicBlock *BrCondTarget = BrCond->getOperand(1).getMBB();
1239 return BrCondTarget != MI.getOperand(0).getMBB() &&
1240 MBB->isLayoutSuccessor(BrCondTarget);
1241}
1242
1243void CombinerHelper::applyOptBrCondByInvertingCond(MachineInstr &MI,
1244 MachineInstr *&BrCond) {
1245 MachineBasicBlock *BrTarget = MI.getOperand(0).getMBB();
1246 Builder.setInstrAndDebugLoc(*BrCond);
1247 LLT Ty = MRI.getType(BrCond->getOperand(0).getReg());
1248 // FIXME: Does int/fp matter for this? If so, we might need to restrict
1249 // this to i1 only since we might not know for sure what kind of
1250 // compare generated the condition value.
1251 auto True = Builder.buildConstant(
1252 Ty, getICmpTrueVal(getTargetLowering(), false, false));
1253 auto Xor = Builder.buildXor(Ty, BrCond->getOperand(0), True);
1254
1255 auto *FallthroughBB = BrCond->getOperand(1).getMBB();
1256 Observer.changingInstr(MI);
1257 MI.getOperand(0).setMBB(FallthroughBB);
1258 Observer.changedInstr(MI);
1259
1260 // Change the conditional branch to use the inverted condition and
1261 // new target block.
1262 Observer.changingInstr(*BrCond);
1263 BrCond->getOperand(0).setReg(Xor.getReg(0));
1264 BrCond->getOperand(1).setMBB(BrTarget);
1265 Observer.changedInstr(*BrCond);
1266}
1267
1268static Type *getTypeForLLT(LLT Ty, LLVMContext &C) {
1269 if (Ty.isVector())
1270 return FixedVectorType::get(IntegerType::get(C, Ty.getScalarSizeInBits()),
1271 Ty.getNumElements());
1272 return IntegerType::get(C, Ty.getSizeInBits());
1273}
1274
1275bool CombinerHelper::tryEmitMemcpyInline(MachineInstr &MI) {
1276 MachineIRBuilder HelperBuilder(MI);
1277 GISelObserverWrapper DummyObserver;
1278 LegalizerHelper Helper(HelperBuilder.getMF(), DummyObserver, HelperBuilder);
1279 return Helper.lowerMemcpyInline(MI) ==
1280 LegalizerHelper::LegalizeResult::Legalized;
1281}
1282
1283bool CombinerHelper::tryCombineMemCpyFamily(MachineInstr &MI, unsigned MaxLen) {
1284 MachineIRBuilder HelperBuilder(MI);
1285 GISelObserverWrapper DummyObserver;
1286 LegalizerHelper Helper(HelperBuilder.getMF(), DummyObserver, HelperBuilder);
1287 return Helper.lowerMemCpyFamily(MI, MaxLen) ==
1288 LegalizerHelper::LegalizeResult::Legalized;
1289}
1290
1291static std::optional<APFloat>
1292constantFoldFpUnary(unsigned Opcode, LLT DstTy, const Register Op,
1293 const MachineRegisterInfo &MRI) {
1294 const ConstantFP *MaybeCst = getConstantFPVRegVal(Op, MRI);
1295 if (!MaybeCst)
1296 return std::nullopt;
1297
1298 APFloat V = MaybeCst->getValueAPF();
1299 switch (Opcode) {
1300 default:
1301 llvm_unreachable("Unexpected opcode!")::llvm::llvm_unreachable_internal("Unexpected opcode!", "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp"
, 1301)
;
1302 case TargetOpcode::G_FNEG: {
1303 V.changeSign();
1304 return V;
1305 }
1306 case TargetOpcode::G_FABS: {
1307 V.clearSign();
1308 return V;
1309 }
1310 case TargetOpcode::G_FPTRUNC:
1311 break;
1312 case TargetOpcode::G_FSQRT: {
1313 bool Unused;
1314 V.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &Unused);
1315 V = APFloat(sqrt(V.convertToDouble()));
1316 break;
1317 }
1318 case TargetOpcode::G_FLOG2: {
1319 bool Unused;
1320 V.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &Unused);
1321 V = APFloat(log2(V.convertToDouble()));
1322 break;
1323 }
1324 }
1325 // Convert `APFloat` to appropriate IEEE type depending on `DstTy`. Otherwise,
1326 // `buildFConstant` will assert on size mismatch. Only `G_FPTRUNC`, `G_FSQRT`,
1327 // and `G_FLOG2` reach here.
1328 bool Unused;
1329 V.convert(getFltSemanticForLLT(DstTy), APFloat::rmNearestTiesToEven, &Unused);
1330 return V;
1331}
1332
1333bool CombinerHelper::matchCombineConstantFoldFpUnary(
1334 MachineInstr &MI, std::optional<APFloat> &Cst) {
1335 Register DstReg = MI.getOperand(0).getReg();
1336 Register SrcReg = MI.getOperand(1).getReg();
1337 LLT DstTy = MRI.getType(DstReg);
1338 Cst = constantFoldFpUnary(MI.getOpcode(), DstTy, SrcReg, MRI);
1339 return Cst.has_value();
1340}
1341
1342void CombinerHelper::applyCombineConstantFoldFpUnary(
1343 MachineInstr &MI, std::optional<APFloat> &Cst) {
1344 assert(Cst && "Optional is unexpectedly empty!")(static_cast <bool> (Cst && "Optional is unexpectedly empty!"
) ? void (0) : __assert_fail ("Cst && \"Optional is unexpectedly empty!\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1344, __extension__
__PRETTY_FUNCTION__))
;
1345 Builder.setInstrAndDebugLoc(MI);
1346 MachineFunction &MF = Builder.getMF();
1347 auto *FPVal = ConstantFP::get(MF.getFunction().getContext(), *Cst);
1348 Register DstReg = MI.getOperand(0).getReg();
1349 Builder.buildFConstant(DstReg, *FPVal);
1350 MI.eraseFromParent();
1351}
1352
1353bool CombinerHelper::matchPtrAddImmedChain(MachineInstr &MI,
1354 PtrAddChain &MatchInfo) {
1355 // We're trying to match the following pattern:
1356 // %t1 = G_PTR_ADD %base, G_CONSTANT imm1
1357 // %root = G_PTR_ADD %t1, G_CONSTANT imm2
1358 // -->
1359 // %root = G_PTR_ADD %base, G_CONSTANT (imm1 + imm2)
1360
1361 if (MI.getOpcode() != TargetOpcode::G_PTR_ADD)
1362 return false;
1363
1364 Register Add2 = MI.getOperand(1).getReg();
1365 Register Imm1 = MI.getOperand(2).getReg();
1366 auto MaybeImmVal = getIConstantVRegValWithLookThrough(Imm1, MRI);
1367 if (!MaybeImmVal)
1368 return false;
1369
1370 MachineInstr *Add2Def = MRI.getVRegDef(Add2);
1371 if (!Add2Def || Add2Def->getOpcode() != TargetOpcode::G_PTR_ADD)
1372 return false;
1373
1374 Register Base = Add2Def->getOperand(1).getReg();
1375 Register Imm2 = Add2Def->getOperand(2).getReg();
1376 auto MaybeImm2Val = getIConstantVRegValWithLookThrough(Imm2, MRI);
1377 if (!MaybeImm2Val)
1378 return false;
1379
1380 // Check if the new combined immediate forms an illegal addressing mode.
1381 // Do not combine if it was legal before but would get illegal.
1382 // To do so, we need to find a load/store user of the pointer to get
1383 // the access type.
1384 Type *AccessTy = nullptr;
1385 auto &MF = *MI.getMF();
1386 for (auto &UseMI : MRI.use_nodbg_instructions(MI.getOperand(0).getReg())) {
1387 if (auto *LdSt = dyn_cast<GLoadStore>(&UseMI)) {
1388 AccessTy = getTypeForLLT(MRI.getType(LdSt->getReg(0)),
1389 MF.getFunction().getContext());
1390 break;
1391 }
1392 }
1393 TargetLoweringBase::AddrMode AMNew;
1394 APInt CombinedImm = MaybeImmVal->Value + MaybeImm2Val->Value;
1395 AMNew.BaseOffs = CombinedImm.getSExtValue();
1396 if (AccessTy) {
1397 AMNew.HasBaseReg = true;
1398 TargetLoweringBase::AddrMode AMOld;
1399 AMOld.BaseOffs = MaybeImm2Val->Value.getSExtValue();
1400 AMOld.HasBaseReg = true;
1401 unsigned AS = MRI.getType(Add2).getAddressSpace();
1402 const auto &TLI = *MF.getSubtarget().getTargetLowering();
1403 if (TLI.isLegalAddressingMode(MF.getDataLayout(), AMOld, AccessTy, AS) &&
1404 !TLI.isLegalAddressingMode(MF.getDataLayout(), AMNew, AccessTy, AS))
1405 return false;
1406 }
1407
1408 // Pass the combined immediate to the apply function.
1409 MatchInfo.Imm = AMNew.BaseOffs;
1410 MatchInfo.Base = Base;
1411 MatchInfo.Bank = getRegBank(Imm2);
1412 return true;
1413}
1414
1415void CombinerHelper::applyPtrAddImmedChain(MachineInstr &MI,
1416 PtrAddChain &MatchInfo) {
1417 assert(MI.getOpcode() == TargetOpcode::G_PTR_ADD && "Expected G_PTR_ADD")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_PTR_ADD
&& "Expected G_PTR_ADD") ? void (0) : __assert_fail (
"MI.getOpcode() == TargetOpcode::G_PTR_ADD && \"Expected G_PTR_ADD\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1417, __extension__
__PRETTY_FUNCTION__))
;
1418 MachineIRBuilder MIB(MI);
1419 LLT OffsetTy = MRI.getType(MI.getOperand(2).getReg());
1420 auto NewOffset = MIB.buildConstant(OffsetTy, MatchInfo.Imm);
1421 setRegBank(NewOffset.getReg(0), MatchInfo.Bank);
1422 Observer.changingInstr(MI);
1423 MI.getOperand(1).setReg(MatchInfo.Base);
1424 MI.getOperand(2).setReg(NewOffset.getReg(0));
1425 Observer.changedInstr(MI);
1426}
1427
1428bool CombinerHelper::matchShiftImmedChain(MachineInstr &MI,
1429 RegisterImmPair &MatchInfo) {
1430 // We're trying to match the following pattern with any of
1431 // G_SHL/G_ASHR/G_LSHR/G_SSHLSAT/G_USHLSAT shift instructions:
1432 // %t1 = SHIFT %base, G_CONSTANT imm1
1433 // %root = SHIFT %t1, G_CONSTANT imm2
1434 // -->
1435 // %root = SHIFT %base, G_CONSTANT (imm1 + imm2)
1436
1437 unsigned Opcode = MI.getOpcode();
1438 assert((Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR ||(static_cast <bool> ((Opcode == TargetOpcode::G_SHL || Opcode
== TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR ||
Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::
G_USHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT"
) ? void (0) : __assert_fail ("(Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::G_USHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1441, __extension__
__PRETTY_FUNCTION__))
1439 Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_SSHLSAT ||(static_cast <bool> ((Opcode == TargetOpcode::G_SHL || Opcode
== TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR ||
Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::
G_USHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT"
) ? void (0) : __assert_fail ("(Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::G_USHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1441, __extension__
__PRETTY_FUNCTION__))
1440 Opcode == TargetOpcode::G_USHLSAT) &&(static_cast <bool> ((Opcode == TargetOpcode::G_SHL || Opcode
== TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR ||
Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::
G_USHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT"
) ? void (0) : __assert_fail ("(Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::G_USHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1441, __extension__
__PRETTY_FUNCTION__))
1441 "Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT")(static_cast <bool> ((Opcode == TargetOpcode::G_SHL || Opcode
== TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR ||
Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::
G_USHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT"
) ? void (0) : __assert_fail ("(Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::G_USHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1441, __extension__
__PRETTY_FUNCTION__))
;
1442
1443 Register Shl2 = MI.getOperand(1).getReg();
1444 Register Imm1 = MI.getOperand(2).getReg();
1445 auto MaybeImmVal = getIConstantVRegValWithLookThrough(Imm1, MRI);
1446 if (!MaybeImmVal)
1447 return false;
1448
1449 MachineInstr *Shl2Def = MRI.getUniqueVRegDef(Shl2);
1450 if (Shl2Def->getOpcode() != Opcode)
1451 return false;
1452
1453 Register Base = Shl2Def->getOperand(1).getReg();
1454 Register Imm2 = Shl2Def->getOperand(2).getReg();
1455 auto MaybeImm2Val = getIConstantVRegValWithLookThrough(Imm2, MRI);
1456 if (!MaybeImm2Val)
1457 return false;
1458
1459 // Pass the combined immediate to the apply function.
1460 MatchInfo.Imm =
1461 (MaybeImmVal->Value.getSExtValue() + MaybeImm2Val->Value).getSExtValue();
1462 MatchInfo.Reg = Base;
1463
1464 // There is no simple replacement for a saturating unsigned left shift that
1465 // exceeds the scalar size.
1466 if (Opcode == TargetOpcode::G_USHLSAT &&
1467 MatchInfo.Imm >= MRI.getType(Shl2).getScalarSizeInBits())
1468 return false;
1469
1470 return true;
1471}
1472
1473void CombinerHelper::applyShiftImmedChain(MachineInstr &MI,
1474 RegisterImmPair &MatchInfo) {
1475 unsigned Opcode = MI.getOpcode();
1476 assert((Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR ||(static_cast <bool> ((Opcode == TargetOpcode::G_SHL || Opcode
== TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR ||
Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::
G_USHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT"
) ? void (0) : __assert_fail ("(Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::G_USHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1479, __extension__
__PRETTY_FUNCTION__))
1477 Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_SSHLSAT ||(static_cast <bool> ((Opcode == TargetOpcode::G_SHL || Opcode
== TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR ||
Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::
G_USHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT"
) ? void (0) : __assert_fail ("(Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::G_USHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1479, __extension__
__PRETTY_FUNCTION__))
1478 Opcode == TargetOpcode::G_USHLSAT) &&(static_cast <bool> ((Opcode == TargetOpcode::G_SHL || Opcode
== TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR ||
Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::
G_USHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT"
) ? void (0) : __assert_fail ("(Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::G_USHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1479, __extension__
__PRETTY_FUNCTION__))
1479 "Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT")(static_cast <bool> ((Opcode == TargetOpcode::G_SHL || Opcode
== TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR ||
Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::
G_USHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT"
) ? void (0) : __assert_fail ("(Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_SSHLSAT || Opcode == TargetOpcode::G_USHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1479, __extension__
__PRETTY_FUNCTION__))
;
1480
1481 Builder.setInstrAndDebugLoc(MI);
1482 LLT Ty = MRI.getType(MI.getOperand(1).getReg());
1483 unsigned const ScalarSizeInBits = Ty.getScalarSizeInBits();
1484 auto Imm = MatchInfo.Imm;
1485
1486 if (Imm >= ScalarSizeInBits) {
1487 // Any logical shift that exceeds scalar size will produce zero.
1488 if (Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_LSHR) {
1489 Builder.buildConstant(MI.getOperand(0), 0);
1490 MI.eraseFromParent();
1491 return;
1492 }
1493 // Arithmetic shift and saturating signed left shift have no effect beyond
1494 // scalar size.
1495 Imm = ScalarSizeInBits - 1;
1496 }
1497
1498 LLT ImmTy = MRI.getType(MI.getOperand(2).getReg());
1499 Register NewImm = Builder.buildConstant(ImmTy, Imm).getReg(0);
1500 Observer.changingInstr(MI);
1501 MI.getOperand(1).setReg(MatchInfo.Reg);
1502 MI.getOperand(2).setReg(NewImm);
1503 Observer.changedInstr(MI);
1504}
1505
1506bool CombinerHelper::matchShiftOfShiftedLogic(MachineInstr &MI,
1507 ShiftOfShiftedLogic &MatchInfo) {
1508 // We're trying to match the following pattern with any of
1509 // G_SHL/G_ASHR/G_LSHR/G_USHLSAT/G_SSHLSAT shift instructions in combination
1510 // with any of G_AND/G_OR/G_XOR logic instructions.
1511 // %t1 = SHIFT %X, G_CONSTANT C0
1512 // %t2 = LOGIC %t1, %Y
1513 // %root = SHIFT %t2, G_CONSTANT C1
1514 // -->
1515 // %t3 = SHIFT %X, G_CONSTANT (C0+C1)
1516 // %t4 = SHIFT %Y, G_CONSTANT C1
1517 // %root = LOGIC %t3, %t4
1518 unsigned ShiftOpcode = MI.getOpcode();
1519 assert((ShiftOpcode == TargetOpcode::G_SHL ||(static_cast <bool> ((ShiftOpcode == TargetOpcode::G_SHL
|| ShiftOpcode == TargetOpcode::G_ASHR || ShiftOpcode == TargetOpcode
::G_LSHR || ShiftOpcode == TargetOpcode::G_USHLSAT || ShiftOpcode
== TargetOpcode::G_SSHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT"
) ? void (0) : __assert_fail ("(ShiftOpcode == TargetOpcode::G_SHL || ShiftOpcode == TargetOpcode::G_ASHR || ShiftOpcode == TargetOpcode::G_LSHR || ShiftOpcode == TargetOpcode::G_USHLSAT || ShiftOpcode == TargetOpcode::G_SSHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1524, __extension__
__PRETTY_FUNCTION__))
1520 ShiftOpcode == TargetOpcode::G_ASHR ||(static_cast <bool> ((ShiftOpcode == TargetOpcode::G_SHL
|| ShiftOpcode == TargetOpcode::G_ASHR || ShiftOpcode == TargetOpcode
::G_LSHR || ShiftOpcode == TargetOpcode::G_USHLSAT || ShiftOpcode
== TargetOpcode::G_SSHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT"
) ? void (0) : __assert_fail ("(ShiftOpcode == TargetOpcode::G_SHL || ShiftOpcode == TargetOpcode::G_ASHR || ShiftOpcode == TargetOpcode::G_LSHR || ShiftOpcode == TargetOpcode::G_USHLSAT || ShiftOpcode == TargetOpcode::G_SSHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1524, __extension__
__PRETTY_FUNCTION__))
1521 ShiftOpcode == TargetOpcode::G_LSHR ||(static_cast <bool> ((ShiftOpcode == TargetOpcode::G_SHL
|| ShiftOpcode == TargetOpcode::G_ASHR || ShiftOpcode == TargetOpcode
::G_LSHR || ShiftOpcode == TargetOpcode::G_USHLSAT || ShiftOpcode
== TargetOpcode::G_SSHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT"
) ? void (0) : __assert_fail ("(ShiftOpcode == TargetOpcode::G_SHL || ShiftOpcode == TargetOpcode::G_ASHR || ShiftOpcode == TargetOpcode::G_LSHR || ShiftOpcode == TargetOpcode::G_USHLSAT || ShiftOpcode == TargetOpcode::G_SSHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1524, __extension__
__PRETTY_FUNCTION__))
1522 ShiftOpcode == TargetOpcode::G_USHLSAT ||(static_cast <bool> ((ShiftOpcode == TargetOpcode::G_SHL
|| ShiftOpcode == TargetOpcode::G_ASHR || ShiftOpcode == TargetOpcode
::G_LSHR || ShiftOpcode == TargetOpcode::G_USHLSAT || ShiftOpcode
== TargetOpcode::G_SSHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT"
) ? void (0) : __assert_fail ("(ShiftOpcode == TargetOpcode::G_SHL || ShiftOpcode == TargetOpcode::G_ASHR || ShiftOpcode == TargetOpcode::G_LSHR || ShiftOpcode == TargetOpcode::G_USHLSAT || ShiftOpcode == TargetOpcode::G_SSHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1524, __extension__
__PRETTY_FUNCTION__))
1523 ShiftOpcode == TargetOpcode::G_SSHLSAT) &&(static_cast <bool> ((ShiftOpcode == TargetOpcode::G_SHL
|| ShiftOpcode == TargetOpcode::G_ASHR || ShiftOpcode == TargetOpcode
::G_LSHR || ShiftOpcode == TargetOpcode::G_USHLSAT || ShiftOpcode
== TargetOpcode::G_SSHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT"
) ? void (0) : __assert_fail ("(ShiftOpcode == TargetOpcode::G_SHL || ShiftOpcode == TargetOpcode::G_ASHR || ShiftOpcode == TargetOpcode::G_LSHR || ShiftOpcode == TargetOpcode::G_USHLSAT || ShiftOpcode == TargetOpcode::G_SSHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1524, __extension__
__PRETTY_FUNCTION__))
1524 "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT")(static_cast <bool> ((ShiftOpcode == TargetOpcode::G_SHL
|| ShiftOpcode == TargetOpcode::G_ASHR || ShiftOpcode == TargetOpcode
::G_LSHR || ShiftOpcode == TargetOpcode::G_USHLSAT || ShiftOpcode
== TargetOpcode::G_SSHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT"
) ? void (0) : __assert_fail ("(ShiftOpcode == TargetOpcode::G_SHL || ShiftOpcode == TargetOpcode::G_ASHR || ShiftOpcode == TargetOpcode::G_LSHR || ShiftOpcode == TargetOpcode::G_USHLSAT || ShiftOpcode == TargetOpcode::G_SSHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1524, __extension__
__PRETTY_FUNCTION__))
;
1525
1526 // Match a one-use bitwise logic op.
1527 Register LogicDest = MI.getOperand(1).getReg();
1528 if (!MRI.hasOneNonDBGUse(LogicDest))
1529 return false;
1530
1531 MachineInstr *LogicMI = MRI.getUniqueVRegDef(LogicDest);
1532 unsigned LogicOpcode = LogicMI->getOpcode();
1533 if (LogicOpcode != TargetOpcode::G_AND && LogicOpcode != TargetOpcode::G_OR &&
1534 LogicOpcode != TargetOpcode::G_XOR)
1535 return false;
1536
1537 // Find a matching one-use shift by constant.
1538 const Register C1 = MI.getOperand(2).getReg();
1539 auto MaybeImmVal = getIConstantVRegValWithLookThrough(C1, MRI);
1540 if (!MaybeImmVal)
1541 return false;
1542
1543 const uint64_t C1Val = MaybeImmVal->Value.getZExtValue();
1544
1545 auto matchFirstShift = [&](const MachineInstr *MI, uint64_t &ShiftVal) {
1546 // Shift should match previous one and should be a one-use.
1547 if (MI->getOpcode() != ShiftOpcode ||
1548 !MRI.hasOneNonDBGUse(MI->getOperand(0).getReg()))
1549 return false;
1550
1551 // Must be a constant.
1552 auto MaybeImmVal =
1553 getIConstantVRegValWithLookThrough(MI->getOperand(2).getReg(), MRI);
1554 if (!MaybeImmVal)
1555 return false;
1556
1557 ShiftVal = MaybeImmVal->Value.getSExtValue();
1558 return true;
1559 };
1560
1561 // Logic ops are commutative, so check each operand for a match.
1562 Register LogicMIReg1 = LogicMI->getOperand(1).getReg();
1563 MachineInstr *LogicMIOp1 = MRI.getUniqueVRegDef(LogicMIReg1);
1564 Register LogicMIReg2 = LogicMI->getOperand(2).getReg();
1565 MachineInstr *LogicMIOp2 = MRI.getUniqueVRegDef(LogicMIReg2);
1566 uint64_t C0Val;
1567
1568 if (matchFirstShift(LogicMIOp1, C0Val)) {
1569 MatchInfo.LogicNonShiftReg = LogicMIReg2;
1570 MatchInfo.Shift2 = LogicMIOp1;
1571 } else if (matchFirstShift(LogicMIOp2, C0Val)) {
1572 MatchInfo.LogicNonShiftReg = LogicMIReg1;
1573 MatchInfo.Shift2 = LogicMIOp2;
1574 } else
1575 return false;
1576
1577 MatchInfo.ValSum = C0Val + C1Val;
1578
1579 // The fold is not valid if the sum of the shift values exceeds bitwidth.
1580 if (MatchInfo.ValSum >= MRI.getType(LogicDest).getScalarSizeInBits())
1581 return false;
1582
1583 MatchInfo.Logic = LogicMI;
1584 return true;
1585}
1586
1587void CombinerHelper::applyShiftOfShiftedLogic(MachineInstr &MI,
1588 ShiftOfShiftedLogic &MatchInfo) {
1589 unsigned Opcode = MI.getOpcode();
1590 assert((Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR ||(static_cast <bool> ((Opcode == TargetOpcode::G_SHL || Opcode
== TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR ||
Opcode == TargetOpcode::G_USHLSAT || Opcode == TargetOpcode::
G_SSHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT"
) ? void (0) : __assert_fail ("(Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_USHLSAT || Opcode == TargetOpcode::G_SSHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1593, __extension__
__PRETTY_FUNCTION__))
1591 Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_USHLSAT ||(static_cast <bool> ((Opcode == TargetOpcode::G_SHL || Opcode
== TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR ||
Opcode == TargetOpcode::G_USHLSAT || Opcode == TargetOpcode::
G_SSHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT"
) ? void (0) : __assert_fail ("(Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_USHLSAT || Opcode == TargetOpcode::G_SSHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1593, __extension__
__PRETTY_FUNCTION__))
1592 Opcode == TargetOpcode::G_SSHLSAT) &&(static_cast <bool> ((Opcode == TargetOpcode::G_SHL || Opcode
== TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR ||
Opcode == TargetOpcode::G_USHLSAT || Opcode == TargetOpcode::
G_SSHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT"
) ? void (0) : __assert_fail ("(Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_USHLSAT || Opcode == TargetOpcode::G_SSHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1593, __extension__
__PRETTY_FUNCTION__))
1593 "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT")(static_cast <bool> ((Opcode == TargetOpcode::G_SHL || Opcode
== TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR ||
Opcode == TargetOpcode::G_USHLSAT || Opcode == TargetOpcode::
G_SSHLSAT) && "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT"
) ? void (0) : __assert_fail ("(Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_USHLSAT || Opcode == TargetOpcode::G_SSHLSAT) && \"Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1593, __extension__
__PRETTY_FUNCTION__))
;
1594
1595 LLT ShlType = MRI.getType(MI.getOperand(2).getReg());
1596 LLT DestType = MRI.getType(MI.getOperand(0).getReg());
1597 Builder.setInstrAndDebugLoc(MI);
1598
1599 Register Const = Builder.buildConstant(ShlType, MatchInfo.ValSum).getReg(0);
1600
1601 Register Shift1Base = MatchInfo.Shift2->getOperand(1).getReg();
1602 Register Shift1 =
1603 Builder.buildInstr(Opcode, {DestType}, {Shift1Base, Const}).getReg(0);
1604
1605 // If LogicNonShiftReg is the same to Shift1Base, and shift1 const is the same
1606 // to MatchInfo.Shift2 const, CSEMIRBuilder will reuse the old shift1 when
1607 // build shift2. So, if we erase MatchInfo.Shift2 at the end, actually we
1608 // remove old shift1. And it will cause crash later. So erase it earlier to
1609 // avoid the crash.
1610 MatchInfo.Shift2->eraseFromParent();
1611
1612 Register Shift2Const = MI.getOperand(2).getReg();
1613 Register Shift2 = Builder
1614 .buildInstr(Opcode, {DestType},
1615 {MatchInfo.LogicNonShiftReg, Shift2Const})
1616 .getReg(0);
1617
1618 Register Dest = MI.getOperand(0).getReg();
1619 Builder.buildInstr(MatchInfo.Logic->getOpcode(), {Dest}, {Shift1, Shift2});
1620
1621 // This was one use so it's safe to remove it.
1622 MatchInfo.Logic->eraseFromParent();
1623
1624 MI.eraseFromParent();
1625}
1626
1627bool CombinerHelper::matchCommuteShift(MachineInstr &MI, BuildFnTy &MatchInfo) {
1628 assert(MI.getOpcode() == TargetOpcode::G_SHL && "Expected G_SHL")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SHL
&& "Expected G_SHL") ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_SHL && \"Expected G_SHL\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1628, __extension__
__PRETTY_FUNCTION__))
;
1629 // Combine (shl (add x, c1), c2) -> (add (shl x, c2), c1 << c2)
1630 // Combine (shl (or x, c1), c2) -> (or (shl x, c2), c1 << c2)
1631 auto &Shl = cast<GenericMachineInstr>(MI);
1632 Register DstReg = Shl.getReg(0);
1633 Register SrcReg = Shl.getReg(1);
1634 Register ShiftReg = Shl.getReg(2);
1635 Register X, C1;
1636
1637 if (!getTargetLowering().isDesirableToCommuteWithShift(MI, !isPreLegalize()))
1638 return false;
1639
1640 if (!mi_match(SrcReg, MRI,
1641 m_OneNonDBGUse(m_any_of(m_GAdd(m_Reg(X), m_Reg(C1)),
1642 m_GOr(m_Reg(X), m_Reg(C1))))))
1643 return false;
1644
1645 APInt C1Val, C2Val;
1646 if (!mi_match(C1, MRI, m_ICstOrSplat(C1Val)) ||
1647 !mi_match(ShiftReg, MRI, m_ICstOrSplat(C2Val)))
1648 return false;
1649
1650 auto *SrcDef = MRI.getVRegDef(SrcReg);
1651 assert((SrcDef->getOpcode() == TargetOpcode::G_ADD ||(static_cast <bool> ((SrcDef->getOpcode() == TargetOpcode
::G_ADD || SrcDef->getOpcode() == TargetOpcode::G_OR) &&
"Unexpected op") ? void (0) : __assert_fail ("(SrcDef->getOpcode() == TargetOpcode::G_ADD || SrcDef->getOpcode() == TargetOpcode::G_OR) && \"Unexpected op\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1652, __extension__
__PRETTY_FUNCTION__))
1652 SrcDef->getOpcode() == TargetOpcode::G_OR) && "Unexpected op")(static_cast <bool> ((SrcDef->getOpcode() == TargetOpcode
::G_ADD || SrcDef->getOpcode() == TargetOpcode::G_OR) &&
"Unexpected op") ? void (0) : __assert_fail ("(SrcDef->getOpcode() == TargetOpcode::G_ADD || SrcDef->getOpcode() == TargetOpcode::G_OR) && \"Unexpected op\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1652, __extension__
__PRETTY_FUNCTION__))
;
1653 LLT SrcTy = MRI.getType(SrcReg);
1654 MatchInfo = [=](MachineIRBuilder &B) {
1655 auto S1 = B.buildShl(SrcTy, X, ShiftReg);
1656 auto S2 = B.buildShl(SrcTy, C1, ShiftReg);
1657 B.buildInstr(SrcDef->getOpcode(), {DstReg}, {S1, S2});
1658 };
1659 return true;
1660}
1661
1662bool CombinerHelper::matchCombineMulToShl(MachineInstr &MI,
1663 unsigned &ShiftVal) {
1664 assert(MI.getOpcode() == TargetOpcode::G_MUL && "Expected a G_MUL")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_MUL
&& "Expected a G_MUL") ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_MUL && \"Expected a G_MUL\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1664, __extension__
__PRETTY_FUNCTION__))
;
1665 auto MaybeImmVal =
1666 getIConstantVRegValWithLookThrough(MI.getOperand(2).getReg(), MRI);
1667 if (!MaybeImmVal)
1668 return false;
1669
1670 ShiftVal = MaybeImmVal->Value.exactLogBase2();
1671 return (static_cast<int32_t>(ShiftVal) != -1);
1672}
1673
1674void CombinerHelper::applyCombineMulToShl(MachineInstr &MI,
1675 unsigned &ShiftVal) {
1676 assert(MI.getOpcode() == TargetOpcode::G_MUL && "Expected a G_MUL")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_MUL
&& "Expected a G_MUL") ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_MUL && \"Expected a G_MUL\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1676, __extension__
__PRETTY_FUNCTION__))
;
1677 MachineIRBuilder MIB(MI);
1678 LLT ShiftTy = MRI.getType(MI.getOperand(0).getReg());
1679 auto ShiftCst = MIB.buildConstant(ShiftTy, ShiftVal);
1680 Observer.changingInstr(MI);
1681 MI.setDesc(MIB.getTII().get(TargetOpcode::G_SHL));
1682 MI.getOperand(2).setReg(ShiftCst.getReg(0));
1683 Observer.changedInstr(MI);
1684}
1685
1686// shl ([sza]ext x), y => zext (shl x, y), if shift does not overflow source
1687bool CombinerHelper::matchCombineShlOfExtend(MachineInstr &MI,
1688 RegisterImmPair &MatchData) {
1689 assert(MI.getOpcode() == TargetOpcode::G_SHL && KB)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SHL
&& KB) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_SHL && KB"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1689, __extension__
__PRETTY_FUNCTION__))
;
1690
1691 Register LHS = MI.getOperand(1).getReg();
1692
1693 Register ExtSrc;
1694 if (!mi_match(LHS, MRI, m_GAnyExt(m_Reg(ExtSrc))) &&
1695 !mi_match(LHS, MRI, m_GZExt(m_Reg(ExtSrc))) &&
1696 !mi_match(LHS, MRI, m_GSExt(m_Reg(ExtSrc))))
1697 return false;
1698
1699 // TODO: Should handle vector splat.
1700 Register RHS = MI.getOperand(2).getReg();
1701 auto MaybeShiftAmtVal = getIConstantVRegValWithLookThrough(RHS, MRI);
1702 if (!MaybeShiftAmtVal)
1703 return false;
1704
1705 if (LI) {
1706 LLT SrcTy = MRI.getType(ExtSrc);
1707
1708 // We only really care about the legality with the shifted value. We can
1709 // pick any type the constant shift amount, so ask the target what to
1710 // use. Otherwise we would have to guess and hope it is reported as legal.
1711 LLT ShiftAmtTy = getTargetLowering().getPreferredShiftAmountTy(SrcTy);
1712 if (!isLegalOrBeforeLegalizer({TargetOpcode::G_SHL, {SrcTy, ShiftAmtTy}}))
1713 return false;
1714 }
1715
1716 int64_t ShiftAmt = MaybeShiftAmtVal->Value.getSExtValue();
1717 MatchData.Reg = ExtSrc;
1718 MatchData.Imm = ShiftAmt;
1719
1720 unsigned MinLeadingZeros = KB->getKnownZeroes(ExtSrc).countl_one();
1721 return MinLeadingZeros >= ShiftAmt;
1722}
1723
1724void CombinerHelper::applyCombineShlOfExtend(MachineInstr &MI,
1725 const RegisterImmPair &MatchData) {
1726 Register ExtSrcReg = MatchData.Reg;
1727 int64_t ShiftAmtVal = MatchData.Imm;
1728
1729 LLT ExtSrcTy = MRI.getType(ExtSrcReg);
1730 Builder.setInstrAndDebugLoc(MI);
1731 auto ShiftAmt = Builder.buildConstant(ExtSrcTy, ShiftAmtVal);
1732 auto NarrowShift =
1733 Builder.buildShl(ExtSrcTy, ExtSrcReg, ShiftAmt, MI.getFlags());
1734 Builder.buildZExt(MI.getOperand(0), NarrowShift);
1735 MI.eraseFromParent();
1736}
1737
1738bool CombinerHelper::matchCombineMergeUnmerge(MachineInstr &MI,
1739 Register &MatchInfo) {
1740 GMerge &Merge = cast<GMerge>(MI);
1741 SmallVector<Register, 16> MergedValues;
1742 for (unsigned I = 0; I < Merge.getNumSources(); ++I)
1743 MergedValues.emplace_back(Merge.getSourceReg(I));
1744
1745 auto *Unmerge = getOpcodeDef<GUnmerge>(MergedValues[0], MRI);
1746 if (!Unmerge || Unmerge->getNumDefs() != Merge.getNumSources())
1747 return false;
1748
1749 for (unsigned I = 0; I < MergedValues.size(); ++I)
1750 if (MergedValues[I] != Unmerge->getReg(I))
1751 return false;
1752
1753 MatchInfo = Unmerge->getSourceReg();
1754 return true;
1755}
1756
1757static Register peekThroughBitcast(Register Reg,
1758 const MachineRegisterInfo &MRI) {
1759 while (mi_match(Reg, MRI, m_GBitcast(m_Reg(Reg))))
1760 ;
1761
1762 return Reg;
1763}
1764
1765bool CombinerHelper::matchCombineUnmergeMergeToPlainValues(
1766 MachineInstr &MI, SmallVectorImpl<Register> &Operands) {
1767 assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES
&& "Expected an unmerge") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES && \"Expected an unmerge\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1768, __extension__
__PRETTY_FUNCTION__))
1768 "Expected an unmerge")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES
&& "Expected an unmerge") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES && \"Expected an unmerge\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1768, __extension__
__PRETTY_FUNCTION__))
;
1769 auto &Unmerge = cast<GUnmerge>(MI);
1770 Register SrcReg = peekThroughBitcast(Unmerge.getSourceReg(), MRI);
1771
1772 auto *SrcInstr = getOpcodeDef<GMergeLikeInstr>(SrcReg, MRI);
1773 if (!SrcInstr)
1774 return false;
1775
1776 // Check the source type of the merge.
1777 LLT SrcMergeTy = MRI.getType(SrcInstr->getSourceReg(0));
1778 LLT Dst0Ty = MRI.getType(Unmerge.getReg(0));
1779 bool SameSize = Dst0Ty.getSizeInBits() == SrcMergeTy.getSizeInBits();
1780 if (SrcMergeTy != Dst0Ty && !SameSize)
1781 return false;
1782 // They are the same now (modulo a bitcast).
1783 // We can collect all the src registers.
1784 for (unsigned Idx = 0; Idx < SrcInstr->getNumSources(); ++Idx)
1785 Operands.push_back(SrcInstr->getSourceReg(Idx));
1786 return true;
1787}
1788
1789void CombinerHelper::applyCombineUnmergeMergeToPlainValues(
1790 MachineInstr &MI, SmallVectorImpl<Register> &Operands) {
1791 assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES
&& "Expected an unmerge") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES && \"Expected an unmerge\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1792, __extension__
__PRETTY_FUNCTION__))
1792 "Expected an unmerge")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES
&& "Expected an unmerge") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES && \"Expected an unmerge\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1792, __extension__
__PRETTY_FUNCTION__))
;
1793 assert((MI.getNumOperands() - 1 == Operands.size()) &&(static_cast <bool> ((MI.getNumOperands() - 1 == Operands
.size()) && "Not enough operands to replace all defs"
) ? void (0) : __assert_fail ("(MI.getNumOperands() - 1 == Operands.size()) && \"Not enough operands to replace all defs\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1794, __extension__
__PRETTY_FUNCTION__))
1794 "Not enough operands to replace all defs")(static_cast <bool> ((MI.getNumOperands() - 1 == Operands
.size()) && "Not enough operands to replace all defs"
) ? void (0) : __assert_fail ("(MI.getNumOperands() - 1 == Operands.size()) && \"Not enough operands to replace all defs\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1794, __extension__
__PRETTY_FUNCTION__))
;
1795 unsigned NumElems = MI.getNumOperands() - 1;
1796
1797 LLT SrcTy = MRI.getType(Operands[0]);
1798 LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
1799 bool CanReuseInputDirectly = DstTy == SrcTy;
1800 Builder.setInstrAndDebugLoc(MI);
1801 for (unsigned Idx = 0; Idx < NumElems; ++Idx) {
1802 Register DstReg = MI.getOperand(Idx).getReg();
1803 Register SrcReg = Operands[Idx];
1804
1805 // This combine may run after RegBankSelect, so we need to be aware of
1806 // register banks.
1807 const auto &DstCB = MRI.getRegClassOrRegBank(DstReg);
1808 if (!DstCB.isNull() && DstCB != MRI.getRegClassOrRegBank(SrcReg)) {
1809 SrcReg = Builder.buildCopy(MRI.getType(SrcReg), SrcReg).getReg(0);
1810 MRI.setRegClassOrRegBank(SrcReg, DstCB);
1811 }
1812
1813 if (CanReuseInputDirectly)
1814 replaceRegWith(MRI, DstReg, SrcReg);
1815 else
1816 Builder.buildCast(DstReg, SrcReg);
1817 }
1818 MI.eraseFromParent();
1819}
1820
1821bool CombinerHelper::matchCombineUnmergeConstant(MachineInstr &MI,
1822 SmallVectorImpl<APInt> &Csts) {
1823 unsigned SrcIdx = MI.getNumOperands() - 1;
1824 Register SrcReg = MI.getOperand(SrcIdx).getReg();
1825 MachineInstr *SrcInstr = MRI.getVRegDef(SrcReg);
1826 if (SrcInstr->getOpcode() != TargetOpcode::G_CONSTANT &&
1827 SrcInstr->getOpcode() != TargetOpcode::G_FCONSTANT)
1828 return false;
1829 // Break down the big constant in smaller ones.
1830 const MachineOperand &CstVal = SrcInstr->getOperand(1);
1831 APInt Val = SrcInstr->getOpcode() == TargetOpcode::G_CONSTANT
1832 ? CstVal.getCImm()->getValue()
1833 : CstVal.getFPImm()->getValueAPF().bitcastToAPInt();
1834
1835 LLT Dst0Ty = MRI.getType(MI.getOperand(0).getReg());
1836 unsigned ShiftAmt = Dst0Ty.getSizeInBits();
1837 // Unmerge a constant.
1838 for (unsigned Idx = 0; Idx != SrcIdx; ++Idx) {
1839 Csts.emplace_back(Val.trunc(ShiftAmt));
1840 Val = Val.lshr(ShiftAmt);
1841 }
1842
1843 return true;
1844}
1845
1846void CombinerHelper::applyCombineUnmergeConstant(MachineInstr &MI,
1847 SmallVectorImpl<APInt> &Csts) {
1848 assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES
&& "Expected an unmerge") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES && \"Expected an unmerge\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1849, __extension__
__PRETTY_FUNCTION__))
1849 "Expected an unmerge")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES
&& "Expected an unmerge") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES && \"Expected an unmerge\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1849, __extension__
__PRETTY_FUNCTION__))
;
1850 assert((MI.getNumOperands() - 1 == Csts.size()) &&(static_cast <bool> ((MI.getNumOperands() - 1 == Csts.size
()) && "Not enough operands to replace all defs") ? void
(0) : __assert_fail ("(MI.getNumOperands() - 1 == Csts.size()) && \"Not enough operands to replace all defs\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1851, __extension__
__PRETTY_FUNCTION__))
1851 "Not enough operands to replace all defs")(static_cast <bool> ((MI.getNumOperands() - 1 == Csts.size
()) && "Not enough operands to replace all defs") ? void
(0) : __assert_fail ("(MI.getNumOperands() - 1 == Csts.size()) && \"Not enough operands to replace all defs\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1851, __extension__
__PRETTY_FUNCTION__))
;
1852 unsigned NumElems = MI.getNumOperands() - 1;
1853 Builder.setInstrAndDebugLoc(MI);
1854 for (unsigned Idx = 0; Idx < NumElems; ++Idx) {
1855 Register DstReg = MI.getOperand(Idx).getReg();
1856 Builder.buildConstant(DstReg, Csts[Idx]);
1857 }
1858
1859 MI.eraseFromParent();
1860}
1861
1862bool CombinerHelper::matchCombineUnmergeUndef(
1863 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
1864 unsigned SrcIdx = MI.getNumOperands() - 1;
1865 Register SrcReg = MI.getOperand(SrcIdx).getReg();
1866 MatchInfo = [&MI](MachineIRBuilder &B) {
1867 unsigned NumElems = MI.getNumOperands() - 1;
1868 for (unsigned Idx = 0; Idx < NumElems; ++Idx) {
1869 Register DstReg = MI.getOperand(Idx).getReg();
1870 B.buildUndef(DstReg);
1871 }
1872 };
1873 return isa<GImplicitDef>(MRI.getVRegDef(SrcReg));
1874}
1875
1876bool CombinerHelper::matchCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI) {
1877 assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES
&& "Expected an unmerge") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES && \"Expected an unmerge\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1878, __extension__
__PRETTY_FUNCTION__))
1878 "Expected an unmerge")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES
&& "Expected an unmerge") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES && \"Expected an unmerge\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1878, __extension__
__PRETTY_FUNCTION__))
;
1879 // Check that all the lanes are dead except the first one.
1880 for (unsigned Idx = 1, EndIdx = MI.getNumDefs(); Idx != EndIdx; ++Idx) {
1881 if (!MRI.use_nodbg_empty(MI.getOperand(Idx).getReg()))
1882 return false;
1883 }
1884 return true;
1885}
1886
1887void CombinerHelper::applyCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI) {
1888 Builder.setInstrAndDebugLoc(MI);
1889 Register SrcReg = MI.getOperand(MI.getNumDefs()).getReg();
1890 // Truncating a vector is going to truncate every single lane,
1891 // whereas we want the full lowbits.
1892 // Do the operation on a scalar instead.
1893 LLT SrcTy = MRI.getType(SrcReg);
1894 if (SrcTy.isVector())
1895 SrcReg =
1896 Builder.buildCast(LLT::scalar(SrcTy.getSizeInBits()), SrcReg).getReg(0);
1897
1898 Register Dst0Reg = MI.getOperand(0).getReg();
1899 LLT Dst0Ty = MRI.getType(Dst0Reg);
1900 if (Dst0Ty.isVector()) {
1901 auto MIB = Builder.buildTrunc(LLT::scalar(Dst0Ty.getSizeInBits()), SrcReg);
1902 Builder.buildCast(Dst0Reg, MIB);
1903 } else
1904 Builder.buildTrunc(Dst0Reg, SrcReg);
1905 MI.eraseFromParent();
1906}
1907
1908bool CombinerHelper::matchCombineUnmergeZExtToZExt(MachineInstr &MI) {
1909 assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES
&& "Expected an unmerge") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES && \"Expected an unmerge\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1910, __extension__
__PRETTY_FUNCTION__))
1910 "Expected an unmerge")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES
&& "Expected an unmerge") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES && \"Expected an unmerge\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1910, __extension__
__PRETTY_FUNCTION__))
;
1911 Register Dst0Reg = MI.getOperand(0).getReg();
1912 LLT Dst0Ty = MRI.getType(Dst0Reg);
1913 // G_ZEXT on vector applies to each lane, so it will
1914 // affect all destinations. Therefore we won't be able
1915 // to simplify the unmerge to just the first definition.
1916 if (Dst0Ty.isVector())
1917 return false;
1918 Register SrcReg = MI.getOperand(MI.getNumDefs()).getReg();
1919 LLT SrcTy = MRI.getType(SrcReg);
1920 if (SrcTy.isVector())
1921 return false;
1922
1923 Register ZExtSrcReg;
1924 if (!mi_match(SrcReg, MRI, m_GZExt(m_Reg(ZExtSrcReg))))
1925 return false;
1926
1927 // Finally we can replace the first definition with
1928 // a zext of the source if the definition is big enough to hold
1929 // all of ZExtSrc bits.
1930 LLT ZExtSrcTy = MRI.getType(ZExtSrcReg);
1931 return ZExtSrcTy.getSizeInBits() <= Dst0Ty.getSizeInBits();
1932}
1933
1934void CombinerHelper::applyCombineUnmergeZExtToZExt(MachineInstr &MI) {
1935 assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES
&& "Expected an unmerge") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES && \"Expected an unmerge\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1936, __extension__
__PRETTY_FUNCTION__))
1936 "Expected an unmerge")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES
&& "Expected an unmerge") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES && \"Expected an unmerge\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1936, __extension__
__PRETTY_FUNCTION__))
;
1937
1938 Register Dst0Reg = MI.getOperand(0).getReg();
1939
1940 MachineInstr *ZExtInstr =
1941 MRI.getVRegDef(MI.getOperand(MI.getNumDefs()).getReg());
1942 assert(ZExtInstr && ZExtInstr->getOpcode() == TargetOpcode::G_ZEXT &&(static_cast <bool> (ZExtInstr && ZExtInstr->
getOpcode() == TargetOpcode::G_ZEXT && "Expecting a G_ZEXT"
) ? void (0) : __assert_fail ("ZExtInstr && ZExtInstr->getOpcode() == TargetOpcode::G_ZEXT && \"Expecting a G_ZEXT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1943, __extension__
__PRETTY_FUNCTION__))
1943 "Expecting a G_ZEXT")(static_cast <bool> (ZExtInstr && ZExtInstr->
getOpcode() == TargetOpcode::G_ZEXT && "Expecting a G_ZEXT"
) ? void (0) : __assert_fail ("ZExtInstr && ZExtInstr->getOpcode() == TargetOpcode::G_ZEXT && \"Expecting a G_ZEXT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1943, __extension__
__PRETTY_FUNCTION__))
;
1944
1945 Register ZExtSrcReg = ZExtInstr->getOperand(1).getReg();
1946 LLT Dst0Ty = MRI.getType(Dst0Reg);
1947 LLT ZExtSrcTy = MRI.getType(ZExtSrcReg);
1948
1949 Builder.setInstrAndDebugLoc(MI);
1950
1951 if (Dst0Ty.getSizeInBits() > ZExtSrcTy.getSizeInBits()) {
1952 Builder.buildZExt(Dst0Reg, ZExtSrcReg);
1953 } else {
1954 assert(Dst0Ty.getSizeInBits() == ZExtSrcTy.getSizeInBits() &&(static_cast <bool> (Dst0Ty.getSizeInBits() == ZExtSrcTy
.getSizeInBits() && "ZExt src doesn't fit in destination"
) ? void (0) : __assert_fail ("Dst0Ty.getSizeInBits() == ZExtSrcTy.getSizeInBits() && \"ZExt src doesn't fit in destination\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1955, __extension__
__PRETTY_FUNCTION__))
1955 "ZExt src doesn't fit in destination")(static_cast <bool> (Dst0Ty.getSizeInBits() == ZExtSrcTy
.getSizeInBits() && "ZExt src doesn't fit in destination"
) ? void (0) : __assert_fail ("Dst0Ty.getSizeInBits() == ZExtSrcTy.getSizeInBits() && \"ZExt src doesn't fit in destination\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1955, __extension__
__PRETTY_FUNCTION__))
;
1956 replaceRegWith(MRI, Dst0Reg, ZExtSrcReg);
1957 }
1958
1959 Register ZeroReg;
1960 for (unsigned Idx = 1, EndIdx = MI.getNumDefs(); Idx != EndIdx; ++Idx) {
1961 if (!ZeroReg)
1962 ZeroReg = Builder.buildConstant(Dst0Ty, 0).getReg(0);
1963 replaceRegWith(MRI, MI.getOperand(Idx).getReg(), ZeroReg);
1964 }
1965 MI.eraseFromParent();
1966}
1967
1968bool CombinerHelper::matchCombineShiftToUnmerge(MachineInstr &MI,
1969 unsigned TargetShiftSize,
1970 unsigned &ShiftVal) {
1971 assert((MI.getOpcode() == TargetOpcode::G_SHL ||(static_cast <bool> ((MI.getOpcode() == TargetOpcode::G_SHL
|| MI.getOpcode() == TargetOpcode::G_LSHR || MI.getOpcode() ==
TargetOpcode::G_ASHR) && "Expected a shift") ? void (
0) : __assert_fail ("(MI.getOpcode() == TargetOpcode::G_SHL || MI.getOpcode() == TargetOpcode::G_LSHR || MI.getOpcode() == TargetOpcode::G_ASHR) && \"Expected a shift\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1973, __extension__
__PRETTY_FUNCTION__))
1972 MI.getOpcode() == TargetOpcode::G_LSHR ||(static_cast <bool> ((MI.getOpcode() == TargetOpcode::G_SHL
|| MI.getOpcode() == TargetOpcode::G_LSHR || MI.getOpcode() ==
TargetOpcode::G_ASHR) && "Expected a shift") ? void (
0) : __assert_fail ("(MI.getOpcode() == TargetOpcode::G_SHL || MI.getOpcode() == TargetOpcode::G_LSHR || MI.getOpcode() == TargetOpcode::G_ASHR) && \"Expected a shift\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1973, __extension__
__PRETTY_FUNCTION__))
1973 MI.getOpcode() == TargetOpcode::G_ASHR) && "Expected a shift")(static_cast <bool> ((MI.getOpcode() == TargetOpcode::G_SHL
|| MI.getOpcode() == TargetOpcode::G_LSHR || MI.getOpcode() ==
TargetOpcode::G_ASHR) && "Expected a shift") ? void (
0) : __assert_fail ("(MI.getOpcode() == TargetOpcode::G_SHL || MI.getOpcode() == TargetOpcode::G_LSHR || MI.getOpcode() == TargetOpcode::G_ASHR) && \"Expected a shift\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 1973, __extension__
__PRETTY_FUNCTION__))
;
1974
1975 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
1976 if (Ty.isVector()) // TODO:
1977 return false;
1978
1979 // Don't narrow further than the requested size.
1980 unsigned Size = Ty.getSizeInBits();
1981 if (Size <= TargetShiftSize)
1982 return false;
1983
1984 auto MaybeImmVal =
1985 getIConstantVRegValWithLookThrough(MI.getOperand(2).getReg(), MRI);
1986 if (!MaybeImmVal)
1987 return false;
1988
1989 ShiftVal = MaybeImmVal->Value.getSExtValue();
1990 return ShiftVal >= Size / 2 && ShiftVal < Size;
1991}
1992
1993void CombinerHelper::applyCombineShiftToUnmerge(MachineInstr &MI,
1994 const unsigned &ShiftVal) {
1995 Register DstReg = MI.getOperand(0).getReg();
1996 Register SrcReg = MI.getOperand(1).getReg();
1997 LLT Ty = MRI.getType(SrcReg);
1998 unsigned Size = Ty.getSizeInBits();
1999 unsigned HalfSize = Size / 2;
2000 assert(ShiftVal >= HalfSize)(static_cast <bool> (ShiftVal >= HalfSize) ? void (0
) : __assert_fail ("ShiftVal >= HalfSize", "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp"
, 2000, __extension__ __PRETTY_FUNCTION__))
;
2001
2002 LLT HalfTy = LLT::scalar(HalfSize);
2003
2004 Builder.setInstr(MI);
2005 auto Unmerge = Builder.buildUnmerge(HalfTy, SrcReg);
2006 unsigned NarrowShiftAmt = ShiftVal - HalfSize;
2007
2008 if (MI.getOpcode() == TargetOpcode::G_LSHR) {
2009 Register Narrowed = Unmerge.getReg(1);
2010
2011 // dst = G_LSHR s64:x, C for C >= 32
2012 // =>
2013 // lo, hi = G_UNMERGE_VALUES x
2014 // dst = G_MERGE_VALUES (G_LSHR hi, C - 32), 0
2015
2016 if (NarrowShiftAmt != 0) {
2017 Narrowed = Builder.buildLShr(HalfTy, Narrowed,
2018 Builder.buildConstant(HalfTy, NarrowShiftAmt)).getReg(0);
2019 }
2020
2021 auto Zero = Builder.buildConstant(HalfTy, 0);
2022 Builder.buildMergeLikeInstr(DstReg, {Narrowed, Zero});
2023 } else if (MI.getOpcode() == TargetOpcode::G_SHL) {
2024 Register Narrowed = Unmerge.getReg(0);
2025 // dst = G_SHL s64:x, C for C >= 32
2026 // =>
2027 // lo, hi = G_UNMERGE_VALUES x
2028 // dst = G_MERGE_VALUES 0, (G_SHL hi, C - 32)
2029 if (NarrowShiftAmt != 0) {
2030 Narrowed = Builder.buildShl(HalfTy, Narrowed,
2031 Builder.buildConstant(HalfTy, NarrowShiftAmt)).getReg(0);
2032 }
2033
2034 auto Zero = Builder.buildConstant(HalfTy, 0);
2035 Builder.buildMergeLikeInstr(DstReg, {Zero, Narrowed});
2036 } else {
2037 assert(MI.getOpcode() == TargetOpcode::G_ASHR)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_ASHR
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_ASHR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2037, __extension__
__PRETTY_FUNCTION__))
;
2038 auto Hi = Builder.buildAShr(
2039 HalfTy, Unmerge.getReg(1),
2040 Builder.buildConstant(HalfTy, HalfSize - 1));
2041
2042 if (ShiftVal == HalfSize) {
2043 // (G_ASHR i64:x, 32) ->
2044 // G_MERGE_VALUES hi_32(x), (G_ASHR hi_32(x), 31)
2045 Builder.buildMergeLikeInstr(DstReg, {Unmerge.getReg(1), Hi});
2046 } else if (ShiftVal == Size - 1) {
2047 // Don't need a second shift.
2048 // (G_ASHR i64:x, 63) ->
2049 // %narrowed = (G_ASHR hi_32(x), 31)
2050 // G_MERGE_VALUES %narrowed, %narrowed
2051 Builder.buildMergeLikeInstr(DstReg, {Hi, Hi});
2052 } else {
2053 auto Lo = Builder.buildAShr(
2054 HalfTy, Unmerge.getReg(1),
2055 Builder.buildConstant(HalfTy, ShiftVal - HalfSize));
2056
2057 // (G_ASHR i64:x, C) ->, for C >= 32
2058 // G_MERGE_VALUES (G_ASHR hi_32(x), C - 32), (G_ASHR hi_32(x), 31)
2059 Builder.buildMergeLikeInstr(DstReg, {Lo, Hi});
2060 }
2061 }
2062
2063 MI.eraseFromParent();
2064}
2065
2066bool CombinerHelper::tryCombineShiftToUnmerge(MachineInstr &MI,
2067 unsigned TargetShiftAmount) {
2068 unsigned ShiftAmt;
2069 if (matchCombineShiftToUnmerge(MI, TargetShiftAmount, ShiftAmt)) {
2070 applyCombineShiftToUnmerge(MI, ShiftAmt);
2071 return true;
2072 }
2073
2074 return false;
2075}
2076
2077bool CombinerHelper::matchCombineI2PToP2I(MachineInstr &MI, Register &Reg) {
2078 assert(MI.getOpcode() == TargetOpcode::G_INTTOPTR && "Expected a G_INTTOPTR")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_INTTOPTR
&& "Expected a G_INTTOPTR") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_INTTOPTR && \"Expected a G_INTTOPTR\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2078, __extension__
__PRETTY_FUNCTION__))
;
2079 Register DstReg = MI.getOperand(0).getReg();
2080 LLT DstTy = MRI.getType(DstReg);
2081 Register SrcReg = MI.getOperand(1).getReg();
2082 return mi_match(SrcReg, MRI,
2083 m_GPtrToInt(m_all_of(m_SpecificType(DstTy), m_Reg(Reg))));
2084}
2085
2086void CombinerHelper::applyCombineI2PToP2I(MachineInstr &MI, Register &Reg) {
2087 assert(MI.getOpcode() == TargetOpcode::G_INTTOPTR && "Expected a G_INTTOPTR")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_INTTOPTR
&& "Expected a G_INTTOPTR") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_INTTOPTR && \"Expected a G_INTTOPTR\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2087, __extension__
__PRETTY_FUNCTION__))
;
2088 Register DstReg = MI.getOperand(0).getReg();
2089 Builder.setInstr(MI);
2090 Builder.buildCopy(DstReg, Reg);
2091 MI.eraseFromParent();
2092}
2093
2094void CombinerHelper::applyCombineP2IToI2P(MachineInstr &MI, Register &Reg) {
2095 assert(MI.getOpcode() == TargetOpcode::G_PTRTOINT && "Expected a G_PTRTOINT")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_PTRTOINT
&& "Expected a G_PTRTOINT") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_PTRTOINT && \"Expected a G_PTRTOINT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2095, __extension__
__PRETTY_FUNCTION__))
;
2096 Register DstReg = MI.getOperand(0).getReg();
2097 Builder.setInstr(MI);
2098 Builder.buildZExtOrTrunc(DstReg, Reg);
2099 MI.eraseFromParent();
2100}
2101
2102bool CombinerHelper::matchCombineAddP2IToPtrAdd(
2103 MachineInstr &MI, std::pair<Register, bool> &PtrReg) {
2104 assert(MI.getOpcode() == TargetOpcode::G_ADD)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_ADD
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_ADD"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2104, __extension__
__PRETTY_FUNCTION__))
;
2105 Register LHS = MI.getOperand(1).getReg();
2106 Register RHS = MI.getOperand(2).getReg();
2107 LLT IntTy = MRI.getType(LHS);
2108
2109 // G_PTR_ADD always has the pointer in the LHS, so we may need to commute the
2110 // instruction.
2111 PtrReg.second = false;
2112 for (Register SrcReg : {LHS, RHS}) {
2113 if (mi_match(SrcReg, MRI, m_GPtrToInt(m_Reg(PtrReg.first)))) {
2114 // Don't handle cases where the integer is implicitly converted to the
2115 // pointer width.
2116 LLT PtrTy = MRI.getType(PtrReg.first);
2117 if (PtrTy.getScalarSizeInBits() == IntTy.getScalarSizeInBits())
2118 return true;
2119 }
2120
2121 PtrReg.second = true;
2122 }
2123
2124 return false;
2125}
2126
2127void CombinerHelper::applyCombineAddP2IToPtrAdd(
2128 MachineInstr &MI, std::pair<Register, bool> &PtrReg) {
2129 Register Dst = MI.getOperand(0).getReg();
2130 Register LHS = MI.getOperand(1).getReg();
2131 Register RHS = MI.getOperand(2).getReg();
2132
2133 const bool DoCommute = PtrReg.second;
2134 if (DoCommute)
2135 std::swap(LHS, RHS);
2136 LHS = PtrReg.first;
2137
2138 LLT PtrTy = MRI.getType(LHS);
2139
2140 Builder.setInstrAndDebugLoc(MI);
2141 auto PtrAdd = Builder.buildPtrAdd(PtrTy, LHS, RHS);
2142 Builder.buildPtrToInt(Dst, PtrAdd);
2143 MI.eraseFromParent();
2144}
2145
2146bool CombinerHelper::matchCombineConstPtrAddToI2P(MachineInstr &MI,
2147 APInt &NewCst) {
2148 auto &PtrAdd = cast<GPtrAdd>(MI);
2149 Register LHS = PtrAdd.getBaseReg();
2150 Register RHS = PtrAdd.getOffsetReg();
2151 MachineRegisterInfo &MRI = Builder.getMF().getRegInfo();
2152
2153 if (auto RHSCst = getIConstantVRegVal(RHS, MRI)) {
2154 APInt Cst;
2155 if (mi_match(LHS, MRI, m_GIntToPtr(m_ICst(Cst)))) {
2156 auto DstTy = MRI.getType(PtrAdd.getReg(0));
2157 // G_INTTOPTR uses zero-extension
2158 NewCst = Cst.zextOrTrunc(DstTy.getSizeInBits());
2159 NewCst += RHSCst->sextOrTrunc(DstTy.getSizeInBits());
2160 return true;
2161 }
2162 }
2163
2164 return false;
2165}
2166
2167void CombinerHelper::applyCombineConstPtrAddToI2P(MachineInstr &MI,
2168 APInt &NewCst) {
2169 auto &PtrAdd = cast<GPtrAdd>(MI);
2170 Register Dst = PtrAdd.getReg(0);
2171
2172 Builder.setInstrAndDebugLoc(MI);
2173 Builder.buildConstant(Dst, NewCst);
2174 PtrAdd.eraseFromParent();
2175}
2176
2177bool CombinerHelper::matchCombineAnyExtTrunc(MachineInstr &MI, Register &Reg) {
2178 assert(MI.getOpcode() == TargetOpcode::G_ANYEXT && "Expected a G_ANYEXT")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_ANYEXT
&& "Expected a G_ANYEXT") ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_ANYEXT && \"Expected a G_ANYEXT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2178, __extension__
__PRETTY_FUNCTION__))
;
2179 Register DstReg = MI.getOperand(0).getReg();
2180 Register SrcReg = MI.getOperand(1).getReg();
2181 LLT DstTy = MRI.getType(DstReg);
2182 return mi_match(SrcReg, MRI,
2183 m_GTrunc(m_all_of(m_Reg(Reg), m_SpecificType(DstTy))));
2184}
2185
2186bool CombinerHelper::matchCombineZextTrunc(MachineInstr &MI, Register &Reg) {
2187 assert(MI.getOpcode() == TargetOpcode::G_ZEXT && "Expected a G_ZEXT")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_ZEXT
&& "Expected a G_ZEXT") ? void (0) : __assert_fail (
"MI.getOpcode() == TargetOpcode::G_ZEXT && \"Expected a G_ZEXT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2187, __extension__
__PRETTY_FUNCTION__))
;
2188 Register DstReg = MI.getOperand(0).getReg();
2189 Register SrcReg = MI.getOperand(1).getReg();
2190 LLT DstTy = MRI.getType(DstReg);
2191 if (mi_match(SrcReg, MRI,
2192 m_GTrunc(m_all_of(m_Reg(Reg), m_SpecificType(DstTy))))) {
2193 unsigned DstSize = DstTy.getScalarSizeInBits();
2194 unsigned SrcSize = MRI.getType(SrcReg).getScalarSizeInBits();
2195 return KB->getKnownBits(Reg).countMinLeadingZeros() >= DstSize - SrcSize;
2196 }
2197 return false;
2198}
2199
2200bool CombinerHelper::matchCombineExtOfExt(
2201 MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo) {
2202 assert((MI.getOpcode() == TargetOpcode::G_ANYEXT ||(static_cast <bool> ((MI.getOpcode() == TargetOpcode::G_ANYEXT
|| MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() ==
TargetOpcode::G_ZEXT) && "Expected a G_[ASZ]EXT") ? void
(0) : __assert_fail ("(MI.getOpcode() == TargetOpcode::G_ANYEXT || MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() == TargetOpcode::G_ZEXT) && \"Expected a G_[ASZ]EXT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2205, __extension__
__PRETTY_FUNCTION__))
2203 MI.getOpcode() == TargetOpcode::G_SEXT ||(static_cast <bool> ((MI.getOpcode() == TargetOpcode::G_ANYEXT
|| MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() ==
TargetOpcode::G_ZEXT) && "Expected a G_[ASZ]EXT") ? void
(0) : __assert_fail ("(MI.getOpcode() == TargetOpcode::G_ANYEXT || MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() == TargetOpcode::G_ZEXT) && \"Expected a G_[ASZ]EXT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2205, __extension__
__PRETTY_FUNCTION__))
2204 MI.getOpcode() == TargetOpcode::G_ZEXT) &&(static_cast <bool> ((MI.getOpcode() == TargetOpcode::G_ANYEXT
|| MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() ==
TargetOpcode::G_ZEXT) && "Expected a G_[ASZ]EXT") ? void
(0) : __assert_fail ("(MI.getOpcode() == TargetOpcode::G_ANYEXT || MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() == TargetOpcode::G_ZEXT) && \"Expected a G_[ASZ]EXT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2205, __extension__
__PRETTY_FUNCTION__))
2205 "Expected a G_[ASZ]EXT")(static_cast <bool> ((MI.getOpcode() == TargetOpcode::G_ANYEXT
|| MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() ==
TargetOpcode::G_ZEXT) && "Expected a G_[ASZ]EXT") ? void
(0) : __assert_fail ("(MI.getOpcode() == TargetOpcode::G_ANYEXT || MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() == TargetOpcode::G_ZEXT) && \"Expected a G_[ASZ]EXT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2205, __extension__
__PRETTY_FUNCTION__))
;
2206 Register SrcReg = MI.getOperand(1).getReg();
2207 MachineInstr *SrcMI = MRI.getVRegDef(SrcReg);
2208 // Match exts with the same opcode, anyext([sz]ext) and sext(zext).
2209 unsigned Opc = MI.getOpcode();
2210 unsigned SrcOpc = SrcMI->getOpcode();
2211 if (Opc == SrcOpc ||
2212 (Opc == TargetOpcode::G_ANYEXT &&
2213 (SrcOpc == TargetOpcode::G_SEXT || SrcOpc == TargetOpcode::G_ZEXT)) ||
2214 (Opc == TargetOpcode::G_SEXT && SrcOpc == TargetOpcode::G_ZEXT)) {
2215 MatchInfo = std::make_tuple(SrcMI->getOperand(1).getReg(), SrcOpc);
2216 return true;
2217 }
2218 return false;
2219}
2220
2221void CombinerHelper::applyCombineExtOfExt(
2222 MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo) {
2223 assert((MI.getOpcode() == TargetOpcode::G_ANYEXT ||(static_cast <bool> ((MI.getOpcode() == TargetOpcode::G_ANYEXT
|| MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() ==
TargetOpcode::G_ZEXT) && "Expected a G_[ASZ]EXT") ? void
(0) : __assert_fail ("(MI.getOpcode() == TargetOpcode::G_ANYEXT || MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() == TargetOpcode::G_ZEXT) && \"Expected a G_[ASZ]EXT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2226, __extension__
__PRETTY_FUNCTION__))
2224 MI.getOpcode() == TargetOpcode::G_SEXT ||(static_cast <bool> ((MI.getOpcode() == TargetOpcode::G_ANYEXT
|| MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() ==
TargetOpcode::G_ZEXT) && "Expected a G_[ASZ]EXT") ? void
(0) : __assert_fail ("(MI.getOpcode() == TargetOpcode::G_ANYEXT || MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() == TargetOpcode::G_ZEXT) && \"Expected a G_[ASZ]EXT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2226, __extension__
__PRETTY_FUNCTION__))
2225 MI.getOpcode() == TargetOpcode::G_ZEXT) &&(static_cast <bool> ((MI.getOpcode() == TargetOpcode::G_ANYEXT
|| MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() ==
TargetOpcode::G_ZEXT) && "Expected a G_[ASZ]EXT") ? void
(0) : __assert_fail ("(MI.getOpcode() == TargetOpcode::G_ANYEXT || MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() == TargetOpcode::G_ZEXT) && \"Expected a G_[ASZ]EXT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2226, __extension__
__PRETTY_FUNCTION__))
2226 "Expected a G_[ASZ]EXT")(static_cast <bool> ((MI.getOpcode() == TargetOpcode::G_ANYEXT
|| MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() ==
TargetOpcode::G_ZEXT) && "Expected a G_[ASZ]EXT") ? void
(0) : __assert_fail ("(MI.getOpcode() == TargetOpcode::G_ANYEXT || MI.getOpcode() == TargetOpcode::G_SEXT || MI.getOpcode() == TargetOpcode::G_ZEXT) && \"Expected a G_[ASZ]EXT\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2226, __extension__
__PRETTY_FUNCTION__))
;
2227
2228 Register Reg = std::get<0>(MatchInfo);
2229 unsigned SrcExtOp = std::get<1>(MatchInfo);
2230
2231 // Combine exts with the same opcode.
2232 if (MI.getOpcode() == SrcExtOp) {
2233 Observer.changingInstr(MI);
2234 MI.getOperand(1).setReg(Reg);
2235 Observer.changedInstr(MI);
2236 return;
2237 }
2238
2239 // Combine:
2240 // - anyext([sz]ext x) to [sz]ext x
2241 // - sext(zext x) to zext x
2242 if (MI.getOpcode() == TargetOpcode::G_ANYEXT ||
2243 (MI.getOpcode() == TargetOpcode::G_SEXT &&
2244 SrcExtOp == TargetOpcode::G_ZEXT)) {
2245 Register DstReg = MI.getOperand(0).getReg();
2246 Builder.setInstrAndDebugLoc(MI);
2247 Builder.buildInstr(SrcExtOp, {DstReg}, {Reg});
2248 MI.eraseFromParent();
2249 }
2250}
2251
2252void CombinerHelper::applyCombineMulByNegativeOne(MachineInstr &MI) {
2253 assert(MI.getOpcode() == TargetOpcode::G_MUL && "Expected a G_MUL")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_MUL
&& "Expected a G_MUL") ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_MUL && \"Expected a G_MUL\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2253, __extension__
__PRETTY_FUNCTION__))
;
2254 Register DstReg = MI.getOperand(0).getReg();
2255 Register SrcReg = MI.getOperand(1).getReg();
2256 LLT DstTy = MRI.getType(DstReg);
2257
2258 Builder.setInstrAndDebugLoc(MI);
2259 Builder.buildSub(DstReg, Builder.buildConstant(DstTy, 0), SrcReg,
2260 MI.getFlags());
2261 MI.eraseFromParent();
2262}
2263
2264bool CombinerHelper::matchCombineFAbsOfFNeg(MachineInstr &MI,
2265 BuildFnTy &MatchInfo) {
2266 assert(MI.getOpcode() == TargetOpcode::G_FABS && "Expected a G_FABS")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_FABS
&& "Expected a G_FABS") ? void (0) : __assert_fail (
"MI.getOpcode() == TargetOpcode::G_FABS && \"Expected a G_FABS\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2266, __extension__
__PRETTY_FUNCTION__))
;
2267 Register Src = MI.getOperand(1).getReg();
2268 Register NegSrc;
2269
2270 if (!mi_match(Src, MRI, m_GFNeg(m_Reg(NegSrc))))
2271 return false;
2272
2273 MatchInfo = [=, &MI](MachineIRBuilder &B) {
2274 Observer.changingInstr(MI);
2275 MI.getOperand(1).setReg(NegSrc);
2276 Observer.changedInstr(MI);
2277 };
2278 return true;
2279}
2280
2281bool CombinerHelper::matchCombineTruncOfExt(
2282 MachineInstr &MI, std::pair<Register, unsigned> &MatchInfo) {
2283 assert(MI.getOpcode() == TargetOpcode::G_TRUNC && "Expected a G_TRUNC")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_TRUNC
&& "Expected a G_TRUNC") ? void (0) : __assert_fail (
"MI.getOpcode() == TargetOpcode::G_TRUNC && \"Expected a G_TRUNC\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2283, __extension__
__PRETTY_FUNCTION__))
;
2284 Register SrcReg = MI.getOperand(1).getReg();
2285 MachineInstr *SrcMI = MRI.getVRegDef(SrcReg);
2286 unsigned SrcOpc = SrcMI->getOpcode();
2287 if (SrcOpc == TargetOpcode::G_ANYEXT || SrcOpc == TargetOpcode::G_SEXT ||
2288 SrcOpc == TargetOpcode::G_ZEXT) {
2289 MatchInfo = std::make_pair(SrcMI->getOperand(1).getReg(), SrcOpc);
2290 return true;
2291 }
2292 return false;
2293}
2294
2295void CombinerHelper::applyCombineTruncOfExt(
2296 MachineInstr &MI, std::pair<Register, unsigned> &MatchInfo) {
2297 assert(MI.getOpcode() == TargetOpcode::G_TRUNC && "Expected a G_TRUNC")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_TRUNC
&& "Expected a G_TRUNC") ? void (0) : __assert_fail (
"MI.getOpcode() == TargetOpcode::G_TRUNC && \"Expected a G_TRUNC\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2297, __extension__
__PRETTY_FUNCTION__))
;
2298 Register SrcReg = MatchInfo.first;
2299 unsigned SrcExtOp = MatchInfo.second;
2300 Register DstReg = MI.getOperand(0).getReg();
2301 LLT SrcTy = MRI.getType(SrcReg);
2302 LLT DstTy = MRI.getType(DstReg);
2303 if (SrcTy == DstTy) {
2304 MI.eraseFromParent();
2305 replaceRegWith(MRI, DstReg, SrcReg);
2306 return;
2307 }
2308 Builder.setInstrAndDebugLoc(MI);
2309 if (SrcTy.getSizeInBits() < DstTy.getSizeInBits())
2310 Builder.buildInstr(SrcExtOp, {DstReg}, {SrcReg});
2311 else
2312 Builder.buildTrunc(DstReg, SrcReg);
2313 MI.eraseFromParent();
2314}
2315
2316static LLT getMidVTForTruncRightShiftCombine(LLT ShiftTy, LLT TruncTy) {
2317 const unsigned ShiftSize = ShiftTy.getScalarSizeInBits();
2318 const unsigned TruncSize = TruncTy.getScalarSizeInBits();
2319
2320 // ShiftTy > 32 > TruncTy -> 32
2321 if (ShiftSize > 32 && TruncSize < 32)
2322 return ShiftTy.changeElementSize(32);
2323
2324 // TODO: We could also reduce to 16 bits, but that's more target-dependent.
2325 // Some targets like it, some don't, some only like it under certain
2326 // conditions/processor versions, etc.
2327 // A TL hook might be needed for this.
2328
2329 // Don't combine
2330 return ShiftTy;
2331}
2332
2333bool CombinerHelper::matchCombineTruncOfShift(
2334 MachineInstr &MI, std::pair<MachineInstr *, LLT> &MatchInfo) {
2335 assert(MI.getOpcode() == TargetOpcode::G_TRUNC && "Expected a G_TRUNC")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_TRUNC
&& "Expected a G_TRUNC") ? void (0) : __assert_fail (
"MI.getOpcode() == TargetOpcode::G_TRUNC && \"Expected a G_TRUNC\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2335, __extension__
__PRETTY_FUNCTION__))
;
2336 Register DstReg = MI.getOperand(0).getReg();
2337 Register SrcReg = MI.getOperand(1).getReg();
2338
2339 if (!MRI.hasOneNonDBGUse(SrcReg))
2340 return false;
2341
2342 LLT SrcTy = MRI.getType(SrcReg);
2343 LLT DstTy = MRI.getType(DstReg);
2344
2345 MachineInstr *SrcMI = getDefIgnoringCopies(SrcReg, MRI);
2346 const auto &TL = getTargetLowering();
2347
2348 LLT NewShiftTy;
2349 switch (SrcMI->getOpcode()) {
2350 default:
2351 return false;
2352 case TargetOpcode::G_SHL: {
2353 NewShiftTy = DstTy;
2354
2355 // Make sure new shift amount is legal.
2356 KnownBits Known = KB->getKnownBits(SrcMI->getOperand(2).getReg());
2357 if (Known.getMaxValue().uge(NewShiftTy.getScalarSizeInBits()))
2358 return false;
2359 break;
2360 }
2361 case TargetOpcode::G_LSHR:
2362 case TargetOpcode::G_ASHR: {
2363 // For right shifts, we conservatively do not do the transform if the TRUNC
2364 // has any STORE users. The reason is that if we change the type of the
2365 // shift, we may break the truncstore combine.
2366 //
2367 // TODO: Fix truncstore combine to handle (trunc(lshr (trunc x), k)).
2368 for (auto &User : MRI.use_instructions(DstReg))
2369 if (User.getOpcode() == TargetOpcode::G_STORE)
2370 return false;
2371
2372 NewShiftTy = getMidVTForTruncRightShiftCombine(SrcTy, DstTy);
2373 if (NewShiftTy == SrcTy)
2374 return false;
2375
2376 // Make sure we won't lose information by truncating the high bits.
2377 KnownBits Known = KB->getKnownBits(SrcMI->getOperand(2).getReg());
2378 if (Known.getMaxValue().ugt(NewShiftTy.getScalarSizeInBits() -
2379 DstTy.getScalarSizeInBits()))
2380 return false;
2381 break;
2382 }
2383 }
2384
2385 if (!isLegalOrBeforeLegalizer(
2386 {SrcMI->getOpcode(),
2387 {NewShiftTy, TL.getPreferredShiftAmountTy(NewShiftTy)}}))
2388 return false;
2389
2390 MatchInfo = std::make_pair(SrcMI, NewShiftTy);
2391 return true;
2392}
2393
2394void CombinerHelper::applyCombineTruncOfShift(
2395 MachineInstr &MI, std::pair<MachineInstr *, LLT> &MatchInfo) {
2396 Builder.setInstrAndDebugLoc(MI);
2397
2398 MachineInstr *ShiftMI = MatchInfo.first;
2399 LLT NewShiftTy = MatchInfo.second;
2400
2401 Register Dst = MI.getOperand(0).getReg();
2402 LLT DstTy = MRI.getType(Dst);
2403
2404 Register ShiftAmt = ShiftMI->getOperand(2).getReg();
2405 Register ShiftSrc = ShiftMI->getOperand(1).getReg();
2406 ShiftSrc = Builder.buildTrunc(NewShiftTy, ShiftSrc).getReg(0);
2407
2408 Register NewShift =
2409 Builder
2410 .buildInstr(ShiftMI->getOpcode(), {NewShiftTy}, {ShiftSrc, ShiftAmt})
2411 .getReg(0);
2412
2413 if (NewShiftTy == DstTy)
2414 replaceRegWith(MRI, Dst, NewShift);
2415 else
2416 Builder.buildTrunc(Dst, NewShift);
2417
2418 eraseInst(MI);
2419}
2420
2421bool CombinerHelper::matchAnyExplicitUseIsUndef(MachineInstr &MI) {
2422 return any_of(MI.explicit_uses(), [this](const MachineOperand &MO) {
2423 return MO.isReg() &&
2424 getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MO.getReg(), MRI);
2425 });
2426}
2427
2428bool CombinerHelper::matchAllExplicitUsesAreUndef(MachineInstr &MI) {
2429 return all_of(MI.explicit_uses(), [this](const MachineOperand &MO) {
2430 return !MO.isReg() ||
2431 getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MO.getReg(), MRI);
2432 });
2433}
2434
2435bool CombinerHelper::matchUndefShuffleVectorMask(MachineInstr &MI) {
2436 assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2436, __extension__
__PRETTY_FUNCTION__))
;
2437 ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
2438 return all_of(Mask, [](int Elt) { return Elt < 0; });
2439}
2440
2441bool CombinerHelper::matchUndefStore(MachineInstr &MI) {
2442 assert(MI.getOpcode() == TargetOpcode::G_STORE)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_STORE
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_STORE"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2442, __extension__
__PRETTY_FUNCTION__))
;
2443 return getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MI.getOperand(0).getReg(),
2444 MRI);
2445}
2446
2447bool CombinerHelper::matchUndefSelectCmp(MachineInstr &MI) {
2448 assert(MI.getOpcode() == TargetOpcode::G_SELECT)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SELECT
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_SELECT"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2448, __extension__
__PRETTY_FUNCTION__))
;
2449 return getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MI.getOperand(1).getReg(),
2450 MRI);
2451}
2452
2453bool CombinerHelper::matchInsertExtractVecEltOutOfBounds(MachineInstr &MI) {
2454 assert((MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT ||(static_cast <bool> ((MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT
|| MI.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT) &&
"Expected an insert/extract element op") ? void (0) : __assert_fail
("(MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT || MI.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT) && \"Expected an insert/extract element op\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2456, __extension__
__PRETTY_FUNCTION__))
2455 MI.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT) &&(static_cast <bool> ((MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT
|| MI.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT) &&
"Expected an insert/extract element op") ? void (0) : __assert_fail
("(MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT || MI.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT) && \"Expected an insert/extract element op\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2456, __extension__
__PRETTY_FUNCTION__))
2456 "Expected an insert/extract element op")(static_cast <bool> ((MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT
|| MI.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT) &&
"Expected an insert/extract element op") ? void (0) : __assert_fail
("(MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT || MI.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT) && \"Expected an insert/extract element op\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2456, __extension__
__PRETTY_FUNCTION__))
;
2457 LLT VecTy = MRI.getType(MI.getOperand(1).getReg());
2458 unsigned IdxIdx =
2459 MI.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT ? 2 : 3;
2460 auto Idx = getIConstantVRegVal(MI.getOperand(IdxIdx).getReg(), MRI);
2461 if (!Idx)
2462 return false;
2463 return Idx->getZExtValue() >= VecTy.getNumElements();
2464}
2465
2466bool CombinerHelper::matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx) {
2467 GSelect &SelMI = cast<GSelect>(MI);
2468 auto Cst =
2469 isConstantOrConstantSplatVector(*MRI.getVRegDef(SelMI.getCondReg()), MRI);
2470 if (!Cst)
2471 return false;
2472 OpIdx = Cst->isZero() ? 3 : 2;
2473 return true;
2474}
2475
2476bool CombinerHelper::eraseInst(MachineInstr &MI) {
2477 MI.eraseFromParent();
2478 return true;
2479}
2480
2481bool CombinerHelper::matchEqualDefs(const MachineOperand &MOP1,
2482 const MachineOperand &MOP2) {
2483 if (!MOP1.isReg() || !MOP2.isReg())
2484 return false;
2485 auto InstAndDef1 = getDefSrcRegIgnoringCopies(MOP1.getReg(), MRI);
2486 if (!InstAndDef1)
2487 return false;
2488 auto InstAndDef2 = getDefSrcRegIgnoringCopies(MOP2.getReg(), MRI);
2489 if (!InstAndDef2)
2490 return false;
2491 MachineInstr *I1 = InstAndDef1->MI;
2492 MachineInstr *I2 = InstAndDef2->MI;
2493
2494 // Handle a case like this:
2495 //
2496 // %0:_(s64), %1:_(s64) = G_UNMERGE_VALUES %2:_(<2 x s64>)
2497 //
2498 // Even though %0 and %1 are produced by the same instruction they are not
2499 // the same values.
2500 if (I1 == I2)
2501 return MOP1.getReg() == MOP2.getReg();
2502
2503 // If we have an instruction which loads or stores, we can't guarantee that
2504 // it is identical.
2505 //
2506 // For example, we may have
2507 //
2508 // %x1 = G_LOAD %addr (load N from @somewhere)
2509 // ...
2510 // call @foo
2511 // ...
2512 // %x2 = G_LOAD %addr (load N from @somewhere)
2513 // ...
2514 // %or = G_OR %x1, %x2
2515 //
2516 // It's possible that @foo will modify whatever lives at the address we're
2517 // loading from. To be safe, let's just assume that all loads and stores
2518 // are different (unless we have something which is guaranteed to not
2519 // change.)
2520 if (I1->mayLoadOrStore() && !I1->isDereferenceableInvariantLoad())
2521 return false;
2522
2523 // If both instructions are loads or stores, they are equal only if both
2524 // are dereferenceable invariant loads with the same number of bits.
2525 if (I1->mayLoadOrStore() && I2->mayLoadOrStore()) {
2526 GLoadStore *LS1 = dyn_cast<GLoadStore>(I1);
2527 GLoadStore *LS2 = dyn_cast<GLoadStore>(I2);
2528 if (!LS1 || !LS2)
2529 return false;
2530
2531 if (!I2->isDereferenceableInvariantLoad() ||
2532 (LS1->getMemSizeInBits() != LS2->getMemSizeInBits()))
2533 return false;
2534 }
2535
2536 // Check for physical registers on the instructions first to avoid cases
2537 // like this:
2538 //
2539 // %a = COPY $physreg
2540 // ...
2541 // SOMETHING implicit-def $physreg
2542 // ...
2543 // %b = COPY $physreg
2544 //
2545 // These copies are not equivalent.
2546 if (any_of(I1->uses(), [](const MachineOperand &MO) {
2547 return MO.isReg() && MO.getReg().isPhysical();
2548 })) {
2549 // Check if we have a case like this:
2550 //
2551 // %a = COPY $physreg
2552 // %b = COPY %a
2553 //
2554 // In this case, I1 and I2 will both be equal to %a = COPY $physreg.
2555 // From that, we know that they must have the same value, since they must
2556 // have come from the same COPY.
2557 return I1->isIdenticalTo(*I2);
2558 }
2559
2560 // We don't have any physical registers, so we don't necessarily need the
2561 // same vreg defs.
2562 //
2563 // On the off-chance that there's some target instruction feeding into the
2564 // instruction, let's use produceSameValue instead of isIdenticalTo.
2565 if (Builder.getTII().produceSameValue(*I1, *I2, &MRI)) {
2566 // Handle instructions with multiple defs that produce same values. Values
2567 // are same for operands with same index.
2568 // %0:_(s8), %1:_(s8), %2:_(s8), %3:_(s8) = G_UNMERGE_VALUES %4:_(<4 x s8>)
2569 // %5:_(s8), %6:_(s8), %7:_(s8), %8:_(s8) = G_UNMERGE_VALUES %4:_(<4 x s8>)
2570 // I1 and I2 are different instructions but produce same values,
2571 // %1 and %6 are same, %1 and %7 are not the same value.
2572 return I1->findRegisterDefOperandIdx(InstAndDef1->Reg) ==
2573 I2->findRegisterDefOperandIdx(InstAndDef2->Reg);
2574 }
2575 return false;
2576}
2577
2578bool CombinerHelper::matchConstantOp(const MachineOperand &MOP, int64_t C) {
2579 if (!MOP.isReg())
2580 return false;
2581 auto *MI = MRI.getVRegDef(MOP.getReg());
2582 auto MaybeCst = isConstantOrConstantSplatVector(*MI, MRI);
2583 return MaybeCst && MaybeCst->getBitWidth() <= 64 &&
2584 MaybeCst->getSExtValue() == C;
2585}
2586
2587bool CombinerHelper::replaceSingleDefInstWithOperand(MachineInstr &MI,
2588 unsigned OpIdx) {
2589 assert(MI.getNumExplicitDefs() == 1 && "Expected one explicit def?")(static_cast <bool> (MI.getNumExplicitDefs() == 1 &&
"Expected one explicit def?") ? void (0) : __assert_fail ("MI.getNumExplicitDefs() == 1 && \"Expected one explicit def?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2589, __extension__
__PRETTY_FUNCTION__))
;
2590 Register OldReg = MI.getOperand(0).getReg();
2591 Register Replacement = MI.getOperand(OpIdx).getReg();
2592 assert(canReplaceReg(OldReg, Replacement, MRI) && "Cannot replace register?")(static_cast <bool> (canReplaceReg(OldReg, Replacement,
MRI) && "Cannot replace register?") ? void (0) : __assert_fail
("canReplaceReg(OldReg, Replacement, MRI) && \"Cannot replace register?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2592, __extension__
__PRETTY_FUNCTION__))
;
2593 MI.eraseFromParent();
2594 replaceRegWith(MRI, OldReg, Replacement);
2595 return true;
2596}
2597
2598bool CombinerHelper::replaceSingleDefInstWithReg(MachineInstr &MI,
2599 Register Replacement) {
2600 assert(MI.getNumExplicitDefs() == 1 && "Expected one explicit def?")(static_cast <bool> (MI.getNumExplicitDefs() == 1 &&
"Expected one explicit def?") ? void (0) : __assert_fail ("MI.getNumExplicitDefs() == 1 && \"Expected one explicit def?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2600, __extension__
__PRETTY_FUNCTION__))
;
2601 Register OldReg = MI.getOperand(0).getReg();
2602 assert(canReplaceReg(OldReg, Replacement, MRI) && "Cannot replace register?")(static_cast <bool> (canReplaceReg(OldReg, Replacement,
MRI) && "Cannot replace register?") ? void (0) : __assert_fail
("canReplaceReg(OldReg, Replacement, MRI) && \"Cannot replace register?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2602, __extension__
__PRETTY_FUNCTION__))
;
2603 MI.eraseFromParent();
2604 replaceRegWith(MRI, OldReg, Replacement);
2605 return true;
2606}
2607
2608bool CombinerHelper::matchSelectSameVal(MachineInstr &MI) {
2609 assert(MI.getOpcode() == TargetOpcode::G_SELECT)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SELECT
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_SELECT"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2609, __extension__
__PRETTY_FUNCTION__))
;
2610 // Match (cond ? x : x)
2611 return matchEqualDefs(MI.getOperand(2), MI.getOperand(3)) &&
2612 canReplaceReg(MI.getOperand(0).getReg(), MI.getOperand(2).getReg(),
2613 MRI);
2614}
2615
2616bool CombinerHelper::matchBinOpSameVal(MachineInstr &MI) {
2617 return matchEqualDefs(MI.getOperand(1), MI.getOperand(2)) &&
2618 canReplaceReg(MI.getOperand(0).getReg(), MI.getOperand(1).getReg(),
2619 MRI);
2620}
2621
2622bool CombinerHelper::matchOperandIsZero(MachineInstr &MI, unsigned OpIdx) {
2623 return matchConstantOp(MI.getOperand(OpIdx), 0) &&
2624 canReplaceReg(MI.getOperand(0).getReg(), MI.getOperand(OpIdx).getReg(),
2625 MRI);
2626}
2627
2628bool CombinerHelper::matchOperandIsUndef(MachineInstr &MI, unsigned OpIdx) {
2629 MachineOperand &MO = MI.getOperand(OpIdx);
2630 return MO.isReg() &&
2631 getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MO.getReg(), MRI);
2632}
2633
2634bool CombinerHelper::matchOperandIsKnownToBeAPowerOfTwo(MachineInstr &MI,
2635 unsigned OpIdx) {
2636 MachineOperand &MO = MI.getOperand(OpIdx);
2637 return isKnownToBeAPowerOfTwo(MO.getReg(), MRI, KB);
2638}
2639
2640bool CombinerHelper::replaceInstWithFConstant(MachineInstr &MI, double C) {
2641 assert(MI.getNumDefs() == 1 && "Expected only one def?")(static_cast <bool> (MI.getNumDefs() == 1 && "Expected only one def?"
) ? void (0) : __assert_fail ("MI.getNumDefs() == 1 && \"Expected only one def?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2641, __extension__
__PRETTY_FUNCTION__))
;
2642 Builder.setInstr(MI);
2643 Builder.buildFConstant(MI.getOperand(0), C);
2644 MI.eraseFromParent();
2645 return true;
2646}
2647
2648bool CombinerHelper::replaceInstWithConstant(MachineInstr &MI, int64_t C) {
2649 assert(MI.getNumDefs() == 1 && "Expected only one def?")(static_cast <bool> (MI.getNumDefs() == 1 && "Expected only one def?"
) ? void (0) : __assert_fail ("MI.getNumDefs() == 1 && \"Expected only one def?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2649, __extension__
__PRETTY_FUNCTION__))
;
2650 Builder.setInstr(MI);
2651 Builder.buildConstant(MI.getOperand(0), C);
2652 MI.eraseFromParent();
2653 return true;
2654}
2655
2656bool CombinerHelper::replaceInstWithConstant(MachineInstr &MI, APInt C) {
2657 assert(MI.getNumDefs() == 1 && "Expected only one def?")(static_cast <bool> (MI.getNumDefs() == 1 && "Expected only one def?"
) ? void (0) : __assert_fail ("MI.getNumDefs() == 1 && \"Expected only one def?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2657, __extension__
__PRETTY_FUNCTION__))
;
2658 Builder.setInstr(MI);
2659 Builder.buildConstant(MI.getOperand(0), C);
2660 MI.eraseFromParent();
2661 return true;
2662}
2663
2664bool CombinerHelper::replaceInstWithUndef(MachineInstr &MI) {
2665 assert(MI.getNumDefs() == 1 && "Expected only one def?")(static_cast <bool> (MI.getNumDefs() == 1 && "Expected only one def?"
) ? void (0) : __assert_fail ("MI.getNumDefs() == 1 && \"Expected only one def?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2665, __extension__
__PRETTY_FUNCTION__))
;
2666 Builder.setInstr(MI);
2667 Builder.buildUndef(MI.getOperand(0));
2668 MI.eraseFromParent();
2669 return true;
2670}
2671
2672bool CombinerHelper::matchSimplifyAddToSub(
2673 MachineInstr &MI, std::tuple<Register, Register> &MatchInfo) {
2674 Register LHS = MI.getOperand(1).getReg();
2675 Register RHS = MI.getOperand(2).getReg();
2676 Register &NewLHS = std::get<0>(MatchInfo);
2677 Register &NewRHS = std::get<1>(MatchInfo);
2678
2679 // Helper lambda to check for opportunities for
2680 // ((0-A) + B) -> B - A
2681 // (A + (0-B)) -> A - B
2682 auto CheckFold = [&](Register &MaybeSub, Register &MaybeNewLHS) {
2683 if (!mi_match(MaybeSub, MRI, m_Neg(m_Reg(NewRHS))))
2684 return false;
2685 NewLHS = MaybeNewLHS;
2686 return true;
2687 };
2688
2689 return CheckFold(LHS, RHS) || CheckFold(RHS, LHS);
2690}
2691
2692bool CombinerHelper::matchCombineInsertVecElts(
2693 MachineInstr &MI, SmallVectorImpl<Register> &MatchInfo) {
2694 assert(MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT &&(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT
&& "Invalid opcode") ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT && \"Invalid opcode\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2695, __extension__
__PRETTY_FUNCTION__))
2695 "Invalid opcode")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT
&& "Invalid opcode") ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT && \"Invalid opcode\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2695, __extension__
__PRETTY_FUNCTION__))
;
2696 Register DstReg = MI.getOperand(0).getReg();
2697 LLT DstTy = MRI.getType(DstReg);
2698 assert(DstTy.isVector() && "Invalid G_INSERT_VECTOR_ELT?")(static_cast <bool> (DstTy.isVector() && "Invalid G_INSERT_VECTOR_ELT?"
) ? void (0) : __assert_fail ("DstTy.isVector() && \"Invalid G_INSERT_VECTOR_ELT?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2698, __extension__
__PRETTY_FUNCTION__))
;
2699 unsigned NumElts = DstTy.getNumElements();
2700 // If this MI is part of a sequence of insert_vec_elts, then
2701 // don't do the combine in the middle of the sequence.
2702 if (MRI.hasOneUse(DstReg) && MRI.use_instr_begin(DstReg)->getOpcode() ==
2703 TargetOpcode::G_INSERT_VECTOR_ELT)
2704 return false;
2705 MachineInstr *CurrInst = &MI;
2706 MachineInstr *TmpInst;
2707 int64_t IntImm;
2708 Register TmpReg;
2709 MatchInfo.resize(NumElts);
2710 while (mi_match(
2711 CurrInst->getOperand(0).getReg(), MRI,
2712 m_GInsertVecElt(m_MInstr(TmpInst), m_Reg(TmpReg), m_ICst(IntImm)))) {
2713 if (IntImm >= NumElts || IntImm < 0)
2714 return false;
2715 if (!MatchInfo[IntImm])
2716 MatchInfo[IntImm] = TmpReg;
2717 CurrInst = TmpInst;
2718 }
2719 // Variable index.
2720 if (CurrInst->getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT)
2721 return false;
2722 if (TmpInst->getOpcode() == TargetOpcode::G_BUILD_VECTOR) {
2723 for (unsigned I = 1; I < TmpInst->getNumOperands(); ++I) {
2724 if (!MatchInfo[I - 1].isValid())
2725 MatchInfo[I - 1] = TmpInst->getOperand(I).getReg();
2726 }
2727 return true;
2728 }
2729 // If we didn't end in a G_IMPLICIT_DEF, bail out.
2730 return TmpInst->getOpcode() == TargetOpcode::G_IMPLICIT_DEF;
2731}
2732
2733void CombinerHelper::applyCombineInsertVecElts(
2734 MachineInstr &MI, SmallVectorImpl<Register> &MatchInfo) {
2735 Builder.setInstr(MI);
2736 Register UndefReg;
2737 auto GetUndef = [&]() {
2738 if (UndefReg)
2739 return UndefReg;
2740 LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
2741 UndefReg = Builder.buildUndef(DstTy.getScalarType()).getReg(0);
2742 return UndefReg;
2743 };
2744 for (unsigned I = 0; I < MatchInfo.size(); ++I) {
2745 if (!MatchInfo[I])
2746 MatchInfo[I] = GetUndef();
2747 }
2748 Builder.buildBuildVector(MI.getOperand(0).getReg(), MatchInfo);
2749 MI.eraseFromParent();
2750}
2751
2752void CombinerHelper::applySimplifyAddToSub(
2753 MachineInstr &MI, std::tuple<Register, Register> &MatchInfo) {
2754 Builder.setInstr(MI);
2755 Register SubLHS, SubRHS;
2756 std::tie(SubLHS, SubRHS) = MatchInfo;
2757 Builder.buildSub(MI.getOperand(0).getReg(), SubLHS, SubRHS);
2758 MI.eraseFromParent();
2759}
2760
2761bool CombinerHelper::matchHoistLogicOpWithSameOpcodeHands(
2762 MachineInstr &MI, InstructionStepsMatchInfo &MatchInfo) {
2763 // Matches: logic (hand x, ...), (hand y, ...) -> hand (logic x, y), ...
2764 //
2765 // Creates the new hand + logic instruction (but does not insert them.)
2766 //
2767 // On success, MatchInfo is populated with the new instructions. These are
2768 // inserted in applyHoistLogicOpWithSameOpcodeHands.
2769 unsigned LogicOpcode = MI.getOpcode();
2770 assert(LogicOpcode == TargetOpcode::G_AND ||(static_cast <bool> (LogicOpcode == TargetOpcode::G_AND
|| LogicOpcode == TargetOpcode::G_OR || LogicOpcode == TargetOpcode
::G_XOR) ? void (0) : __assert_fail ("LogicOpcode == TargetOpcode::G_AND || LogicOpcode == TargetOpcode::G_OR || LogicOpcode == TargetOpcode::G_XOR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2772, __extension__
__PRETTY_FUNCTION__))
2771 LogicOpcode == TargetOpcode::G_OR ||(static_cast <bool> (LogicOpcode == TargetOpcode::G_AND
|| LogicOpcode == TargetOpcode::G_OR || LogicOpcode == TargetOpcode
::G_XOR) ? void (0) : __assert_fail ("LogicOpcode == TargetOpcode::G_AND || LogicOpcode == TargetOpcode::G_OR || LogicOpcode == TargetOpcode::G_XOR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2772, __extension__
__PRETTY_FUNCTION__))
2772 LogicOpcode == TargetOpcode::G_XOR)(static_cast <bool> (LogicOpcode == TargetOpcode::G_AND
|| LogicOpcode == TargetOpcode::G_OR || LogicOpcode == TargetOpcode
::G_XOR) ? void (0) : __assert_fail ("LogicOpcode == TargetOpcode::G_AND || LogicOpcode == TargetOpcode::G_OR || LogicOpcode == TargetOpcode::G_XOR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2772, __extension__
__PRETTY_FUNCTION__))
;
2773 MachineIRBuilder MIB(MI);
2774 Register Dst = MI.getOperand(0).getReg();
2775 Register LHSReg = MI.getOperand(1).getReg();
2776 Register RHSReg = MI.getOperand(2).getReg();
2777
2778 // Don't recompute anything.
2779 if (!MRI.hasOneNonDBGUse(LHSReg) || !MRI.hasOneNonDBGUse(RHSReg))
2780 return false;
2781
2782 // Make sure we have (hand x, ...), (hand y, ...)
2783 MachineInstr *LeftHandInst = getDefIgnoringCopies(LHSReg, MRI);
2784 MachineInstr *RightHandInst = getDefIgnoringCopies(RHSReg, MRI);
2785 if (!LeftHandInst || !RightHandInst)
2786 return false;
2787 unsigned HandOpcode = LeftHandInst->getOpcode();
2788 if (HandOpcode != RightHandInst->getOpcode())
2789 return false;
2790 if (!LeftHandInst->getOperand(1).isReg() ||
2791 !RightHandInst->getOperand(1).isReg())
2792 return false;
2793
2794 // Make sure the types match up, and if we're doing this post-legalization,
2795 // we end up with legal types.
2796 Register X = LeftHandInst->getOperand(1).getReg();
2797 Register Y = RightHandInst->getOperand(1).getReg();
2798 LLT XTy = MRI.getType(X);
2799 LLT YTy = MRI.getType(Y);
2800 if (!XTy.isValid() || XTy != YTy)
2801 return false;
2802
2803 // Optional extra source register.
2804 Register ExtraHandOpSrcReg;
2805 switch (HandOpcode) {
2806 default:
2807 return false;
2808 case TargetOpcode::G_ANYEXT:
2809 case TargetOpcode::G_SEXT:
2810 case TargetOpcode::G_ZEXT: {
2811 // Match: logic (ext X), (ext Y) --> ext (logic X, Y)
2812 break;
2813 }
2814 case TargetOpcode::G_AND:
2815 case TargetOpcode::G_ASHR:
2816 case TargetOpcode::G_LSHR:
2817 case TargetOpcode::G_SHL: {
2818 // Match: logic (binop x, z), (binop y, z) -> binop (logic x, y), z
2819 MachineOperand &ZOp = LeftHandInst->getOperand(2);
2820 if (!matchEqualDefs(ZOp, RightHandInst->getOperand(2)))
2821 return false;
2822 ExtraHandOpSrcReg = ZOp.getReg();
2823 break;
2824 }
2825 }
2826
2827 if (!isLegalOrBeforeLegalizer({LogicOpcode, {XTy, YTy}}))
2828 return false;
2829
2830 // Record the steps to build the new instructions.
2831 //
2832 // Steps to build (logic x, y)
2833 auto NewLogicDst = MRI.createGenericVirtualRegister(XTy);
2834 OperandBuildSteps LogicBuildSteps = {
2835 [=](MachineInstrBuilder &MIB) { MIB.addDef(NewLogicDst); },
2836 [=](MachineInstrBuilder &MIB) { MIB.addReg(X); },
2837 [=](MachineInstrBuilder &MIB) { MIB.addReg(Y); }};
2838 InstructionBuildSteps LogicSteps(LogicOpcode, LogicBuildSteps);
2839
2840 // Steps to build hand (logic x, y), ...z
2841 OperandBuildSteps HandBuildSteps = {
2842 [=](MachineInstrBuilder &MIB) { MIB.addDef(Dst); },
2843 [=](MachineInstrBuilder &MIB) { MIB.addReg(NewLogicDst); }};
2844 if (ExtraHandOpSrcReg.isValid())
2845 HandBuildSteps.push_back(
2846 [=](MachineInstrBuilder &MIB) { MIB.addReg(ExtraHandOpSrcReg); });
2847 InstructionBuildSteps HandSteps(HandOpcode, HandBuildSteps);
2848
2849 MatchInfo = InstructionStepsMatchInfo({LogicSteps, HandSteps});
2850 return true;
2851}
2852
2853void CombinerHelper::applyBuildInstructionSteps(
2854 MachineInstr &MI, InstructionStepsMatchInfo &MatchInfo) {
2855 assert(MatchInfo.InstrsToBuild.size() &&(static_cast <bool> (MatchInfo.InstrsToBuild.size() &&
"Expected at least one instr to build?") ? void (0) : __assert_fail
("MatchInfo.InstrsToBuild.size() && \"Expected at least one instr to build?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2856, __extension__
__PRETTY_FUNCTION__))
2856 "Expected at least one instr to build?")(static_cast <bool> (MatchInfo.InstrsToBuild.size() &&
"Expected at least one instr to build?") ? void (0) : __assert_fail
("MatchInfo.InstrsToBuild.size() && \"Expected at least one instr to build?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2856, __extension__
__PRETTY_FUNCTION__))
;
2857 Builder.setInstr(MI);
2858 for (auto &InstrToBuild : MatchInfo.InstrsToBuild) {
2859 assert(InstrToBuild.Opcode && "Expected a valid opcode?")(static_cast <bool> (InstrToBuild.Opcode && "Expected a valid opcode?"
) ? void (0) : __assert_fail ("InstrToBuild.Opcode && \"Expected a valid opcode?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2859, __extension__
__PRETTY_FUNCTION__))
;
2860 assert(InstrToBuild.OperandFns.size() && "Expected at least one operand?")(static_cast <bool> (InstrToBuild.OperandFns.size() &&
"Expected at least one operand?") ? void (0) : __assert_fail
("InstrToBuild.OperandFns.size() && \"Expected at least one operand?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2860, __extension__
__PRETTY_FUNCTION__))
;
2861 MachineInstrBuilder Instr = Builder.buildInstr(InstrToBuild.Opcode);
2862 for (auto &OperandFn : InstrToBuild.OperandFns)
2863 OperandFn(Instr);
2864 }
2865 MI.eraseFromParent();
2866}
2867
2868bool CombinerHelper::matchAshrShlToSextInreg(
2869 MachineInstr &MI, std::tuple<Register, int64_t> &MatchInfo) {
2870 assert(MI.getOpcode() == TargetOpcode::G_ASHR)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_ASHR
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_ASHR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2870, __extension__
__PRETTY_FUNCTION__))
;
2871 int64_t ShlCst, AshrCst;
2872 Register Src;
2873 if (!mi_match(MI.getOperand(0).getReg(), MRI,
2874 m_GAShr(m_GShl(m_Reg(Src), m_ICstOrSplat(ShlCst)),
2875 m_ICstOrSplat(AshrCst))))
2876 return false;
2877 if (ShlCst != AshrCst)
2878 return false;
2879 if (!isLegalOrBeforeLegalizer(
2880 {TargetOpcode::G_SEXT_INREG, {MRI.getType(Src)}}))
2881 return false;
2882 MatchInfo = std::make_tuple(Src, ShlCst);
2883 return true;
2884}
2885
2886void CombinerHelper::applyAshShlToSextInreg(
2887 MachineInstr &MI, std::tuple<Register, int64_t> &MatchInfo) {
2888 assert(MI.getOpcode() == TargetOpcode::G_ASHR)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_ASHR
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_ASHR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2888, __extension__
__PRETTY_FUNCTION__))
;
2889 Register Src;
2890 int64_t ShiftAmt;
2891 std::tie(Src, ShiftAmt) = MatchInfo;
2892 unsigned Size = MRI.getType(Src).getScalarSizeInBits();
2893 Builder.setInstrAndDebugLoc(MI);
2894 Builder.buildSExtInReg(MI.getOperand(0).getReg(), Src, Size - ShiftAmt);
2895 MI.eraseFromParent();
2896}
2897
2898/// and(and(x, C1), C2) -> C1&C2 ? and(x, C1&C2) : 0
2899bool CombinerHelper::matchOverlappingAnd(
2900 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
2901 assert(MI.getOpcode() == TargetOpcode::G_AND)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_AND
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_AND"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2901, __extension__
__PRETTY_FUNCTION__))
;
2902
2903 Register Dst = MI.getOperand(0).getReg();
2904 LLT Ty = MRI.getType(Dst);
2905
2906 Register R;
2907 int64_t C1;
2908 int64_t C2;
2909 if (!mi_match(
2910 Dst, MRI,
2911 m_GAnd(m_GAnd(m_Reg(R), m_ICst(C1)), m_ICst(C2))))
2912 return false;
2913
2914 MatchInfo = [=](MachineIRBuilder &B) {
2915 if (C1 & C2) {
2916 B.buildAnd(Dst, R, B.buildConstant(Ty, C1 & C2));
2917 return;
2918 }
2919 auto Zero = B.buildConstant(Ty, 0);
2920 replaceRegWith(MRI, Dst, Zero->getOperand(0).getReg());
2921 };
2922 return true;
2923}
2924
2925bool CombinerHelper::matchRedundantAnd(MachineInstr &MI,
2926 Register &Replacement) {
2927 // Given
2928 //
2929 // %y:_(sN) = G_SOMETHING
2930 // %x:_(sN) = G_SOMETHING
2931 // %res:_(sN) = G_AND %x, %y
2932 //
2933 // Eliminate the G_AND when it is known that x & y == x or x & y == y.
2934 //
2935 // Patterns like this can appear as a result of legalization. E.g.
2936 //
2937 // %cmp:_(s32) = G_ICMP intpred(pred), %x(s32), %y
2938 // %one:_(s32) = G_CONSTANT i32 1
2939 // %and:_(s32) = G_AND %cmp, %one
2940 //
2941 // In this case, G_ICMP only produces a single bit, so x & 1 == x.
2942 assert(MI.getOpcode() == TargetOpcode::G_AND)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_AND
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_AND"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2942, __extension__
__PRETTY_FUNCTION__))
;
2943 if (!KB)
2944 return false;
2945
2946 Register AndDst = MI.getOperand(0).getReg();
2947 Register LHS = MI.getOperand(1).getReg();
2948 Register RHS = MI.getOperand(2).getReg();
2949 KnownBits LHSBits = KB->getKnownBits(LHS);
2950 KnownBits RHSBits = KB->getKnownBits(RHS);
2951
2952 // Check that x & Mask == x.
2953 // x & 1 == x, always
2954 // x & 0 == x, only if x is also 0
2955 // Meaning Mask has no effect if every bit is either one in Mask or zero in x.
2956 //
2957 // Check if we can replace AndDst with the LHS of the G_AND
2958 if (canReplaceReg(AndDst, LHS, MRI) &&
2959 (LHSBits.Zero | RHSBits.One).isAllOnes()) {
2960 Replacement = LHS;
2961 return true;
2962 }
2963
2964 // Check if we can replace AndDst with the RHS of the G_AND
2965 if (canReplaceReg(AndDst, RHS, MRI) &&
2966 (LHSBits.One | RHSBits.Zero).isAllOnes()) {
2967 Replacement = RHS;
2968 return true;
2969 }
2970
2971 return false;
2972}
2973
2974bool CombinerHelper::matchRedundantOr(MachineInstr &MI, Register &Replacement) {
2975 // Given
2976 //
2977 // %y:_(sN) = G_SOMETHING
2978 // %x:_(sN) = G_SOMETHING
2979 // %res:_(sN) = G_OR %x, %y
2980 //
2981 // Eliminate the G_OR when it is known that x | y == x or x | y == y.
2982 assert(MI.getOpcode() == TargetOpcode::G_OR)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_OR
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_OR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 2982, __extension__
__PRETTY_FUNCTION__))
;
2983 if (!KB)
2984 return false;
2985
2986 Register OrDst = MI.getOperand(0).getReg();
2987 Register LHS = MI.getOperand(1).getReg();
2988 Register RHS = MI.getOperand(2).getReg();
2989 KnownBits LHSBits = KB->getKnownBits(LHS);
2990 KnownBits RHSBits = KB->getKnownBits(RHS);
2991
2992 // Check that x | Mask == x.
2993 // x | 0 == x, always
2994 // x | 1 == x, only if x is also 1
2995 // Meaning Mask has no effect if every bit is either zero in Mask or one in x.
2996 //
2997 // Check if we can replace OrDst with the LHS of the G_OR
2998 if (canReplaceReg(OrDst, LHS, MRI) &&
2999 (LHSBits.One | RHSBits.Zero).isAllOnes()) {
3000 Replacement = LHS;
3001 return true;
3002 }
3003
3004 // Check if we can replace OrDst with the RHS of the G_OR
3005 if (canReplaceReg(OrDst, RHS, MRI) &&
3006 (LHSBits.Zero | RHSBits.One).isAllOnes()) {
3007 Replacement = RHS;
3008 return true;
3009 }
3010
3011 return false;
3012}
3013
3014bool CombinerHelper::matchRedundantSExtInReg(MachineInstr &MI) {
3015 // If the input is already sign extended, just drop the extension.
3016 Register Src = MI.getOperand(1).getReg();
3017 unsigned ExtBits = MI.getOperand(2).getImm();
3018 unsigned TypeSize = MRI.getType(Src).getScalarSizeInBits();
3019 return KB->computeNumSignBits(Src) >= (TypeSize - ExtBits + 1);
3020}
3021
3022static bool isConstValidTrue(const TargetLowering &TLI, unsigned ScalarSizeBits,
3023 int64_t Cst, bool IsVector, bool IsFP) {
3024 // For i1, Cst will always be -1 regardless of boolean contents.
3025 return (ScalarSizeBits == 1 && Cst == -1) ||
3026 isConstTrueVal(TLI, Cst, IsVector, IsFP);
3027}
3028
3029bool CombinerHelper::matchNotCmp(MachineInstr &MI,
3030 SmallVectorImpl<Register> &RegsToNegate) {
3031 assert(MI.getOpcode() == TargetOpcode::G_XOR)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_XOR
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_XOR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3031, __extension__
__PRETTY_FUNCTION__))
;
3032 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
3033 const auto &TLI = *Builder.getMF().getSubtarget().getTargetLowering();
3034 Register XorSrc;
3035 Register CstReg;
3036 // We match xor(src, true) here.
3037 if (!mi_match(MI.getOperand(0).getReg(), MRI,
3038 m_GXor(m_Reg(XorSrc), m_Reg(CstReg))))
3039 return false;
3040
3041 if (!MRI.hasOneNonDBGUse(XorSrc))
3042 return false;
3043
3044 // Check that XorSrc is the root of a tree of comparisons combined with ANDs
3045 // and ORs. The suffix of RegsToNegate starting from index I is used a work
3046 // list of tree nodes to visit.
3047 RegsToNegate.push_back(XorSrc);
3048 // Remember whether the comparisons are all integer or all floating point.
3049 bool IsInt = false;
3050 bool IsFP = false;
3051 for (unsigned I = 0; I < RegsToNegate.size(); ++I) {
3052 Register Reg = RegsToNegate[I];
3053 if (!MRI.hasOneNonDBGUse(Reg))
3054 return false;
3055 MachineInstr *Def = MRI.getVRegDef(Reg);
3056 switch (Def->getOpcode()) {
3057 default:
3058 // Don't match if the tree contains anything other than ANDs, ORs and
3059 // comparisons.
3060 return false;
3061 case TargetOpcode::G_ICMP:
3062 if (IsFP)
3063 return false;
3064 IsInt = true;
3065 // When we apply the combine we will invert the predicate.
3066 break;
3067 case TargetOpcode::G_FCMP:
3068 if (IsInt)
3069 return false;
3070 IsFP = true;
3071 // When we apply the combine we will invert the predicate.
3072 break;
3073 case TargetOpcode::G_AND:
3074 case TargetOpcode::G_OR:
3075 // Implement De Morgan's laws:
3076 // ~(x & y) -> ~x | ~y
3077 // ~(x | y) -> ~x & ~y
3078 // When we apply the combine we will change the opcode and recursively
3079 // negate the operands.
3080 RegsToNegate.push_back(Def->getOperand(1).getReg());
3081 RegsToNegate.push_back(Def->getOperand(2).getReg());
3082 break;
3083 }
3084 }
3085
3086 // Now we know whether the comparisons are integer or floating point, check
3087 // the constant in the xor.
3088 int64_t Cst;
3089 if (Ty.isVector()) {
3090 MachineInstr *CstDef = MRI.getVRegDef(CstReg);
3091 auto MaybeCst = getIConstantSplatSExtVal(*CstDef, MRI);
3092 if (!MaybeCst)
3093 return false;
3094 if (!isConstValidTrue(TLI, Ty.getScalarSizeInBits(), *MaybeCst, true, IsFP))
3095 return false;
3096 } else {
3097 if (!mi_match(CstReg, MRI, m_ICst(Cst)))
3098 return false;
3099 if (!isConstValidTrue(TLI, Ty.getSizeInBits(), Cst, false, IsFP))
3100 return false;
3101 }
3102
3103 return true;
3104}
3105
3106void CombinerHelper::applyNotCmp(MachineInstr &MI,
3107 SmallVectorImpl<Register> &RegsToNegate) {
3108 for (Register Reg : RegsToNegate) {
3109 MachineInstr *Def = MRI.getVRegDef(Reg);
3110 Observer.changingInstr(*Def);
3111 // For each comparison, invert the opcode. For each AND and OR, change the
3112 // opcode.
3113 switch (Def->getOpcode()) {
3114 default:
3115 llvm_unreachable("Unexpected opcode")::llvm::llvm_unreachable_internal("Unexpected opcode", "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp"
, 3115)
;
3116 case TargetOpcode::G_ICMP:
3117 case TargetOpcode::G_FCMP: {
3118 MachineOperand &PredOp = Def->getOperand(1);
3119 CmpInst::Predicate NewP = CmpInst::getInversePredicate(
3120 (CmpInst::Predicate)PredOp.getPredicate());
3121 PredOp.setPredicate(NewP);
3122 break;
3123 }
3124 case TargetOpcode::G_AND:
3125 Def->setDesc(Builder.getTII().get(TargetOpcode::G_OR));
3126 break;
3127 case TargetOpcode::G_OR:
3128 Def->setDesc(Builder.getTII().get(TargetOpcode::G_AND));
3129 break;
3130 }
3131 Observer.changedInstr(*Def);
3132 }
3133
3134 replaceRegWith(MRI, MI.getOperand(0).getReg(), MI.getOperand(1).getReg());
3135 MI.eraseFromParent();
3136}
3137
3138bool CombinerHelper::matchXorOfAndWithSameReg(
3139 MachineInstr &MI, std::pair<Register, Register> &MatchInfo) {
3140 // Match (xor (and x, y), y) (or any of its commuted cases)
3141 assert(MI.getOpcode() == TargetOpcode::G_XOR)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_XOR
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_XOR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3141, __extension__
__PRETTY_FUNCTION__))
;
3142 Register &X = MatchInfo.first;
3143 Register &Y = MatchInfo.second;
3144 Register AndReg = MI.getOperand(1).getReg();
3145 Register SharedReg = MI.getOperand(2).getReg();
3146
3147 // Find a G_AND on either side of the G_XOR.
3148 // Look for one of
3149 //
3150 // (xor (and x, y), SharedReg)
3151 // (xor SharedReg, (and x, y))
3152 if (!mi_match(AndReg, MRI, m_GAnd(m_Reg(X), m_Reg(Y)))) {
3153 std::swap(AndReg, SharedReg);
3154 if (!mi_match(AndReg, MRI, m_GAnd(m_Reg(X), m_Reg(Y))))
3155 return false;
3156 }
3157
3158 // Only do this if we'll eliminate the G_AND.
3159 if (!MRI.hasOneNonDBGUse(AndReg))
3160 return false;
3161
3162 // We can combine if SharedReg is the same as either the LHS or RHS of the
3163 // G_AND.
3164 if (Y != SharedReg)
3165 std::swap(X, Y);
3166 return Y == SharedReg;
3167}
3168
3169void CombinerHelper::applyXorOfAndWithSameReg(
3170 MachineInstr &MI, std::pair<Register, Register> &MatchInfo) {
3171 // Fold (xor (and x, y), y) -> (and (not x), y)
3172 Builder.setInstrAndDebugLoc(MI);
3173 Register X, Y;
3174 std::tie(X, Y) = MatchInfo;
3175 auto Not = Builder.buildNot(MRI.getType(X), X);
3176 Observer.changingInstr(MI);
3177 MI.setDesc(Builder.getTII().get(TargetOpcode::G_AND));
3178 MI.getOperand(1).setReg(Not->getOperand(0).getReg());
3179 MI.getOperand(2).setReg(Y);
3180 Observer.changedInstr(MI);
3181}
3182
3183bool CombinerHelper::matchPtrAddZero(MachineInstr &MI) {
3184 auto &PtrAdd = cast<GPtrAdd>(MI);
3185 Register DstReg = PtrAdd.getReg(0);
3186 LLT Ty = MRI.getType(DstReg);
3187 const DataLayout &DL = Builder.getMF().getDataLayout();
3188
3189 if (DL.isNonIntegralAddressSpace(Ty.getScalarType().getAddressSpace()))
3190 return false;
3191
3192 if (Ty.isPointer()) {
3193 auto ConstVal = getIConstantVRegVal(PtrAdd.getBaseReg(), MRI);
3194 return ConstVal && *ConstVal == 0;
3195 }
3196
3197 assert(Ty.isVector() && "Expecting a vector type")(static_cast <bool> (Ty.isVector() && "Expecting a vector type"
) ? void (0) : __assert_fail ("Ty.isVector() && \"Expecting a vector type\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3197, __extension__
__PRETTY_FUNCTION__))
;
3198 const MachineInstr *VecMI = MRI.getVRegDef(PtrAdd.getBaseReg());
3199 return isBuildVectorAllZeros(*VecMI, MRI);
3200}
3201
3202void CombinerHelper::applyPtrAddZero(MachineInstr &MI) {
3203 auto &PtrAdd = cast<GPtrAdd>(MI);
3204 Builder.setInstrAndDebugLoc(PtrAdd);
3205 Builder.buildIntToPtr(PtrAdd.getReg(0), PtrAdd.getOffsetReg());
3206 PtrAdd.eraseFromParent();
3207}
3208
3209/// The second source operand is known to be a power of 2.
3210void CombinerHelper::applySimplifyURemByPow2(MachineInstr &MI) {
3211 Register DstReg = MI.getOperand(0).getReg();
3212 Register Src0 = MI.getOperand(1).getReg();
3213 Register Pow2Src1 = MI.getOperand(2).getReg();
3214 LLT Ty = MRI.getType(DstReg);
3215 Builder.setInstrAndDebugLoc(MI);
3216
3217 // Fold (urem x, pow2) -> (and x, pow2-1)
3218 auto NegOne = Builder.buildConstant(Ty, -1);
3219 auto Add = Builder.buildAdd(Ty, Pow2Src1, NegOne);
3220 Builder.buildAnd(DstReg, Src0, Add);
3221 MI.eraseFromParent();
3222}
3223
3224bool CombinerHelper::matchFoldBinOpIntoSelect(MachineInstr &MI,
3225 unsigned &SelectOpNo) {
3226 Register LHS = MI.getOperand(1).getReg();
3227 Register RHS = MI.getOperand(2).getReg();
3228
3229 Register OtherOperandReg = RHS;
3230 SelectOpNo = 1;
3231 MachineInstr *Select = MRI.getVRegDef(LHS);
3232
3233 // Don't do this unless the old select is going away. We want to eliminate the
3234 // binary operator, not replace a binop with a select.
3235 if (Select->getOpcode() != TargetOpcode::G_SELECT ||
3236 !MRI.hasOneNonDBGUse(LHS)) {
3237 OtherOperandReg = LHS;
3238 SelectOpNo = 2;
3239 Select = MRI.getVRegDef(RHS);
3240 if (Select->getOpcode() != TargetOpcode::G_SELECT ||
3241 !MRI.hasOneNonDBGUse(RHS))
3242 return false;
3243 }
3244
3245 MachineInstr *SelectLHS = MRI.getVRegDef(Select->getOperand(2).getReg());
3246 MachineInstr *SelectRHS = MRI.getVRegDef(Select->getOperand(3).getReg());
3247
3248 if (!isConstantOrConstantVector(*SelectLHS, MRI,
3249 /*AllowFP*/ true,
3250 /*AllowOpaqueConstants*/ false))
3251 return false;
3252 if (!isConstantOrConstantVector(*SelectRHS, MRI,
3253 /*AllowFP*/ true,
3254 /*AllowOpaqueConstants*/ false))
3255 return false;
3256
3257 unsigned BinOpcode = MI.getOpcode();
3258
3259 // We know know one of the operands is a select of constants. Now verify that
3260 // the other binary operator operand is either a constant, or we can handle a
3261 // variable.
3262 bool CanFoldNonConst =
3263 (BinOpcode == TargetOpcode::G_AND || BinOpcode == TargetOpcode::G_OR) &&
3264 (isNullOrNullSplat(*SelectLHS, MRI) ||
3265 isAllOnesOrAllOnesSplat(*SelectLHS, MRI)) &&
3266 (isNullOrNullSplat(*SelectRHS, MRI) ||
3267 isAllOnesOrAllOnesSplat(*SelectRHS, MRI));
3268 if (CanFoldNonConst)
3269 return true;
3270
3271 return isConstantOrConstantVector(*MRI.getVRegDef(OtherOperandReg), MRI,
3272 /*AllowFP*/ true,
3273 /*AllowOpaqueConstants*/ false);
3274}
3275
3276/// \p SelectOperand is the operand in binary operator \p MI that is the select
3277/// to fold.
3278bool CombinerHelper::applyFoldBinOpIntoSelect(MachineInstr &MI,
3279 const unsigned &SelectOperand) {
3280 Builder.setInstrAndDebugLoc(MI);
3281
3282 Register Dst = MI.getOperand(0).getReg();
3283 Register LHS = MI.getOperand(1).getReg();
3284 Register RHS = MI.getOperand(2).getReg();
3285 MachineInstr *Select = MRI.getVRegDef(MI.getOperand(SelectOperand).getReg());
3286
3287 Register SelectCond = Select->getOperand(1).getReg();
3288 Register SelectTrue = Select->getOperand(2).getReg();
3289 Register SelectFalse = Select->getOperand(3).getReg();
3290
3291 LLT Ty = MRI.getType(Dst);
3292 unsigned BinOpcode = MI.getOpcode();
3293
3294 Register FoldTrue, FoldFalse;
3295
3296 // We have a select-of-constants followed by a binary operator with a
3297 // constant. Eliminate the binop by pulling the constant math into the select.
3298 // Example: add (select Cond, CT, CF), CBO --> select Cond, CT + CBO, CF + CBO
3299 if (SelectOperand == 1) {
3300 // TODO: SelectionDAG verifies this actually constant folds before
3301 // committing to the combine.
3302
3303 FoldTrue = Builder.buildInstr(BinOpcode, {Ty}, {SelectTrue, RHS}).getReg(0);
3304 FoldFalse =
3305 Builder.buildInstr(BinOpcode, {Ty}, {SelectFalse, RHS}).getReg(0);
3306 } else {
3307 FoldTrue = Builder.buildInstr(BinOpcode, {Ty}, {LHS, SelectTrue}).getReg(0);
3308 FoldFalse =
3309 Builder.buildInstr(BinOpcode, {Ty}, {LHS, SelectFalse}).getReg(0);
3310 }
3311
3312 Builder.buildSelect(Dst, SelectCond, FoldTrue, FoldFalse, MI.getFlags());
3313 MI.eraseFromParent();
3314
3315 return true;
3316}
3317
3318std::optional<SmallVector<Register, 8>>
3319CombinerHelper::findCandidatesForLoadOrCombine(const MachineInstr *Root) const {
3320 assert(Root->getOpcode() == TargetOpcode::G_OR && "Expected G_OR only!")(static_cast <bool> (Root->getOpcode() == TargetOpcode
::G_OR && "Expected G_OR only!") ? void (0) : __assert_fail
("Root->getOpcode() == TargetOpcode::G_OR && \"Expected G_OR only!\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3320, __extension__
__PRETTY_FUNCTION__))
;
3321 // We want to detect if Root is part of a tree which represents a bunch
3322 // of loads being merged into a larger load. We'll try to recognize patterns
3323 // like, for example:
3324 //
3325 // Reg Reg
3326 // \ /
3327 // OR_1 Reg
3328 // \ /
3329 // OR_2
3330 // \ Reg
3331 // .. /
3332 // Root
3333 //
3334 // Reg Reg Reg Reg
3335 // \ / \ /
3336 // OR_1 OR_2
3337 // \ /
3338 // \ /
3339 // ...
3340 // Root
3341 //
3342 // Each "Reg" may have been produced by a load + some arithmetic. This
3343 // function will save each of them.
3344 SmallVector<Register, 8> RegsToVisit;
3345 SmallVector<const MachineInstr *, 7> Ors = {Root};
3346
3347 // In the "worst" case, we're dealing with a load for each byte. So, there
3348 // are at most #bytes - 1 ORs.
3349 const unsigned MaxIter =
3350 MRI.getType(Root->getOperand(0).getReg()).getSizeInBytes() - 1;
3351 for (unsigned Iter = 0; Iter < MaxIter; ++Iter) {
3352 if (Ors.empty())
3353 break;
3354 const MachineInstr *Curr = Ors.pop_back_val();
3355 Register OrLHS = Curr->getOperand(1).getReg();
3356 Register OrRHS = Curr->getOperand(2).getReg();
3357
3358 // In the combine, we want to elimate the entire tree.
3359 if (!MRI.hasOneNonDBGUse(OrLHS) || !MRI.hasOneNonDBGUse(OrRHS))
3360 return std::nullopt;
3361
3362 // If it's a G_OR, save it and continue to walk. If it's not, then it's
3363 // something that may be a load + arithmetic.
3364 if (const MachineInstr *Or = getOpcodeDef(TargetOpcode::G_OR, OrLHS, MRI))
3365 Ors.push_back(Or);
3366 else
3367 RegsToVisit.push_back(OrLHS);
3368 if (const MachineInstr *Or = getOpcodeDef(TargetOpcode::G_OR, OrRHS, MRI))
3369 Ors.push_back(Or);
3370 else
3371 RegsToVisit.push_back(OrRHS);
3372 }
3373
3374 // We're going to try and merge each register into a wider power-of-2 type,
3375 // so we ought to have an even number of registers.
3376 if (RegsToVisit.empty() || RegsToVisit.size() % 2 != 0)
3377 return std::nullopt;
3378 return RegsToVisit;
3379}
3380
3381/// Helper function for findLoadOffsetsForLoadOrCombine.
3382///
3383/// Check if \p Reg is the result of loading a \p MemSizeInBits wide value,
3384/// and then moving that value into a specific byte offset.
3385///
3386/// e.g. x[i] << 24
3387///
3388/// \returns The load instruction and the byte offset it is moved into.
3389static std::optional<std::pair<GZExtLoad *, int64_t>>
3390matchLoadAndBytePosition(Register Reg, unsigned MemSizeInBits,
3391 const MachineRegisterInfo &MRI) {
3392 assert(MRI.hasOneNonDBGUse(Reg) &&(static_cast <bool> (MRI.hasOneNonDBGUse(Reg) &&
"Expected Reg to only have one non-debug use?") ? void (0) :
__assert_fail ("MRI.hasOneNonDBGUse(Reg) && \"Expected Reg to only have one non-debug use?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3393, __extension__
__PRETTY_FUNCTION__))
3393 "Expected Reg to only have one non-debug use?")(static_cast <bool> (MRI.hasOneNonDBGUse(Reg) &&
"Expected Reg to only have one non-debug use?") ? void (0) :
__assert_fail ("MRI.hasOneNonDBGUse(Reg) && \"Expected Reg to only have one non-debug use?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3393, __extension__
__PRETTY_FUNCTION__))
;
3394 Register MaybeLoad;
3395 int64_t Shift;
3396 if (!mi_match(Reg, MRI,
3397 m_OneNonDBGUse(m_GShl(m_Reg(MaybeLoad), m_ICst(Shift))))) {
3398 Shift = 0;
3399 MaybeLoad = Reg;
3400 }
3401
3402 if (Shift % MemSizeInBits != 0)
3403 return std::nullopt;
3404
3405 // TODO: Handle other types of loads.
3406 auto *Load = getOpcodeDef<GZExtLoad>(MaybeLoad, MRI);
3407 if (!Load)
3408 return std::nullopt;
3409
3410 if (!Load->isUnordered() || Load->getMemSizeInBits() != MemSizeInBits)
3411 return std::nullopt;
3412
3413 return std::make_pair(Load, Shift / MemSizeInBits);
3414}
3415
3416std::optional<std::tuple<GZExtLoad *, int64_t, GZExtLoad *>>
3417CombinerHelper::findLoadOffsetsForLoadOrCombine(
3418 SmallDenseMap<int64_t, int64_t, 8> &MemOffset2Idx,
3419 const SmallVector<Register, 8> &RegsToVisit, const unsigned MemSizeInBits) {
3420
3421 // Each load found for the pattern. There should be one for each RegsToVisit.
3422 SmallSetVector<const MachineInstr *, 8> Loads;
3423
3424 // The lowest index used in any load. (The lowest "i" for each x[i].)
3425 int64_t LowestIdx = INT64_MAX(9223372036854775807L);
3426
3427 // The load which uses the lowest index.
3428 GZExtLoad *LowestIdxLoad = nullptr;
3429
3430 // Keeps track of the load indices we see. We shouldn't see any indices twice.
3431 SmallSet<int64_t, 8> SeenIdx;
3432
3433 // Ensure each load is in the same MBB.
3434 // TODO: Support multiple MachineBasicBlocks.
3435 MachineBasicBlock *MBB = nullptr;
3436 const MachineMemOperand *MMO = nullptr;
3437
3438 // Earliest instruction-order load in the pattern.
3439 GZExtLoad *EarliestLoad = nullptr;
3440
3441 // Latest instruction-order load in the pattern.
3442 GZExtLoad *LatestLoad = nullptr;
3443
3444 // Base pointer which every load should share.
3445 Register BasePtr;
3446
3447 // We want to find a load for each register. Each load should have some
3448 // appropriate bit twiddling arithmetic. During this loop, we will also keep
3449 // track of the load which uses the lowest index. Later, we will check if we
3450 // can use its pointer in the final, combined load.
3451 for (auto Reg : RegsToVisit) {
3452 // Find the load, and find the position that it will end up in (e.g. a
3453 // shifted) value.
3454 auto LoadAndPos = matchLoadAndBytePosition(Reg, MemSizeInBits, MRI);
3455 if (!LoadAndPos)
3456 return std::nullopt;
3457 GZExtLoad *Load;
3458 int64_t DstPos;
3459 std::tie(Load, DstPos) = *LoadAndPos;
3460
3461 // TODO: Handle multiple MachineBasicBlocks. Currently not handled because
3462 // it is difficult to check for stores/calls/etc between loads.
3463 MachineBasicBlock *LoadMBB = Load->getParent();
3464 if (!MBB)
3465 MBB = LoadMBB;
3466 if (LoadMBB != MBB)
3467 return std::nullopt;
3468
3469 // Make sure that the MachineMemOperands of every seen load are compatible.
3470 auto &LoadMMO = Load->getMMO();
3471 if (!MMO)
3472 MMO = &LoadMMO;
3473 if (MMO->getAddrSpace() != LoadMMO.getAddrSpace())
3474 return std::nullopt;
3475
3476 // Find out what the base pointer and index for the load is.
3477 Register LoadPtr;
3478 int64_t Idx;
3479 if (!mi_match(Load->getOperand(1).getReg(), MRI,
3480 m_GPtrAdd(m_Reg(LoadPtr), m_ICst(Idx)))) {
3481 LoadPtr = Load->getOperand(1).getReg();
3482 Idx = 0;
3483 }
3484
3485 // Don't combine things like a[i], a[i] -> a bigger load.
3486 if (!SeenIdx.insert(Idx).second)
3487 return std::nullopt;
3488
3489 // Every load must share the same base pointer; don't combine things like:
3490 //
3491 // a[i], b[i + 1] -> a bigger load.
3492 if (!BasePtr.isValid())
3493 BasePtr = LoadPtr;
3494 if (BasePtr != LoadPtr)
3495 return std::nullopt;
3496
3497 if (Idx < LowestIdx) {
3498 LowestIdx = Idx;
3499 LowestIdxLoad = Load;
3500 }
3501
3502 // Keep track of the byte offset that this load ends up at. If we have seen
3503 // the byte offset, then stop here. We do not want to combine:
3504 //
3505 // a[i] << 16, a[i + k] << 16 -> a bigger load.
3506 if (!MemOffset2Idx.try_emplace(DstPos, Idx).second)
3507 return std::nullopt;
3508 Loads.insert(Load);
3509
3510 // Keep track of the position of the earliest/latest loads in the pattern.
3511 // We will check that there are no load fold barriers between them later
3512 // on.
3513 //
3514 // FIXME: Is there a better way to check for load fold barriers?
3515 if (!EarliestLoad || dominates(*Load, *EarliestLoad))
3516 EarliestLoad = Load;
3517 if (!LatestLoad || dominates(*LatestLoad, *Load))
3518 LatestLoad = Load;
3519 }
3520
3521 // We found a load for each register. Let's check if each load satisfies the
3522 // pattern.
3523 assert(Loads.size() == RegsToVisit.size() &&(static_cast <bool> (Loads.size() == RegsToVisit.size()
&& "Expected to find a load for each register?") ? void
(0) : __assert_fail ("Loads.size() == RegsToVisit.size() && \"Expected to find a load for each register?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3524, __extension__
__PRETTY_FUNCTION__))
3524 "Expected to find a load for each register?")(static_cast <bool> (Loads.size() == RegsToVisit.size()
&& "Expected to find a load for each register?") ? void
(0) : __assert_fail ("Loads.size() == RegsToVisit.size() && \"Expected to find a load for each register?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3524, __extension__
__PRETTY_FUNCTION__))
;
3525 assert(EarliestLoad != LatestLoad && EarliestLoad &&(static_cast <bool> (EarliestLoad != LatestLoad &&
EarliestLoad && LatestLoad && "Expected at least two loads?"
) ? void (0) : __assert_fail ("EarliestLoad != LatestLoad && EarliestLoad && LatestLoad && \"Expected at least two loads?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3526, __extension__
__PRETTY_FUNCTION__))
3526 LatestLoad && "Expected at least two loads?")(static_cast <bool> (EarliestLoad != LatestLoad &&
EarliestLoad && LatestLoad && "Expected at least two loads?"
) ? void (0) : __assert_fail ("EarliestLoad != LatestLoad && EarliestLoad && LatestLoad && \"Expected at least two loads?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3526, __extension__
__PRETTY_FUNCTION__))
;
3527
3528 // Check if there are any stores, calls, etc. between any of the loads. If
3529 // there are, then we can't safely perform the combine.
3530 //
3531 // MaxIter is chosen based off the (worst case) number of iterations it
3532 // typically takes to succeed in the LLVM test suite plus some padding.
3533 //
3534 // FIXME: Is there a better way to check for load fold barriers?
3535 const unsigned MaxIter = 20;
3536 unsigned Iter = 0;
3537 for (const auto &MI : instructionsWithoutDebug(EarliestLoad->getIterator(),
3538 LatestLoad->getIterator())) {
3539 if (Loads.count(&MI))
3540 continue;
3541 if (MI.isLoadFoldBarrier())
3542 return std::nullopt;
3543 if (Iter++ == MaxIter)
3544 return std::nullopt;
3545 }
3546
3547 return std::make_tuple(LowestIdxLoad, LowestIdx, LatestLoad);
3548}
3549
3550bool CombinerHelper::matchLoadOrCombine(
3551 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
3552 assert(MI.getOpcode() == TargetOpcode::G_OR)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_OR
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_OR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3552, __extension__
__PRETTY_FUNCTION__))
;
3553 MachineFunction &MF = *MI.getMF();
3554 // Assuming a little-endian target, transform:
3555 // s8 *a = ...
3556 // s32 val = a[0] | (a[1] << 8) | (a[2] << 16) | (a[3] << 24)
3557 // =>
3558 // s32 val = *((i32)a)
3559 //
3560 // s8 *a = ...
3561 // s32 val = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]
3562 // =>
3563 // s32 val = BSWAP(*((s32)a))
3564 Register Dst = MI.getOperand(0).getReg();
3565 LLT Ty = MRI.getType(Dst);
3566 if (Ty.isVector())
3567 return false;
3568
3569 // We need to combine at least two loads into this type. Since the smallest
3570 // possible load is into a byte, we need at least a 16-bit wide type.
3571 const unsigned WideMemSizeInBits = Ty.getSizeInBits();
3572 if (WideMemSizeInBits < 16 || WideMemSizeInBits % 8 != 0)
3573 return false;
3574
3575 // Match a collection of non-OR instructions in the pattern.
3576 auto RegsToVisit = findCandidatesForLoadOrCombine(&MI);
3577 if (!RegsToVisit)
3578 return false;
3579
3580 // We have a collection of non-OR instructions. Figure out how wide each of
3581 // the small loads should be based off of the number of potential loads we
3582 // found.
3583 const unsigned NarrowMemSizeInBits = WideMemSizeInBits / RegsToVisit->size();
3584 if (NarrowMemSizeInBits % 8 != 0)
3585 return false;
3586
3587 // Check if each register feeding into each OR is a load from the same
3588 // base pointer + some arithmetic.
3589 //
3590 // e.g. a[0], a[1] << 8, a[2] << 16, etc.
3591 //
3592 // Also verify that each of these ends up putting a[i] into the same memory
3593 // offset as a load into a wide type would.
3594 SmallDenseMap<int64_t, int64_t, 8> MemOffset2Idx;
3595 GZExtLoad *LowestIdxLoad, *LatestLoad;
3596 int64_t LowestIdx;
3597 auto MaybeLoadInfo = findLoadOffsetsForLoadOrCombine(
3598 MemOffset2Idx, *RegsToVisit, NarrowMemSizeInBits);
3599 if (!MaybeLoadInfo)
3600 return false;
3601 std::tie(LowestIdxLoad, LowestIdx, LatestLoad) = *MaybeLoadInfo;
3602
3603 // We have a bunch of loads being OR'd together. Using the addresses + offsets
3604 // we found before, check if this corresponds to a big or little endian byte
3605 // pattern. If it does, then we can represent it using a load + possibly a
3606 // BSWAP.
3607 bool IsBigEndianTarget = MF.getDataLayout().isBigEndian();
3608 std::optional<bool> IsBigEndian = isBigEndian(MemOffset2Idx, LowestIdx);
3609 if (!IsBigEndian)
3610 return false;
3611 bool NeedsBSwap = IsBigEndianTarget != *IsBigEndian;
3612 if (NeedsBSwap && !isLegalOrBeforeLegalizer({TargetOpcode::G_BSWAP, {Ty}}))
3613 return false;
3614
3615 // Make sure that the load from the lowest index produces offset 0 in the
3616 // final value.
3617 //
3618 // This ensures that we won't combine something like this:
3619 //
3620 // load x[i] -> byte 2
3621 // load x[i+1] -> byte 0 ---> wide_load x[i]
3622 // load x[i+2] -> byte 1
3623 const unsigned NumLoadsInTy = WideMemSizeInBits / NarrowMemSizeInBits;
3624 const unsigned ZeroByteOffset =
3625 *IsBigEndian
3626 ? bigEndianByteAt(NumLoadsInTy, 0)
3627 : littleEndianByteAt(NumLoadsInTy, 0);
3628 auto ZeroOffsetIdx = MemOffset2Idx.find(ZeroByteOffset);
3629 if (ZeroOffsetIdx == MemOffset2Idx.end() ||
3630 ZeroOffsetIdx->second != LowestIdx)
3631 return false;
3632
3633 // We wil reuse the pointer from the load which ends up at byte offset 0. It
3634 // may not use index 0.
3635 Register Ptr = LowestIdxLoad->getPointerReg();
3636 const MachineMemOperand &MMO = LowestIdxLoad->getMMO();
3637 LegalityQuery::MemDesc MMDesc(MMO);
3638 MMDesc.MemoryTy = Ty;
3639 if (!isLegalOrBeforeLegalizer(
3640 {TargetOpcode::G_LOAD, {Ty, MRI.getType(Ptr)}, {MMDesc}}))
3641 return false;
3642 auto PtrInfo = MMO.getPointerInfo();
3643 auto *NewMMO = MF.getMachineMemOperand(&MMO, PtrInfo, WideMemSizeInBits / 8);
3644
3645 // Load must be allowed and fast on the target.
3646 LLVMContext &C = MF.getFunction().getContext();
3647 auto &DL = MF.getDataLayout();
3648 unsigned Fast = 0;
3649 if (!getTargetLowering().allowsMemoryAccess(C, DL, Ty, *NewMMO, &Fast) ||
3650 !Fast)
3651 return false;
3652
3653 MatchInfo = [=](MachineIRBuilder &MIB) {
3654 MIB.setInstrAndDebugLoc(*LatestLoad);
3655 Register LoadDst = NeedsBSwap ? MRI.cloneVirtualRegister(Dst) : Dst;
3656 MIB.buildLoad(LoadDst, Ptr, *NewMMO);
3657 if (NeedsBSwap)
3658 MIB.buildBSwap(Dst, LoadDst);
3659 };
3660 return true;
3661}
3662
3663bool CombinerHelper::matchExtendThroughPhis(MachineInstr &MI,
3664 MachineInstr *&ExtMI) {
3665 assert(MI.getOpcode() == TargetOpcode::G_PHI)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_PHI
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_PHI"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3665, __extension__
__PRETTY_FUNCTION__))
;
3666
3667 Register DstReg = MI.getOperand(0).getReg();
3668
3669 // TODO: Extending a vector may be expensive, don't do this until heuristics
3670 // are better.
3671 if (MRI.getType(DstReg).isVector())
3672 return false;
3673
3674 // Try to match a phi, whose only use is an extend.
3675 if (!MRI.hasOneNonDBGUse(DstReg))
3676 return false;
3677 ExtMI = &*MRI.use_instr_nodbg_begin(DstReg);
3678 switch (ExtMI->getOpcode()) {
3679 case TargetOpcode::G_ANYEXT:
3680 return true; // G_ANYEXT is usually free.
3681 case TargetOpcode::G_ZEXT:
3682 case TargetOpcode::G_SEXT:
3683 break;
3684 default:
3685 return false;
3686 }
3687
3688 // If the target is likely to fold this extend away, don't propagate.
3689 if (Builder.getTII().isExtendLikelyToBeFolded(*ExtMI, MRI))
3690 return false;
3691
3692 // We don't want to propagate the extends unless there's a good chance that
3693 // they'll be optimized in some way.
3694 // Collect the unique incoming values.
3695 SmallPtrSet<MachineInstr *, 4> InSrcs;
3696 for (unsigned Idx = 1; Idx < MI.getNumOperands(); Idx += 2) {
3697 auto *DefMI = getDefIgnoringCopies(MI.getOperand(Idx).getReg(), MRI);
3698 switch (DefMI->getOpcode()) {
3699 case TargetOpcode::G_LOAD:
3700 case TargetOpcode::G_TRUNC:
3701 case TargetOpcode::G_SEXT:
3702 case TargetOpcode::G_ZEXT:
3703 case TargetOpcode::G_ANYEXT:
3704 case TargetOpcode::G_CONSTANT:
3705 InSrcs.insert(getDefIgnoringCopies(MI.getOperand(Idx).getReg(), MRI));
3706 // Don't try to propagate if there are too many places to create new
3707 // extends, chances are it'll increase code size.
3708 if (InSrcs.size() > 2)
3709 return false;
3710 break;
3711 default:
3712 return false;
3713 }
3714 }
3715 return true;
3716}
3717
3718void CombinerHelper::applyExtendThroughPhis(MachineInstr &MI,
3719 MachineInstr *&ExtMI) {
3720 assert(MI.getOpcode() == TargetOpcode::G_PHI)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_PHI
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_PHI"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3720, __extension__
__PRETTY_FUNCTION__))
;
3721 Register DstReg = ExtMI->getOperand(0).getReg();
3722 LLT ExtTy = MRI.getType(DstReg);
3723
3724 // Propagate the extension into the block of each incoming reg's block.
3725 // Use a SetVector here because PHIs can have duplicate edges, and we want
3726 // deterministic iteration order.
3727 SmallSetVector<MachineInstr *, 8> SrcMIs;
3728 SmallDenseMap<MachineInstr *, MachineInstr *, 8> OldToNewSrcMap;
3729 for (unsigned SrcIdx = 1; SrcIdx < MI.getNumOperands(); SrcIdx += 2) {
3730 auto *SrcMI = MRI.getVRegDef(MI.getOperand(SrcIdx).getReg());
3731 if (!SrcMIs.insert(SrcMI))
3732 continue;
3733
3734 // Build an extend after each src inst.
3735 auto *MBB = SrcMI->getParent();
3736 MachineBasicBlock::iterator InsertPt = ++SrcMI->getIterator();
3737 if (InsertPt != MBB->end() && InsertPt->isPHI())
3738 InsertPt = MBB->getFirstNonPHI();
3739
3740 Builder.setInsertPt(*SrcMI->getParent(), InsertPt);
3741 Builder.setDebugLoc(MI.getDebugLoc());
3742 auto NewExt = Builder.buildExtOrTrunc(ExtMI->getOpcode(), ExtTy,
3743 SrcMI->getOperand(0).getReg());
3744 OldToNewSrcMap[SrcMI] = NewExt;
3745 }
3746
3747 // Create a new phi with the extended inputs.
3748 Builder.setInstrAndDebugLoc(MI);
3749 auto NewPhi = Builder.buildInstrNoInsert(TargetOpcode::G_PHI);
3750 NewPhi.addDef(DstReg);
3751 for (const MachineOperand &MO : llvm::drop_begin(MI.operands())) {
3752 if (!MO.isReg()) {
3753 NewPhi.addMBB(MO.getMBB());
3754 continue;
3755 }
3756 auto *NewSrc = OldToNewSrcMap[MRI.getVRegDef(MO.getReg())];
3757 NewPhi.addUse(NewSrc->getOperand(0).getReg());
3758 }
3759 Builder.insertInstr(NewPhi);
3760 ExtMI->eraseFromParent();
3761}
3762
3763bool CombinerHelper::matchExtractVecEltBuildVec(MachineInstr &MI,
3764 Register &Reg) {
3765 assert(MI.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3765, __extension__
__PRETTY_FUNCTION__))
;
3766 // If we have a constant index, look for a G_BUILD_VECTOR source
3767 // and find the source register that the index maps to.
3768 Register SrcVec = MI.getOperand(1).getReg();
3769 LLT SrcTy = MRI.getType(SrcVec);
3770
3771 auto Cst = getIConstantVRegValWithLookThrough(MI.getOperand(2).getReg(), MRI);
3772 if (!Cst || Cst->Value.getZExtValue() >= SrcTy.getNumElements())
3773 return false;
3774
3775 unsigned VecIdx = Cst->Value.getZExtValue();
3776
3777 // Check if we have a build_vector or build_vector_trunc with an optional
3778 // trunc in front.
3779 MachineInstr *SrcVecMI = MRI.getVRegDef(SrcVec);
3780 if (SrcVecMI->getOpcode() == TargetOpcode::G_TRUNC) {
3781 SrcVecMI = MRI.getVRegDef(SrcVecMI->getOperand(1).getReg());
3782 }
3783
3784 if (SrcVecMI->getOpcode() != TargetOpcode::G_BUILD_VECTOR &&
3785 SrcVecMI->getOpcode() != TargetOpcode::G_BUILD_VECTOR_TRUNC)
3786 return false;
3787
3788 EVT Ty(getMVTForLLT(SrcTy));
3789 if (!MRI.hasOneNonDBGUse(SrcVec) &&
3790 !getTargetLowering().aggressivelyPreferBuildVectorSources(Ty))
3791 return false;
3792
3793 Reg = SrcVecMI->getOperand(VecIdx + 1).getReg();
3794 return true;
3795}
3796
3797void CombinerHelper::applyExtractVecEltBuildVec(MachineInstr &MI,
3798 Register &Reg) {
3799 // Check the type of the register, since it may have come from a
3800 // G_BUILD_VECTOR_TRUNC.
3801 LLT ScalarTy = MRI.getType(Reg);
3802 Register DstReg = MI.getOperand(0).getReg();
3803 LLT DstTy = MRI.getType(DstReg);
3804
3805 Builder.setInstrAndDebugLoc(MI);
3806 if (ScalarTy != DstTy) {
3807 assert(ScalarTy.getSizeInBits() > DstTy.getSizeInBits())(static_cast <bool> (ScalarTy.getSizeInBits() > DstTy
.getSizeInBits()) ? void (0) : __assert_fail ("ScalarTy.getSizeInBits() > DstTy.getSizeInBits()"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3807, __extension__
__PRETTY_FUNCTION__))
;
3808 Builder.buildTrunc(DstReg, Reg);
3809 MI.eraseFromParent();
3810 return;
3811 }
3812 replaceSingleDefInstWithReg(MI, Reg);
3813}
3814
3815bool CombinerHelper::matchExtractAllEltsFromBuildVector(
3816 MachineInstr &MI,
3817 SmallVectorImpl<std::pair<Register, MachineInstr *>> &SrcDstPairs) {
3818 assert(MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3818, __extension__
__PRETTY_FUNCTION__))
;
3819 // This combine tries to find build_vector's which have every source element
3820 // extracted using G_EXTRACT_VECTOR_ELT. This can happen when transforms like
3821 // the masked load scalarization is run late in the pipeline. There's already
3822 // a combine for a similar pattern starting from the extract, but that
3823 // doesn't attempt to do it if there are multiple uses of the build_vector,
3824 // which in this case is true. Starting the combine from the build_vector
3825 // feels more natural than trying to find sibling nodes of extracts.
3826 // E.g.
3827 // %vec(<4 x s32>) = G_BUILD_VECTOR %s1(s32), %s2, %s3, %s4
3828 // %ext1 = G_EXTRACT_VECTOR_ELT %vec, 0
3829 // %ext2 = G_EXTRACT_VECTOR_ELT %vec, 1
3830 // %ext3 = G_EXTRACT_VECTOR_ELT %vec, 2
3831 // %ext4 = G_EXTRACT_VECTOR_ELT %vec, 3
3832 // ==>
3833 // replace ext{1,2,3,4} with %s{1,2,3,4}
3834
3835 Register DstReg = MI.getOperand(0).getReg();
3836 LLT DstTy = MRI.getType(DstReg);
3837 unsigned NumElts = DstTy.getNumElements();
3838
3839 SmallBitVector ExtractedElts(NumElts);
3840 for (MachineInstr &II : MRI.use_nodbg_instructions(DstReg)) {
3841 if (II.getOpcode() != TargetOpcode::G_EXTRACT_VECTOR_ELT)
3842 return false;
3843 auto Cst = getIConstantVRegVal(II.getOperand(2).getReg(), MRI);
3844 if (!Cst)
3845 return false;
3846 unsigned Idx = Cst->getZExtValue();
3847 if (Idx >= NumElts)
3848 return false; // Out of range.
3849 ExtractedElts.set(Idx);
3850 SrcDstPairs.emplace_back(
3851 std::make_pair(MI.getOperand(Idx + 1).getReg(), &II));
3852 }
3853 // Match if every element was extracted.
3854 return ExtractedElts.all();
3855}
3856
3857void CombinerHelper::applyExtractAllEltsFromBuildVector(
3858 MachineInstr &MI,
3859 SmallVectorImpl<std::pair<Register, MachineInstr *>> &SrcDstPairs) {
3860 assert(MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3860, __extension__
__PRETTY_FUNCTION__))
;
3861 for (auto &Pair : SrcDstPairs) {
3862 auto *ExtMI = Pair.second;
3863 replaceRegWith(MRI, ExtMI->getOperand(0).getReg(), Pair.first);
3864 ExtMI->eraseFromParent();
3865 }
3866 MI.eraseFromParent();
3867}
3868
3869void CombinerHelper::applyBuildFn(
3870 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
3871 Builder.setInstrAndDebugLoc(MI);
3872 MatchInfo(Builder);
3873 MI.eraseFromParent();
3874}
3875
3876void CombinerHelper::applyBuildFnNoErase(
3877 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
3878 Builder.setInstrAndDebugLoc(MI);
3879 MatchInfo(Builder);
3880}
3881
3882bool CombinerHelper::matchOrShiftToFunnelShift(MachineInstr &MI,
3883 BuildFnTy &MatchInfo) {
3884 assert(MI.getOpcode() == TargetOpcode::G_OR)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_OR
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_OR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3884, __extension__
__PRETTY_FUNCTION__))
;
3885
3886 Register Dst = MI.getOperand(0).getReg();
3887 LLT Ty = MRI.getType(Dst);
3888 unsigned BitWidth = Ty.getScalarSizeInBits();
3889
3890 Register ShlSrc, ShlAmt, LShrSrc, LShrAmt, Amt;
3891 unsigned FshOpc = 0;
3892
3893 // Match (or (shl ...), (lshr ...)).
3894 if (!mi_match(Dst, MRI,
3895 // m_GOr() handles the commuted version as well.
3896 m_GOr(m_GShl(m_Reg(ShlSrc), m_Reg(ShlAmt)),
3897 m_GLShr(m_Reg(LShrSrc), m_Reg(LShrAmt)))))
3898 return false;
3899
3900 // Given constants C0 and C1 such that C0 + C1 is bit-width:
3901 // (or (shl x, C0), (lshr y, C1)) -> (fshl x, y, C0) or (fshr x, y, C1)
3902 int64_t CstShlAmt, CstLShrAmt;
3903 if (mi_match(ShlAmt, MRI, m_ICstOrSplat(CstShlAmt)) &&
3904 mi_match(LShrAmt, MRI, m_ICstOrSplat(CstLShrAmt)) &&
3905 CstShlAmt + CstLShrAmt == BitWidth) {
3906 FshOpc = TargetOpcode::G_FSHR;
3907 Amt = LShrAmt;
3908
3909 } else if (mi_match(LShrAmt, MRI,
3910 m_GSub(m_SpecificICstOrSplat(BitWidth), m_Reg(Amt))) &&
3911 ShlAmt == Amt) {
3912 // (or (shl x, amt), (lshr y, (sub bw, amt))) -> (fshl x, y, amt)
3913 FshOpc = TargetOpcode::G_FSHL;
3914
3915 } else if (mi_match(ShlAmt, MRI,
3916 m_GSub(m_SpecificICstOrSplat(BitWidth), m_Reg(Amt))) &&
3917 LShrAmt == Amt) {
3918 // (or (shl x, (sub bw, amt)), (lshr y, amt)) -> (fshr x, y, amt)
3919 FshOpc = TargetOpcode::G_FSHR;
3920
3921 } else {
3922 return false;
3923 }
3924
3925 LLT AmtTy = MRI.getType(Amt);
3926 if (!isLegalOrBeforeLegalizer({FshOpc, {Ty, AmtTy}}))
3927 return false;
3928
3929 MatchInfo = [=](MachineIRBuilder &B) {
3930 B.buildInstr(FshOpc, {Dst}, {ShlSrc, LShrSrc, Amt});
3931 };
3932 return true;
3933}
3934
3935/// Match an FSHL or FSHR that can be combined to a ROTR or ROTL rotate.
3936bool CombinerHelper::matchFunnelShiftToRotate(MachineInstr &MI) {
3937 unsigned Opc = MI.getOpcode();
3938 assert(Opc == TargetOpcode::G_FSHL || Opc == TargetOpcode::G_FSHR)(static_cast <bool> (Opc == TargetOpcode::G_FSHL || Opc
== TargetOpcode::G_FSHR) ? void (0) : __assert_fail ("Opc == TargetOpcode::G_FSHL || Opc == TargetOpcode::G_FSHR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3938, __extension__
__PRETTY_FUNCTION__))
;
3939 Register X = MI.getOperand(1).getReg();
3940 Register Y = MI.getOperand(2).getReg();
3941 if (X != Y)
3942 return false;
3943 unsigned RotateOpc =
3944 Opc == TargetOpcode::G_FSHL ? TargetOpcode::G_ROTL : TargetOpcode::G_ROTR;
3945 return isLegalOrBeforeLegalizer({RotateOpc, {MRI.getType(X), MRI.getType(Y)}});
3946}
3947
3948void CombinerHelper::applyFunnelShiftToRotate(MachineInstr &MI) {
3949 unsigned Opc = MI.getOpcode();
3950 assert(Opc == TargetOpcode::G_FSHL || Opc == TargetOpcode::G_FSHR)(static_cast <bool> (Opc == TargetOpcode::G_FSHL || Opc
== TargetOpcode::G_FSHR) ? void (0) : __assert_fail ("Opc == TargetOpcode::G_FSHL || Opc == TargetOpcode::G_FSHR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3950, __extension__
__PRETTY_FUNCTION__))
;
3951 bool IsFSHL = Opc == TargetOpcode::G_FSHL;
3952 Observer.changingInstr(MI);
3953 MI.setDesc(Builder.getTII().get(IsFSHL ? TargetOpcode::G_ROTL
3954 : TargetOpcode::G_ROTR));
3955 MI.removeOperand(2);
3956 Observer.changedInstr(MI);
3957}
3958
3959// Fold (rot x, c) -> (rot x, c % BitSize)
3960bool CombinerHelper::matchRotateOutOfRange(MachineInstr &MI) {
3961 assert(MI.getOpcode() == TargetOpcode::G_ROTL ||(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_ROTL
|| MI.getOpcode() == TargetOpcode::G_ROTR) ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_ROTL || MI.getOpcode() == TargetOpcode::G_ROTR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3962, __extension__
__PRETTY_FUNCTION__))
3962 MI.getOpcode() == TargetOpcode::G_ROTR)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_ROTL
|| MI.getOpcode() == TargetOpcode::G_ROTR) ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_ROTL || MI.getOpcode() == TargetOpcode::G_ROTR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3962, __extension__
__PRETTY_FUNCTION__))
;
3963 unsigned Bitsize =
3964 MRI.getType(MI.getOperand(0).getReg()).getScalarSizeInBits();
3965 Register AmtReg = MI.getOperand(2).getReg();
3966 bool OutOfRange = false;
3967 auto MatchOutOfRange = [Bitsize, &OutOfRange](const Constant *C) {
3968 if (auto *CI = dyn_cast<ConstantInt>(C))
3969 OutOfRange |= CI->getValue().uge(Bitsize);
3970 return true;
3971 };
3972 return matchUnaryPredicate(MRI, AmtReg, MatchOutOfRange) && OutOfRange;
3973}
3974
3975void CombinerHelper::applyRotateOutOfRange(MachineInstr &MI) {
3976 assert(MI.getOpcode() == TargetOpcode::G_ROTL ||(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_ROTL
|| MI.getOpcode() == TargetOpcode::G_ROTR) ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_ROTL || MI.getOpcode() == TargetOpcode::G_ROTR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3977, __extension__
__PRETTY_FUNCTION__))
3977 MI.getOpcode() == TargetOpcode::G_ROTR)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_ROTL
|| MI.getOpcode() == TargetOpcode::G_ROTR) ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_ROTL || MI.getOpcode() == TargetOpcode::G_ROTR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3977, __extension__
__PRETTY_FUNCTION__))
;
3978 unsigned Bitsize =
3979 MRI.getType(MI.getOperand(0).getReg()).getScalarSizeInBits();
3980 Builder.setInstrAndDebugLoc(MI);
3981 Register Amt = MI.getOperand(2).getReg();
3982 LLT AmtTy = MRI.getType(Amt);
3983 auto Bits = Builder.buildConstant(AmtTy, Bitsize);
3984 Amt = Builder.buildURem(AmtTy, MI.getOperand(2).getReg(), Bits).getReg(0);
3985 Observer.changingInstr(MI);
3986 MI.getOperand(2).setReg(Amt);
3987 Observer.changedInstr(MI);
3988}
3989
3990bool CombinerHelper::matchICmpToTrueFalseKnownBits(MachineInstr &MI,
3991 int64_t &MatchInfo) {
3992 assert(MI.getOpcode() == TargetOpcode::G_ICMP)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_ICMP
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_ICMP"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3992, __extension__
__PRETTY_FUNCTION__))
;
3993 auto Pred = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
3994 auto KnownLHS = KB->getKnownBits(MI.getOperand(2).getReg());
3995 auto KnownRHS = KB->getKnownBits(MI.getOperand(3).getReg());
3996 std::optional<bool> KnownVal;
3997 switch (Pred) {
3998 default:
3999 llvm_unreachable("Unexpected G_ICMP predicate?")::llvm::llvm_unreachable_internal("Unexpected G_ICMP predicate?"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 3999)
;
4000 case CmpInst::ICMP_EQ:
4001 KnownVal = KnownBits::eq(KnownLHS, KnownRHS);
4002 break;
4003 case CmpInst::ICMP_NE:
4004 KnownVal = KnownBits::ne(KnownLHS, KnownRHS);
4005 break;
4006 case CmpInst::ICMP_SGE:
4007 KnownVal = KnownBits::sge(KnownLHS, KnownRHS);
4008 break;
4009 case CmpInst::ICMP_SGT:
4010 KnownVal = KnownBits::sgt(KnownLHS, KnownRHS);
4011 break;
4012 case CmpInst::ICMP_SLE:
4013 KnownVal = KnownBits::sle(KnownLHS, KnownRHS);
4014 break;
4015 case CmpInst::ICMP_SLT:
4016 KnownVal = KnownBits::slt(KnownLHS, KnownRHS);
4017 break;
4018 case CmpInst::ICMP_UGE:
4019 KnownVal = KnownBits::uge(KnownLHS, KnownRHS);
4020 break;
4021 case CmpInst::ICMP_UGT:
4022 KnownVal = KnownBits::ugt(KnownLHS, KnownRHS);
4023 break;
4024 case CmpInst::ICMP_ULE:
4025 KnownVal = KnownBits::ule(KnownLHS, KnownRHS);
4026 break;
4027 case CmpInst::ICMP_ULT:
4028 KnownVal = KnownBits::ult(KnownLHS, KnownRHS);
4029 break;
4030 }
4031 if (!KnownVal)
4032 return false;
4033 MatchInfo =
4034 *KnownVal
4035 ? getICmpTrueVal(getTargetLowering(),
4036 /*IsVector = */
4037 MRI.getType(MI.getOperand(0).getReg()).isVector(),
4038 /* IsFP = */ false)
4039 : 0;
4040 return true;
4041}
4042
4043bool CombinerHelper::matchICmpToLHSKnownBits(
4044 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
4045 assert(MI.getOpcode() == TargetOpcode::G_ICMP)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_ICMP
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_ICMP"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4045, __extension__
__PRETTY_FUNCTION__))
;
4046 // Given:
4047 //
4048 // %x = G_WHATEVER (... x is known to be 0 or 1 ...)
4049 // %cmp = G_ICMP ne %x, 0
4050 //
4051 // Or:
4052 //
4053 // %x = G_WHATEVER (... x is known to be 0 or 1 ...)
4054 // %cmp = G_ICMP eq %x, 1
4055 //
4056 // We can replace %cmp with %x assuming true is 1 on the target.
4057 auto Pred = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
4058 if (!CmpInst::isEquality(Pred))
4059 return false;
4060 Register Dst = MI.getOperand(0).getReg();
4061 LLT DstTy = MRI.getType(Dst);
4062 if (getICmpTrueVal(getTargetLowering(), DstTy.isVector(),
4063 /* IsFP = */ false) != 1)
4064 return false;
4065 int64_t OneOrZero = Pred == CmpInst::ICMP_EQ;
4066 if (!mi_match(MI.getOperand(3).getReg(), MRI, m_SpecificICst(OneOrZero)))
4067 return false;
4068 Register LHS = MI.getOperand(2).getReg();
4069 auto KnownLHS = KB->getKnownBits(LHS);
4070 if (KnownLHS.getMinValue() != 0 || KnownLHS.getMaxValue() != 1)
4071 return false;
4072 // Make sure replacing Dst with the LHS is a legal operation.
4073 LLT LHSTy = MRI.getType(LHS);
4074 unsigned LHSSize = LHSTy.getSizeInBits();
4075 unsigned DstSize = DstTy.getSizeInBits();
4076 unsigned Op = TargetOpcode::COPY;
4077 if (DstSize != LHSSize)
4078 Op = DstSize < LHSSize ? TargetOpcode::G_TRUNC : TargetOpcode::G_ZEXT;
4079 if (!isLegalOrBeforeLegalizer({Op, {DstTy, LHSTy}}))
4080 return false;
4081 MatchInfo = [=](MachineIRBuilder &B) { B.buildInstr(Op, {Dst}, {LHS}); };
4082 return true;
4083}
4084
4085// Replace (and (or x, c1), c2) with (and x, c2) iff c1 & c2 == 0
4086bool CombinerHelper::matchAndOrDisjointMask(
4087 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
4088 assert(MI.getOpcode() == TargetOpcode::G_AND)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_AND
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_AND"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4088, __extension__
__PRETTY_FUNCTION__))
;
4089
4090 // Ignore vector types to simplify matching the two constants.
4091 // TODO: do this for vectors and scalars via a demanded bits analysis.
4092 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
4093 if (Ty.isVector())
4094 return false;
4095
4096 Register Src;
4097 Register AndMaskReg;
4098 int64_t AndMaskBits;
4099 int64_t OrMaskBits;
4100 if (!mi_match(MI, MRI,
4101 m_GAnd(m_GOr(m_Reg(Src), m_ICst(OrMaskBits)),
4102 m_all_of(m_ICst(AndMaskBits), m_Reg(AndMaskReg)))))
4103 return false;
4104
4105 // Check if OrMask could turn on any bits in Src.
4106 if (AndMaskBits & OrMaskBits)
4107 return false;
4108
4109 MatchInfo = [=, &MI](MachineIRBuilder &B) {
4110 Observer.changingInstr(MI);
4111 // Canonicalize the result to have the constant on the RHS.
4112 if (MI.getOperand(1).getReg() == AndMaskReg)
4113 MI.getOperand(2).setReg(AndMaskReg);
4114 MI.getOperand(1).setReg(Src);
4115 Observer.changedInstr(MI);
4116 };
4117 return true;
4118}
4119
4120/// Form a G_SBFX from a G_SEXT_INREG fed by a right shift.
4121bool CombinerHelper::matchBitfieldExtractFromSExtInReg(
4122 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
4123 assert(MI.getOpcode() == TargetOpcode::G_SEXT_INREG)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SEXT_INREG
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_SEXT_INREG"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4123, __extension__
__PRETTY_FUNCTION__))
;
4124 Register Dst = MI.getOperand(0).getReg();
4125 Register Src = MI.getOperand(1).getReg();
4126 LLT Ty = MRI.getType(Src);
4127 LLT ExtractTy = getTargetLowering().getPreferredShiftAmountTy(Ty);
4128 if (!LI || !LI->isLegalOrCustom({TargetOpcode::G_SBFX, {Ty, ExtractTy}}))
4129 return false;
4130 int64_t Width = MI.getOperand(2).getImm();
4131 Register ShiftSrc;
4132 int64_t ShiftImm;
4133 if (!mi_match(
4134 Src, MRI,
4135 m_OneNonDBGUse(m_any_of(m_GAShr(m_Reg(ShiftSrc), m_ICst(ShiftImm)),
4136 m_GLShr(m_Reg(ShiftSrc), m_ICst(ShiftImm))))))
4137 return false;
4138 if (ShiftImm < 0 || ShiftImm + Width > Ty.getScalarSizeInBits())
4139 return false;
4140
4141 MatchInfo = [=](MachineIRBuilder &B) {
4142 auto Cst1 = B.buildConstant(ExtractTy, ShiftImm);
4143 auto Cst2 = B.buildConstant(ExtractTy, Width);
4144 B.buildSbfx(Dst, ShiftSrc, Cst1, Cst2);
4145 };
4146 return true;
4147}
4148
4149/// Form a G_UBFX from "(a srl b) & mask", where b and mask are constants.
4150bool CombinerHelper::matchBitfieldExtractFromAnd(
4151 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
4152 assert(MI.getOpcode() == TargetOpcode::G_AND)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_AND
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_AND"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4152, __extension__
__PRETTY_FUNCTION__))
;
4153 Register Dst = MI.getOperand(0).getReg();
4154 LLT Ty = MRI.getType(Dst);
4155 LLT ExtractTy = getTargetLowering().getPreferredShiftAmountTy(Ty);
4156 if (!getTargetLowering().isConstantUnsignedBitfieldExtractLegal(
4157 TargetOpcode::G_UBFX, Ty, ExtractTy))
4158 return false;
4159
4160 int64_t AndImm, LSBImm;
4161 Register ShiftSrc;
4162 const unsigned Size = Ty.getScalarSizeInBits();
4163 if (!mi_match(MI.getOperand(0).getReg(), MRI,
4164 m_GAnd(m_OneNonDBGUse(m_GLShr(m_Reg(ShiftSrc), m_ICst(LSBImm))),
4165 m_ICst(AndImm))))
4166 return false;
4167
4168 // The mask is a mask of the low bits iff imm & (imm+1) == 0.
4169 auto MaybeMask = static_cast<uint64_t>(AndImm);
4170 if (MaybeMask & (MaybeMask + 1))
4171 return false;
4172
4173 // LSB must fit within the register.
4174 if (static_cast<uint64_t>(LSBImm) >= Size)
4175 return false;
4176
4177 uint64_t Width = APInt(Size, AndImm).countr_one();
4178 MatchInfo = [=](MachineIRBuilder &B) {
4179 auto WidthCst = B.buildConstant(ExtractTy, Width);
4180 auto LSBCst = B.buildConstant(ExtractTy, LSBImm);
4181 B.buildInstr(TargetOpcode::G_UBFX, {Dst}, {ShiftSrc, LSBCst, WidthCst});
4182 };
4183 return true;
4184}
4185
4186bool CombinerHelper::matchBitfieldExtractFromShr(
4187 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
4188 const unsigned Opcode = MI.getOpcode();
4189 assert(Opcode == TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR)(static_cast <bool> (Opcode == TargetOpcode::G_ASHR || Opcode
== TargetOpcode::G_LSHR) ? void (0) : __assert_fail ("Opcode == TargetOpcode::G_ASHR || Opcode == TargetOpcode::G_LSHR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4189, __extension__
__PRETTY_FUNCTION__))
;
4190
4191 const Register Dst = MI.getOperand(0).getReg();
4192
4193 const unsigned ExtrOpcode = Opcode == TargetOpcode::G_ASHR
4194 ? TargetOpcode::G_SBFX
4195 : TargetOpcode::G_UBFX;
4196
4197 // Check if the type we would use for the extract is legal
4198 LLT Ty = MRI.getType(Dst);
4199 LLT ExtractTy = getTargetLowering().getPreferredShiftAmountTy(Ty);
4200 if (!LI || !LI->isLegalOrCustom({ExtrOpcode, {Ty, ExtractTy}}))
4201 return false;
4202
4203 Register ShlSrc;
4204 int64_t ShrAmt;
4205 int64_t ShlAmt;
4206 const unsigned Size = Ty.getScalarSizeInBits();
4207
4208 // Try to match shr (shl x, c1), c2
4209 if (!mi_match(Dst, MRI,
4210 m_BinOp(Opcode,
4211 m_OneNonDBGUse(m_GShl(m_Reg(ShlSrc), m_ICst(ShlAmt))),
4212 m_ICst(ShrAmt))))
4213 return false;
4214
4215 // Make sure that the shift sizes can fit a bitfield extract
4216 if (ShlAmt < 0 || ShlAmt > ShrAmt || ShrAmt >= Size)
4217 return false;
4218
4219 // Skip this combine if the G_SEXT_INREG combine could handle it
4220 if (Opcode == TargetOpcode::G_ASHR && ShlAmt == ShrAmt)
4221 return false;
4222
4223 // Calculate start position and width of the extract
4224 const int64_t Pos = ShrAmt - ShlAmt;
4225 const int64_t Width = Size - ShrAmt;
4226
4227 MatchInfo = [=](MachineIRBuilder &B) {
4228 auto WidthCst = B.buildConstant(ExtractTy, Width);
4229 auto PosCst = B.buildConstant(ExtractTy, Pos);
4230 B.buildInstr(ExtrOpcode, {Dst}, {ShlSrc, PosCst, WidthCst});
4231 };
4232 return true;
4233}
4234
4235bool CombinerHelper::matchBitfieldExtractFromShrAnd(
4236 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
4237 const unsigned Opcode = MI.getOpcode();
4238 assert(Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_ASHR)(static_cast <bool> (Opcode == TargetOpcode::G_LSHR || Opcode
== TargetOpcode::G_ASHR) ? void (0) : __assert_fail ("Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_ASHR"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4238, __extension__
__PRETTY_FUNCTION__))
;
4239
4240 const Register Dst = MI.getOperand(0).getReg();
4241 LLT Ty = MRI.getType(Dst);
4242 LLT ExtractTy = getTargetLowering().getPreferredShiftAmountTy(Ty);
4243 if (!getTargetLowering().isConstantUnsignedBitfieldExtractLegal(
4244 TargetOpcode::G_UBFX, Ty, ExtractTy))
4245 return false;
4246
4247 // Try to match shr (and x, c1), c2
4248 Register AndSrc;
4249 int64_t ShrAmt;
4250 int64_t SMask;
4251 if (!mi_match(Dst, MRI,
4252 m_BinOp(Opcode,
4253 m_OneNonDBGUse(m_GAnd(m_Reg(AndSrc), m_ICst(SMask))),
4254 m_ICst(ShrAmt))))
4255 return false;
4256
4257 const unsigned Size = Ty.getScalarSizeInBits();
4258 if (ShrAmt < 0 || ShrAmt >= Size)
4259 return false;
4260
4261 // If the shift subsumes the mask, emit the 0 directly.
4262 if (0 == (SMask >> ShrAmt)) {
4263 MatchInfo = [=](MachineIRBuilder &B) {
4264 B.buildConstant(Dst, 0);
4265 };
4266 return true;
4267 }
4268
4269 // Check that ubfx can do the extraction, with no holes in the mask.
4270 uint64_t UMask = SMask;
4271 UMask |= maskTrailingOnes<uint64_t>(ShrAmt);
4272 UMask &= maskTrailingOnes<uint64_t>(Size);
4273 if (!isMask_64(UMask))
4274 return false;
4275
4276 // Calculate start position and width of the extract.
4277 const int64_t Pos = ShrAmt;
4278 const int64_t Width = llvm::countr_one(UMask) - ShrAmt;
4279
4280 // It's preferable to keep the shift, rather than form G_SBFX.
4281 // TODO: remove the G_AND via demanded bits analysis.
4282 if (Opcode == TargetOpcode::G_ASHR && Width + ShrAmt == Size)
4283 return false;
4284
4285 MatchInfo = [=](MachineIRBuilder &B) {
4286 auto WidthCst = B.buildConstant(ExtractTy, Width);
4287 auto PosCst = B.buildConstant(ExtractTy, Pos);
4288 B.buildInstr(TargetOpcode::G_UBFX, {Dst}, {AndSrc, PosCst, WidthCst});
4289 };
4290 return true;
4291}
4292
4293bool CombinerHelper::reassociationCanBreakAddressingModePattern(
4294 MachineInstr &PtrAdd) {
4295 assert(PtrAdd.getOpcode() == TargetOpcode::G_PTR_ADD)(static_cast <bool> (PtrAdd.getOpcode() == TargetOpcode
::G_PTR_ADD) ? void (0) : __assert_fail ("PtrAdd.getOpcode() == TargetOpcode::G_PTR_ADD"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4295, __extension__
__PRETTY_FUNCTION__))
;
4296
4297 Register Src1Reg = PtrAdd.getOperand(1).getReg();
4298 MachineInstr *Src1Def = getOpcodeDef(TargetOpcode::G_PTR_ADD, Src1Reg, MRI);
4299 if (!Src1Def)
4300 return false;
4301
4302 Register Src2Reg = PtrAdd.getOperand(2).getReg();
4303
4304 if (MRI.hasOneNonDBGUse(Src1Reg))
4305 return false;
4306
4307 auto C1 = getIConstantVRegVal(Src1Def->getOperand(2).getReg(), MRI);
4308 if (!C1)
4309 return false;
4310 auto C2 = getIConstantVRegVal(Src2Reg, MRI);
4311 if (!C2)
4312 return false;
4313
4314 const APInt &C1APIntVal = *C1;
4315 const APInt &C2APIntVal = *C2;
4316 const int64_t CombinedValue = (C1APIntVal + C2APIntVal).getSExtValue();
4317
4318 for (auto &UseMI : MRI.use_nodbg_instructions(Src1Reg)) {
4319 // This combine may end up running before ptrtoint/inttoptr combines
4320 // manage to eliminate redundant conversions, so try to look through them.
4321 MachineInstr *ConvUseMI = &UseMI;
4322 unsigned ConvUseOpc = ConvUseMI->getOpcode();
4323 while (ConvUseOpc == TargetOpcode::G_INTTOPTR ||
4324 ConvUseOpc == TargetOpcode::G_PTRTOINT) {
4325 Register DefReg = ConvUseMI->getOperand(0).getReg();
4326 if (!MRI.hasOneNonDBGUse(DefReg))
4327 break;
4328 ConvUseMI = &*MRI.use_instr_nodbg_begin(DefReg);
4329 ConvUseOpc = ConvUseMI->getOpcode();
4330 }
4331 auto LoadStore = ConvUseOpc == TargetOpcode::G_LOAD ||
4332 ConvUseOpc == TargetOpcode::G_STORE;
4333 if (!LoadStore)
4334 continue;
4335 // Is x[offset2] already not a legal addressing mode? If so then
4336 // reassociating the constants breaks nothing (we test offset2 because
4337 // that's the one we hope to fold into the load or store).
4338 TargetLoweringBase::AddrMode AM;
4339 AM.HasBaseReg = true;
4340 AM.BaseOffs = C2APIntVal.getSExtValue();
4341 unsigned AS =
4342 MRI.getType(ConvUseMI->getOperand(1).getReg()).getAddressSpace();
4343 Type *AccessTy =
4344 getTypeForLLT(MRI.getType(ConvUseMI->getOperand(0).getReg()),
4345 PtrAdd.getMF()->getFunction().getContext());
4346 const auto &TLI = *PtrAdd.getMF()->getSubtarget().getTargetLowering();
4347 if (!TLI.isLegalAddressingMode(PtrAdd.getMF()->getDataLayout(), AM,
4348 AccessTy, AS))
4349 continue;
4350
4351 // Would x[offset1+offset2] still be a legal addressing mode?
4352 AM.BaseOffs = CombinedValue;
4353 if (!TLI.isLegalAddressingMode(PtrAdd.getMF()->getDataLayout(), AM,
4354 AccessTy, AS))
4355 return true;
4356 }
4357
4358 return false;
4359}
4360
4361bool CombinerHelper::matchReassocConstantInnerRHS(GPtrAdd &MI,
4362 MachineInstr *RHS,
4363 BuildFnTy &MatchInfo) {
4364 // G_PTR_ADD(BASE, G_ADD(X, C)) -> G_PTR_ADD(G_PTR_ADD(BASE, X), C)
4365 Register Src1Reg = MI.getOperand(1).getReg();
4366 if (RHS->getOpcode() != TargetOpcode::G_ADD)
4367 return false;
4368 auto C2 = getIConstantVRegVal(RHS->getOperand(2).getReg(), MRI);
4369 if (!C2)
4370 return false;
4371
4372 MatchInfo = [=, &MI](MachineIRBuilder &B) {
4373 LLT PtrTy = MRI.getType(MI.getOperand(0).getReg());
4374
4375 auto NewBase =
4376 Builder.buildPtrAdd(PtrTy, Src1Reg, RHS->getOperand(1).getReg());
4377 Observer.changingInstr(MI);
4378 MI.getOperand(1).setReg(NewBase.getReg(0));
4379 MI.getOperand(2).setReg(RHS->getOperand(2).getReg());
4380 Observer.changedInstr(MI);
4381 };
4382 return !reassociationCanBreakAddressingModePattern(MI);
4383}
4384
4385bool CombinerHelper::matchReassocConstantInnerLHS(GPtrAdd &MI,
4386 MachineInstr *LHS,
4387 MachineInstr *RHS,
4388 BuildFnTy &MatchInfo) {
4389 // G_PTR_ADD (G_PTR_ADD X, C), Y) -> (G_PTR_ADD (G_PTR_ADD(X, Y), C)
4390 // if and only if (G_PTR_ADD X, C) has one use.
4391 Register LHSBase;
4392 std::optional<ValueAndVReg> LHSCstOff;
4393 if (!mi_match(MI.getBaseReg(), MRI,
4394 m_OneNonDBGUse(m_GPtrAdd(m_Reg(LHSBase), m_GCst(LHSCstOff)))))
4395 return false;
4396
4397 auto *LHSPtrAdd = cast<GPtrAdd>(LHS);
4398 MatchInfo = [=, &MI](MachineIRBuilder &B) {
4399 // When we change LHSPtrAdd's offset register we might cause it to use a reg
4400 // before its def. Sink the instruction so the outer PTR_ADD to ensure this
4401 // doesn't happen.
4402 LHSPtrAdd->moveBefore(&MI);
4403 Register RHSReg = MI.getOffsetReg();
4404 // set VReg will cause type mismatch if it comes from extend/trunc
4405 auto NewCst = B.buildConstant(MRI.getType(RHSReg), LHSCstOff->Value);
4406 Observer.changingInstr(MI);
4407 MI.getOperand(2).setReg(NewCst.getReg(0));
4408 Observer.changedInstr(MI);
4409 Observer.changingInstr(*LHSPtrAdd);
4410 LHSPtrAdd->getOperand(2).setReg(RHSReg);
4411 Observer.changedInstr(*LHSPtrAdd);
4412 };
4413 return !reassociationCanBreakAddressingModePattern(MI);
4414}
4415
4416bool CombinerHelper::matchReassocFoldConstantsInSubTree(GPtrAdd &MI,
4417 MachineInstr *LHS,
4418 MachineInstr *RHS,
4419 BuildFnTy &MatchInfo) {
4420 // G_PTR_ADD(G_PTR_ADD(BASE, C1), C2) -> G_PTR_ADD(BASE, C1+C2)
4421 auto *LHSPtrAdd = dyn_cast<GPtrAdd>(LHS);
4422 if (!LHSPtrAdd)
4423 return false;
4424
4425 Register Src2Reg = MI.getOperand(2).getReg();
4426 Register LHSSrc1 = LHSPtrAdd->getBaseReg();
4427 Register LHSSrc2 = LHSPtrAdd->getOffsetReg();
4428 auto C1 = getIConstantVRegVal(LHSSrc2, MRI);
4429 if (!C1)
4430 return false;
4431 auto C2 = getIConstantVRegVal(Src2Reg, MRI);
4432 if (!C2)
4433 return false;
4434
4435 MatchInfo = [=, &MI](MachineIRBuilder &B) {
4436 auto NewCst = B.buildConstant(MRI.getType(Src2Reg), *C1 + *C2);
4437 Observer.changingInstr(MI);
4438 MI.getOperand(1).setReg(LHSSrc1);
4439 MI.getOperand(2).setReg(NewCst.getReg(0));
4440 Observer.changedInstr(MI);
4441 };
4442 return !reassociationCanBreakAddressingModePattern(MI);
4443}
4444
4445bool CombinerHelper::matchReassocPtrAdd(MachineInstr &MI,
4446 BuildFnTy &MatchInfo) {
4447 auto &PtrAdd = cast<GPtrAdd>(MI);
4448 // We're trying to match a few pointer computation patterns here for
4449 // re-association opportunities.
4450 // 1) Isolating a constant operand to be on the RHS, e.g.:
4451 // G_PTR_ADD(BASE, G_ADD(X, C)) -> G_PTR_ADD(G_PTR_ADD(BASE, X), C)
4452 //
4453 // 2) Folding two constants in each sub-tree as long as such folding
4454 // doesn't break a legal addressing mode.
4455 // G_PTR_ADD(G_PTR_ADD(BASE, C1), C2) -> G_PTR_ADD(BASE, C1+C2)
4456 //
4457 // 3) Move a constant from the LHS of an inner op to the RHS of the outer.
4458 // G_PTR_ADD (G_PTR_ADD X, C), Y) -> G_PTR_ADD (G_PTR_ADD(X, Y), C)
4459 // iif (G_PTR_ADD X, C) has one use.
4460 MachineInstr *LHS = MRI.getVRegDef(PtrAdd.getBaseReg());
4461 MachineInstr *RHS = MRI.getVRegDef(PtrAdd.getOffsetReg());
4462
4463 // Try to match example 2.
4464 if (matchReassocFoldConstantsInSubTree(PtrAdd, LHS, RHS, MatchInfo))
4465 return true;
4466
4467 // Try to match example 3.
4468 if (matchReassocConstantInnerLHS(PtrAdd, LHS, RHS, MatchInfo))
4469 return true;
4470
4471 // Try to match example 1.
4472 if (matchReassocConstantInnerRHS(PtrAdd, RHS, MatchInfo))
4473 return true;
4474
4475 return false;
4476}
4477
4478bool CombinerHelper::matchConstantFold(MachineInstr &MI, APInt &MatchInfo) {
4479 Register Op1 = MI.getOperand(1).getReg();
4480 Register Op2 = MI.getOperand(2).getReg();
4481 auto MaybeCst = ConstantFoldBinOp(MI.getOpcode(), Op1, Op2, MRI);
4482 if (!MaybeCst)
4483 return false;
4484 MatchInfo = *MaybeCst;
4485 return true;
4486}
4487
4488bool CombinerHelper::matchNarrowBinopFeedingAnd(
4489 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
4490 // Look for a binop feeding into an AND with a mask:
4491 //
4492 // %add = G_ADD %lhs, %rhs
4493 // %and = G_AND %add, 000...11111111
4494 //
4495 // Check if it's possible to perform the binop at a narrower width and zext
4496 // back to the original width like so:
4497 //
4498 // %narrow_lhs = G_TRUNC %lhs
4499 // %narrow_rhs = G_TRUNC %rhs
4500 // %narrow_add = G_ADD %narrow_lhs, %narrow_rhs
4501 // %new_add = G_ZEXT %narrow_add
4502 // %and = G_AND %new_add, 000...11111111
4503 //
4504 // This can allow later combines to eliminate the G_AND if it turns out
4505 // that the mask is irrelevant.
4506 assert(MI.getOpcode() == TargetOpcode::G_AND)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_AND
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_AND"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4506, __extension__
__PRETTY_FUNCTION__))
;
4507 Register Dst = MI.getOperand(0).getReg();
4508 Register AndLHS = MI.getOperand(1).getReg();
4509 Register AndRHS = MI.getOperand(2).getReg();
4510 LLT WideTy = MRI.getType(Dst);
4511
4512 // If the potential binop has more than one use, then it's possible that one
4513 // of those uses will need its full width.
4514 if (!WideTy.isScalar() || !MRI.hasOneNonDBGUse(AndLHS))
4515 return false;
4516
4517 // Check if the LHS feeding the AND is impacted by the high bits that we're
4518 // masking out.
4519 //
4520 // e.g. for 64-bit x, y:
4521 //
4522 // add_64(x, y) & 65535 == zext(add_16(trunc(x), trunc(y))) & 65535
4523 MachineInstr *LHSInst = getDefIgnoringCopies(AndLHS, MRI);
4524 if (!LHSInst)
4525 return false;
4526 unsigned LHSOpc = LHSInst->getOpcode();
4527 switch (LHSOpc) {
4528 default:
4529 return false;
4530 case TargetOpcode::G_ADD:
4531 case TargetOpcode::G_SUB:
4532 case TargetOpcode::G_MUL:
4533 case TargetOpcode::G_AND:
4534 case TargetOpcode::G_OR:
4535 case TargetOpcode::G_XOR:
4536 break;
4537 }
4538
4539 // Find the mask on the RHS.
4540 auto Cst = getIConstantVRegValWithLookThrough(AndRHS, MRI);
4541 if (!Cst)
4542 return false;
4543 auto Mask = Cst->Value;
4544 if (!Mask.isMask())
4545 return false;
4546
4547 // No point in combining if there's nothing to truncate.
4548 unsigned NarrowWidth = Mask.countr_one();
4549 if (NarrowWidth == WideTy.getSizeInBits())
4550 return false;
4551 LLT NarrowTy = LLT::scalar(NarrowWidth);
4552
4553 // Check if adding the zext + truncates could be harmful.
4554 auto &MF = *MI.getMF();
4555 const auto &TLI = getTargetLowering();
4556 LLVMContext &Ctx = MF.getFunction().getContext();
4557 auto &DL = MF.getDataLayout();
4558 if (!TLI.isTruncateFree(WideTy, NarrowTy, DL, Ctx) ||
4559 !TLI.isZExtFree(NarrowTy, WideTy, DL, Ctx))
4560 return false;
4561 if (!isLegalOrBeforeLegalizer({TargetOpcode::G_TRUNC, {NarrowTy, WideTy}}) ||
4562 !isLegalOrBeforeLegalizer({TargetOpcode::G_ZEXT, {WideTy, NarrowTy}}))
4563 return false;
4564 Register BinOpLHS = LHSInst->getOperand(1).getReg();
4565 Register BinOpRHS = LHSInst->getOperand(2).getReg();
4566 MatchInfo = [=, &MI](MachineIRBuilder &B) {
4567 auto NarrowLHS = Builder.buildTrunc(NarrowTy, BinOpLHS);
4568 auto NarrowRHS = Builder.buildTrunc(NarrowTy, BinOpRHS);
4569 auto NarrowBinOp =
4570 Builder.buildInstr(LHSOpc, {NarrowTy}, {NarrowLHS, NarrowRHS});
4571 auto Ext = Builder.buildZExt(WideTy, NarrowBinOp);
4572 Observer.changingInstr(MI);
4573 MI.getOperand(1).setReg(Ext.getReg(0));
4574 Observer.changedInstr(MI);
4575 };
4576 return true;
4577}
4578
4579bool CombinerHelper::matchMulOBy2(MachineInstr &MI, BuildFnTy &MatchInfo) {
4580 unsigned Opc = MI.getOpcode();
4581 assert(Opc == TargetOpcode::G_UMULO || Opc == TargetOpcode::G_SMULO)(static_cast <bool> (Opc == TargetOpcode::G_UMULO || Opc
== TargetOpcode::G_SMULO) ? void (0) : __assert_fail ("Opc == TargetOpcode::G_UMULO || Opc == TargetOpcode::G_SMULO"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4581, __extension__
__PRETTY_FUNCTION__))
;
4582
4583 if (!mi_match(MI.getOperand(3).getReg(), MRI, m_SpecificICstOrSplat(2)))
4584 return false;
4585
4586 MatchInfo = [=, &MI](MachineIRBuilder &B) {
4587 Observer.changingInstr(MI);
4588 unsigned NewOpc = Opc == TargetOpcode::G_UMULO ? TargetOpcode::G_UADDO
4589 : TargetOpcode::G_SADDO;
4590 MI.setDesc(Builder.getTII().get(NewOpc));
4591 MI.getOperand(3).setReg(MI.getOperand(2).getReg());
4592 Observer.changedInstr(MI);
4593 };
4594 return true;
4595}
4596
4597bool CombinerHelper::matchMulOBy0(MachineInstr &MI, BuildFnTy &MatchInfo) {
4598 // (G_*MULO x, 0) -> 0 + no carry out
4599 assert(MI.getOpcode() == TargetOpcode::G_UMULO ||(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UMULO
|| MI.getOpcode() == TargetOpcode::G_SMULO) ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UMULO || MI.getOpcode() == TargetOpcode::G_SMULO"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4600, __extension__
__PRETTY_FUNCTION__))
4600 MI.getOpcode() == TargetOpcode::G_SMULO)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UMULO
|| MI.getOpcode() == TargetOpcode::G_SMULO) ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UMULO || MI.getOpcode() == TargetOpcode::G_SMULO"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4600, __extension__
__PRETTY_FUNCTION__))
;
4601 if (!mi_match(MI.getOperand(3).getReg(), MRI, m_SpecificICstOrSplat(0)))
4602 return false;
4603 Register Dst = MI.getOperand(0).getReg();
4604 Register Carry = MI.getOperand(1).getReg();
4605 if (!isConstantLegalOrBeforeLegalizer(MRI.getType(Dst)) ||
4606 !isConstantLegalOrBeforeLegalizer(MRI.getType(Carry)))
4607 return false;
4608 MatchInfo = [=](MachineIRBuilder &B) {
4609 B.buildConstant(Dst, 0);
4610 B.buildConstant(Carry, 0);
4611 };
4612 return true;
4613}
4614
4615bool CombinerHelper::matchAddOBy0(MachineInstr &MI, BuildFnTy &MatchInfo) {
4616 // (G_*ADDO x, 0) -> x + no carry out
4617 assert(MI.getOpcode() == TargetOpcode::G_UADDO ||(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UADDO
|| MI.getOpcode() == TargetOpcode::G_SADDO) ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UADDO || MI.getOpcode() == TargetOpcode::G_SADDO"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4618, __extension__
__PRETTY_FUNCTION__))
4618 MI.getOpcode() == TargetOpcode::G_SADDO)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UADDO
|| MI.getOpcode() == TargetOpcode::G_SADDO) ? void (0) : __assert_fail
("MI.getOpcode() == TargetOpcode::G_UADDO || MI.getOpcode() == TargetOpcode::G_SADDO"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4618, __extension__
__PRETTY_FUNCTION__))
;
4619 if (!mi_match(MI.getOperand(3).getReg(), MRI, m_SpecificICstOrSplat(0)))
4620 return false;
4621 Register Carry = MI.getOperand(1).getReg();
4622 if (!isConstantLegalOrBeforeLegalizer(MRI.getType(Carry)))
4623 return false;
4624 Register Dst = MI.getOperand(0).getReg();
4625 Register LHS = MI.getOperand(2).getReg();
4626 MatchInfo = [=](MachineIRBuilder &B) {
4627 B.buildCopy(Dst, LHS);
4628 B.buildConstant(Carry, 0);
4629 };
4630 return true;
4631}
4632
4633bool CombinerHelper::matchAddEToAddO(MachineInstr &MI, BuildFnTy &MatchInfo) {
4634 // (G_*ADDE x, y, 0) -> (G_*ADDO x, y)
4635 // (G_*SUBE x, y, 0) -> (G_*SUBO x, y)
4636 assert(MI.getOpcode() == TargetOpcode::G_UADDE ||(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UADDE
|| MI.getOpcode() == TargetOpcode::G_SADDE || MI.getOpcode()
== TargetOpcode::G_USUBE || MI.getOpcode() == TargetOpcode::
G_SSUBE) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_UADDE || MI.getOpcode() == TargetOpcode::G_SADDE || MI.getOpcode() == TargetOpcode::G_USUBE || MI.getOpcode() == TargetOpcode::G_SSUBE"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4639, __extension__
__PRETTY_FUNCTION__))
4637 MI.getOpcode() == TargetOpcode::G_SADDE ||(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UADDE
|| MI.getOpcode() == TargetOpcode::G_SADDE || MI.getOpcode()
== TargetOpcode::G_USUBE || MI.getOpcode() == TargetOpcode::
G_SSUBE) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_UADDE || MI.getOpcode() == TargetOpcode::G_SADDE || MI.getOpcode() == TargetOpcode::G_USUBE || MI.getOpcode() == TargetOpcode::G_SSUBE"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4639, __extension__
__PRETTY_FUNCTION__))
4638 MI.getOpcode() == TargetOpcode::G_USUBE ||(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UADDE
|| MI.getOpcode() == TargetOpcode::G_SADDE || MI.getOpcode()
== TargetOpcode::G_USUBE || MI.getOpcode() == TargetOpcode::
G_SSUBE) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_UADDE || MI.getOpcode() == TargetOpcode::G_SADDE || MI.getOpcode() == TargetOpcode::G_USUBE || MI.getOpcode() == TargetOpcode::G_SSUBE"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4639, __extension__
__PRETTY_FUNCTION__))
4639 MI.getOpcode() == TargetOpcode::G_SSUBE)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UADDE
|| MI.getOpcode() == TargetOpcode::G_SADDE || MI.getOpcode()
== TargetOpcode::G_USUBE || MI.getOpcode() == TargetOpcode::
G_SSUBE) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_UADDE || MI.getOpcode() == TargetOpcode::G_SADDE || MI.getOpcode() == TargetOpcode::G_USUBE || MI.getOpcode() == TargetOpcode::G_SSUBE"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4639, __extension__
__PRETTY_FUNCTION__))
;
4640 if (!mi_match(MI.getOperand(4).getReg(), MRI, m_SpecificICstOrSplat(0)))
4641 return false;
4642 MatchInfo = [&](MachineIRBuilder &B) {
4643 unsigned NewOpcode;
4644 switch (MI.getOpcode()) {
4645 case TargetOpcode::G_UADDE:
4646 NewOpcode = TargetOpcode::G_UADDO;
4647 break;
4648 case TargetOpcode::G_SADDE:
4649 NewOpcode = TargetOpcode::G_SADDO;
4650 break;
4651 case TargetOpcode::G_USUBE:
4652 NewOpcode = TargetOpcode::G_USUBO;
4653 break;
4654 case TargetOpcode::G_SSUBE:
4655 NewOpcode = TargetOpcode::G_SSUBO;
4656 break;
4657 }
4658 Observer.changingInstr(MI);
4659 MI.setDesc(B.getTII().get(NewOpcode));
4660 MI.removeOperand(4);
4661 Observer.changedInstr(MI);
4662 };
4663 return true;
4664}
4665
4666bool CombinerHelper::matchSubAddSameReg(MachineInstr &MI,
4667 BuildFnTy &MatchInfo) {
4668 assert(MI.getOpcode() == TargetOpcode::G_SUB)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SUB
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_SUB"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4668, __extension__
__PRETTY_FUNCTION__))
;
4669 Register Dst = MI.getOperand(0).getReg();
4670 // (x + y) - z -> x (if y == z)
4671 // (x + y) - z -> y (if x == z)
4672 Register X, Y, Z;
4673 if (mi_match(Dst, MRI, m_GSub(m_GAdd(m_Reg(X), m_Reg(Y)), m_Reg(Z)))) {
4674 Register ReplaceReg;
4675 int64_t CstX, CstY;
4676 if (Y == Z || (mi_match(Y, MRI, m_ICstOrSplat(CstY)) &&
4677 mi_match(Z, MRI, m_SpecificICstOrSplat(CstY))))
4678 ReplaceReg = X;
4679 else if (X == Z || (mi_match(X, MRI, m_ICstOrSplat(CstX)) &&
4680 mi_match(Z, MRI, m_SpecificICstOrSplat(CstX))))
4681 ReplaceReg = Y;
4682 if (ReplaceReg) {
4683 MatchInfo = [=](MachineIRBuilder &B) { B.buildCopy(Dst, ReplaceReg); };
4684 return true;
4685 }
4686 }
4687
4688 // x - (y + z) -> 0 - y (if x == z)
4689 // x - (y + z) -> 0 - z (if x == y)
4690 if (mi_match(Dst, MRI, m_GSub(m_Reg(X), m_GAdd(m_Reg(Y), m_Reg(Z))))) {
4691 Register ReplaceReg;
4692 int64_t CstX;
4693 if (X == Z || (mi_match(X, MRI, m_ICstOrSplat(CstX)) &&
4694 mi_match(Z, MRI, m_SpecificICstOrSplat(CstX))))
4695 ReplaceReg = Y;
4696 else if (X == Y || (mi_match(X, MRI, m_ICstOrSplat(CstX)) &&
4697 mi_match(Y, MRI, m_SpecificICstOrSplat(CstX))))
4698 ReplaceReg = Z;
4699 if (ReplaceReg) {
4700 MatchInfo = [=](MachineIRBuilder &B) {
4701 auto Zero = B.buildConstant(MRI.getType(Dst), 0);
4702 B.buildSub(Dst, Zero, ReplaceReg);
4703 };
4704 return true;
4705 }
4706 }
4707 return false;
4708}
4709
4710MachineInstr *CombinerHelper::buildUDivUsingMul(MachineInstr &MI) {
4711 assert(MI.getOpcode() == TargetOpcode::G_UDIV)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UDIV
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_UDIV"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4711, __extension__
__PRETTY_FUNCTION__))
;
4712 auto &UDiv = cast<GenericMachineInstr>(MI);
4713 Register Dst = UDiv.getReg(0);
4714 Register LHS = UDiv.getReg(1);
4715 Register RHS = UDiv.getReg(2);
4716 LLT Ty = MRI.getType(Dst);
4717 LLT ScalarTy = Ty.getScalarType();
4718 const unsigned EltBits = ScalarTy.getScalarSizeInBits();
4719 LLT ShiftAmtTy = getTargetLowering().getPreferredShiftAmountTy(Ty);
4720 LLT ScalarShiftAmtTy = ShiftAmtTy.getScalarType();
4721 auto &MIB = Builder;
4722 MIB.setInstrAndDebugLoc(MI);
4723
4724 bool UseNPQ = false;
4725 SmallVector<Register, 16> PreShifts, PostShifts, MagicFactors, NPQFactors;
4726
4727 auto BuildUDIVPattern = [&](const Constant *C) {
4728 auto *CI = cast<ConstantInt>(C);
4729 const APInt &Divisor = CI->getValue();
4730
4731 bool SelNPQ = false;
4732 APInt Magic(Divisor.getBitWidth(), 0);
4733 unsigned PreShift = 0, PostShift = 0;
4734
4735 // Magic algorithm doesn't work for division by 1. We need to emit a select
4736 // at the end.
4737 // TODO: Use undef values for divisor of 1.
4738 if (!Divisor.isOne()) {
4739 UnsignedDivisionByConstantInfo magics =
4740 UnsignedDivisionByConstantInfo::get(Divisor);
4741
4742 Magic = std::move(magics.Magic);
4743
4744 assert(magics.PreShift < Divisor.getBitWidth() &&(static_cast <bool> (magics.PreShift < Divisor.getBitWidth
() && "We shouldn't generate an undefined shift!") ? void
(0) : __assert_fail ("magics.PreShift < Divisor.getBitWidth() && \"We shouldn't generate an undefined shift!\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4745, __extension__
__PRETTY_FUNCTION__))
4745 "We shouldn't generate an undefined shift!")(static_cast <bool> (magics.PreShift < Divisor.getBitWidth
() && "We shouldn't generate an undefined shift!") ? void
(0) : __assert_fail ("magics.PreShift < Divisor.getBitWidth() && \"We shouldn't generate an undefined shift!\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4745, __extension__
__PRETTY_FUNCTION__))
;
4746 assert(magics.PostShift < Divisor.getBitWidth() &&(static_cast <bool> (magics.PostShift < Divisor.getBitWidth
() && "We shouldn't generate an undefined shift!") ? void
(0) : __assert_fail ("magics.PostShift < Divisor.getBitWidth() && \"We shouldn't generate an undefined shift!\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4747, __extension__
__PRETTY_FUNCTION__))
4747 "We shouldn't generate an undefined shift!")(static_cast <bool> (magics.PostShift < Divisor.getBitWidth
() && "We shouldn't generate an undefined shift!") ? void
(0) : __assert_fail ("magics.PostShift < Divisor.getBitWidth() && \"We shouldn't generate an undefined shift!\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4747, __extension__
__PRETTY_FUNCTION__))
;
4748 assert((!magics.IsAdd || magics.PreShift == 0) && "Unexpected pre-shift")(static_cast <bool> ((!magics.IsAdd || magics.PreShift ==
0) && "Unexpected pre-shift") ? void (0) : __assert_fail
("(!magics.IsAdd || magics.PreShift == 0) && \"Unexpected pre-shift\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4748, __extension__
__PRETTY_FUNCTION__))
;
4749 PreShift = magics.PreShift;
4750 PostShift = magics.PostShift;
4751 SelNPQ = magics.IsAdd;
4752 }
4753
4754 PreShifts.push_back(
4755 MIB.buildConstant(ScalarShiftAmtTy, PreShift).getReg(0));
4756 MagicFactors.push_back(MIB.buildConstant(ScalarTy, Magic).getReg(0));
4757 NPQFactors.push_back(
4758 MIB.buildConstant(ScalarTy,
4759 SelNPQ ? APInt::getOneBitSet(EltBits, EltBits - 1)
4760 : APInt::getZero(EltBits))
4761 .getReg(0));
4762 PostShifts.push_back(
4763 MIB.buildConstant(ScalarShiftAmtTy, PostShift).getReg(0));
4764 UseNPQ |= SelNPQ;
4765 return true;
4766 };
4767
4768 // Collect the shifts/magic values from each element.
4769 bool Matched = matchUnaryPredicate(MRI, RHS, BuildUDIVPattern);
4770 (void)Matched;
4771 assert(Matched && "Expected unary predicate match to succeed")(static_cast <bool> (Matched && "Expected unary predicate match to succeed"
) ? void (0) : __assert_fail ("Matched && \"Expected unary predicate match to succeed\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4771, __extension__
__PRETTY_FUNCTION__))
;
4772
4773 Register PreShift, PostShift, MagicFactor, NPQFactor;
4774 auto *RHSDef = getOpcodeDef<GBuildVector>(RHS, MRI);
4775 if (RHSDef) {
4776 PreShift = MIB.buildBuildVector(ShiftAmtTy, PreShifts).getReg(0);
4777 MagicFactor = MIB.buildBuildVector(Ty, MagicFactors).getReg(0);
4778 NPQFactor = MIB.buildBuildVector(Ty, NPQFactors).getReg(0);
4779 PostShift = MIB.buildBuildVector(ShiftAmtTy, PostShifts).getReg(0);
4780 } else {
4781 assert(MRI.getType(RHS).isScalar() &&(static_cast <bool> (MRI.getType(RHS).isScalar() &&
"Non-build_vector operation should have been a scalar") ? void
(0) : __assert_fail ("MRI.getType(RHS).isScalar() && \"Non-build_vector operation should have been a scalar\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4782, __extension__
__PRETTY_FUNCTION__))
4782 "Non-build_vector operation should have been a scalar")(static_cast <bool> (MRI.getType(RHS).isScalar() &&
"Non-build_vector operation should have been a scalar") ? void
(0) : __assert_fail ("MRI.getType(RHS).isScalar() && \"Non-build_vector operation should have been a scalar\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4782, __extension__
__PRETTY_FUNCTION__))
;
4783 PreShift = PreShifts[0];
4784 MagicFactor = MagicFactors[0];
4785 PostShift = PostShifts[0];
4786 }
4787
4788 Register Q = LHS;
4789 Q = MIB.buildLShr(Ty, Q, PreShift).getReg(0);
4790
4791 // Multiply the numerator (operand 0) by the magic value.
4792 Q = MIB.buildUMulH(Ty, Q, MagicFactor).getReg(0);
4793
4794 if (UseNPQ) {
4795 Register NPQ = MIB.buildSub(Ty, LHS, Q).getReg(0);
4796
4797 // For vectors we might have a mix of non-NPQ/NPQ paths, so use
4798 // G_UMULH to act as a SRL-by-1 for NPQ, else multiply by zero.
4799 if (Ty.isVector())
4800 NPQ = MIB.buildUMulH(Ty, NPQ, NPQFactor).getReg(0);
4801 else
4802 NPQ = MIB.buildLShr(Ty, NPQ, MIB.buildConstant(ShiftAmtTy, 1)).getReg(0);
4803
4804 Q = MIB.buildAdd(Ty, NPQ, Q).getReg(0);
4805 }
4806
4807 Q = MIB.buildLShr(Ty, Q, PostShift).getReg(0);
4808 auto One = MIB.buildConstant(Ty, 1);
4809 auto IsOne = MIB.buildICmp(
4810 CmpInst::Predicate::ICMP_EQ,
4811 Ty.isScalar() ? LLT::scalar(1) : Ty.changeElementSize(1), RHS, One);
4812 return MIB.buildSelect(Ty, IsOne, LHS, Q);
4813}
4814
4815bool CombinerHelper::matchUDivByConst(MachineInstr &MI) {
4816 assert(MI.getOpcode() == TargetOpcode::G_UDIV)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UDIV
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_UDIV"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4816, __extension__
__PRETTY_FUNCTION__))
;
4817 Register Dst = MI.getOperand(0).getReg();
4818 Register RHS = MI.getOperand(2).getReg();
4819 LLT DstTy = MRI.getType(Dst);
4820 auto *RHSDef = MRI.getVRegDef(RHS);
4821 if (!isConstantOrConstantVector(*RHSDef, MRI))
4822 return false;
4823
4824 auto &MF = *MI.getMF();
4825 AttributeList Attr = MF.getFunction().getAttributes();
4826 const auto &TLI = getTargetLowering();
4827 LLVMContext &Ctx = MF.getFunction().getContext();
4828 auto &DL = MF.getDataLayout();
4829 if (TLI.isIntDivCheap(getApproximateEVTForLLT(DstTy, DL, Ctx), Attr))
4830 return false;
4831
4832 // Don't do this for minsize because the instruction sequence is usually
4833 // larger.
4834 if (MF.getFunction().hasMinSize())
4835 return false;
4836
4837 // Don't do this if the types are not going to be legal.
4838 if (LI) {
4839 if (!isLegalOrBeforeLegalizer({TargetOpcode::G_MUL, {DstTy, DstTy}}))
4840 return false;
4841 if (!isLegalOrBeforeLegalizer({TargetOpcode::G_UMULH, {DstTy}}))
4842 return false;
4843 if (!isLegalOrBeforeLegalizer(
4844 {TargetOpcode::G_ICMP,
4845 {DstTy.isVector() ? DstTy.changeElementSize(1) : LLT::scalar(1),
4846 DstTy}}))
4847 return false;
4848 }
4849
4850 auto CheckEltValue = [&](const Constant *C) {
4851 if (auto *CI = dyn_cast_or_null<ConstantInt>(C))
4852 return !CI->isZero();
4853 return false;
4854 };
4855 return matchUnaryPredicate(MRI, RHS, CheckEltValue);
4856}
4857
4858void CombinerHelper::applyUDivByConst(MachineInstr &MI) {
4859 auto *NewMI = buildUDivUsingMul(MI);
4860 replaceSingleDefInstWithReg(MI, NewMI->getOperand(0).getReg());
4861}
4862
4863bool CombinerHelper::matchSDivByConst(MachineInstr &MI) {
4864 assert(MI.getOpcode() == TargetOpcode::G_SDIV && "Expected SDIV")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SDIV
&& "Expected SDIV") ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_SDIV && \"Expected SDIV\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4864, __extension__
__PRETTY_FUNCTION__))
;
4865 Register Dst = MI.getOperand(0).getReg();
4866 Register RHS = MI.getOperand(2).getReg();
4867 LLT DstTy = MRI.getType(Dst);
4868
4869 auto &MF = *MI.getMF();
4870 AttributeList Attr = MF.getFunction().getAttributes();
4871 const auto &TLI = getTargetLowering();
4872 LLVMContext &Ctx = MF.getFunction().getContext();
4873 auto &DL = MF.getDataLayout();
4874 if (TLI.isIntDivCheap(getApproximateEVTForLLT(DstTy, DL, Ctx), Attr))
4875 return false;
4876
4877 // Don't do this for minsize because the instruction sequence is usually
4878 // larger.
4879 if (MF.getFunction().hasMinSize())
4880 return false;
4881
4882 // If the sdiv has an 'exact' flag we can use a simpler lowering.
4883 if (MI.getFlag(MachineInstr::MIFlag::IsExact)) {
4884 return matchUnaryPredicate(
4885 MRI, RHS, [](const Constant *C) { return C && !C->isZeroValue(); });
4886 }
4887
4888 // Don't support the general case for now.
4889 return false;
4890}
4891
4892void CombinerHelper::applySDivByConst(MachineInstr &MI) {
4893 auto *NewMI = buildSDivUsingMul(MI);
4894 replaceSingleDefInstWithReg(MI, NewMI->getOperand(0).getReg());
4895}
4896
4897MachineInstr *CombinerHelper::buildSDivUsingMul(MachineInstr &MI) {
4898 assert(MI.getOpcode() == TargetOpcode::G_SDIV && "Expected SDIV")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SDIV
&& "Expected SDIV") ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_SDIV && \"Expected SDIV\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4898, __extension__
__PRETTY_FUNCTION__))
;
4899 auto &SDiv = cast<GenericMachineInstr>(MI);
4900 Register Dst = SDiv.getReg(0);
4901 Register LHS = SDiv.getReg(1);
4902 Register RHS = SDiv.getReg(2);
4903 LLT Ty = MRI.getType(Dst);
4904 LLT ScalarTy = Ty.getScalarType();
4905 LLT ShiftAmtTy = getTargetLowering().getPreferredShiftAmountTy(Ty);
4906 LLT ScalarShiftAmtTy = ShiftAmtTy.getScalarType();
4907 auto &MIB = Builder;
4908 MIB.setInstrAndDebugLoc(MI);
4909
4910 bool UseSRA = false;
4911 SmallVector<Register, 16> Shifts, Factors;
4912
4913 auto *RHSDef = cast<GenericMachineInstr>(getDefIgnoringCopies(RHS, MRI));
4914 bool IsSplat = getIConstantSplatVal(*RHSDef, MRI).has_value();
4915
4916 auto BuildSDIVPattern = [&](const Constant *C) {
4917 // Don't recompute inverses for each splat element.
4918 if (IsSplat && !Factors.empty()) {
4919 Shifts.push_back(Shifts[0]);
4920 Factors.push_back(Factors[0]);
4921 return true;
4922 }
4923
4924 auto *CI = cast<ConstantInt>(C);
4925 APInt Divisor = CI->getValue();
4926 unsigned Shift = Divisor.countr_zero();
4927 if (Shift) {
4928 Divisor.ashrInPlace(Shift);
4929 UseSRA = true;
4930 }
4931
4932 // Calculate the multiplicative inverse modulo BW.
4933 // 2^W requires W + 1 bits, so we have to extend and then truncate.
4934 unsigned W = Divisor.getBitWidth();
4935 APInt Factor = Divisor.zext(W + 1)
4936 .multiplicativeInverse(APInt::getSignedMinValue(W + 1))
4937 .trunc(W);
4938 Shifts.push_back(MIB.buildConstant(ScalarShiftAmtTy, Shift).getReg(0));
4939 Factors.push_back(MIB.buildConstant(ScalarTy, Factor).getReg(0));
4940 return true;
4941 };
4942
4943 // Collect all magic values from the build vector.
4944 bool Matched = matchUnaryPredicate(MRI, RHS, BuildSDIVPattern);
4945 (void)Matched;
4946 assert(Matched && "Expected unary predicate match to succeed")(static_cast <bool> (Matched && "Expected unary predicate match to succeed"
) ? void (0) : __assert_fail ("Matched && \"Expected unary predicate match to succeed\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4946, __extension__
__PRETTY_FUNCTION__))
;
4947
4948 Register Shift, Factor;
4949 if (Ty.isVector()) {
4950 Shift = MIB.buildBuildVector(ShiftAmtTy, Shifts).getReg(0);
4951 Factor = MIB.buildBuildVector(Ty, Factors).getReg(0);
4952 } else {
4953 Shift = Shifts[0];
4954 Factor = Factors[0];
4955 }
4956
4957 Register Res = LHS;
4958
4959 if (UseSRA)
4960 Res = MIB.buildAShr(Ty, Res, Shift, MachineInstr::IsExact).getReg(0);
4961
4962 return MIB.buildMul(Ty, Res, Factor);
4963}
4964
4965bool CombinerHelper::matchUMulHToLShr(MachineInstr &MI) {
4966 assert(MI.getOpcode() == TargetOpcode::G_UMULH)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_UMULH
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_UMULH"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 4966, __extension__
__PRETTY_FUNCTION__))
;
4967 Register RHS = MI.getOperand(2).getReg();
4968 Register Dst = MI.getOperand(0).getReg();
4969 LLT Ty = MRI.getType(Dst);
4970 LLT ShiftAmtTy = getTargetLowering().getPreferredShiftAmountTy(Ty);
4971 auto MatchPow2ExceptOne = [&](const Constant *C) {
4972 if (auto *CI = dyn_cast<ConstantInt>(C))
4973 return CI->getValue().isPowerOf2() && !CI->getValue().isOne();
4974 return false;
4975 };
4976 if (!matchUnaryPredicate(MRI, RHS, MatchPow2ExceptOne, false))
4977 return false;
4978 return isLegalOrBeforeLegalizer({TargetOpcode::G_LSHR, {Ty, ShiftAmtTy}});
4979}
4980
4981void CombinerHelper::applyUMulHToLShr(MachineInstr &MI) {
4982 Register LHS = MI.getOperand(1).getReg();
4983 Register RHS = MI.getOperand(2).getReg();
4984 Register Dst = MI.getOperand(0).getReg();
4985 LLT Ty = MRI.getType(Dst);
4986 LLT ShiftAmtTy = getTargetLowering().getPreferredShiftAmountTy(Ty);
4987 unsigned NumEltBits = Ty.getScalarSizeInBits();
4988
4989 Builder.setInstrAndDebugLoc(MI);
4990 auto LogBase2 = buildLogBase2(RHS, Builder);
4991 auto ShiftAmt =
4992 Builder.buildSub(Ty, Builder.buildConstant(Ty, NumEltBits), LogBase2);
4993 auto Trunc = Builder.buildZExtOrTrunc(ShiftAmtTy, ShiftAmt);
4994 Builder.buildLShr(Dst, LHS, Trunc);
4995 MI.eraseFromParent();
4996}
4997
4998bool CombinerHelper::matchRedundantNegOperands(MachineInstr &MI,
4999 BuildFnTy &MatchInfo) {
5000 unsigned Opc = MI.getOpcode();
5001 assert(Opc == TargetOpcode::G_FADD || Opc == TargetOpcode::G_FSUB ||(static_cast <bool> (Opc == TargetOpcode::G_FADD || Opc
== TargetOpcode::G_FSUB || Opc == TargetOpcode::G_FMUL || Opc
== TargetOpcode::G_FDIV || Opc == TargetOpcode::G_FMAD || Opc
== TargetOpcode::G_FMA) ? void (0) : __assert_fail ("Opc == TargetOpcode::G_FADD || Opc == TargetOpcode::G_FSUB || Opc == TargetOpcode::G_FMUL || Opc == TargetOpcode::G_FDIV || Opc == TargetOpcode::G_FMAD || Opc == TargetOpcode::G_FMA"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5003, __extension__
__PRETTY_FUNCTION__))
5002 Opc == TargetOpcode::G_FMUL || Opc == TargetOpcode::G_FDIV ||(static_cast <bool> (Opc == TargetOpcode::G_FADD || Opc
== TargetOpcode::G_FSUB || Opc == TargetOpcode::G_FMUL || Opc
== TargetOpcode::G_FDIV || Opc == TargetOpcode::G_FMAD || Opc
== TargetOpcode::G_FMA) ? void (0) : __assert_fail ("Opc == TargetOpcode::G_FADD || Opc == TargetOpcode::G_FSUB || Opc == TargetOpcode::G_FMUL || Opc == TargetOpcode::G_FDIV || Opc == TargetOpcode::G_FMAD || Opc == TargetOpcode::G_FMA"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5003, __extension__
__PRETTY_FUNCTION__))
5003 Opc == TargetOpcode::G_FMAD || Opc == TargetOpcode::G_FMA)(static_cast <bool> (Opc == TargetOpcode::G_FADD || Opc
== TargetOpcode::G_FSUB || Opc == TargetOpcode::G_FMUL || Opc
== TargetOpcode::G_FDIV || Opc == TargetOpcode::G_FMAD || Opc
== TargetOpcode::G_FMA) ? void (0) : __assert_fail ("Opc == TargetOpcode::G_FADD || Opc == TargetOpcode::G_FSUB || Opc == TargetOpcode::G_FMUL || Opc == TargetOpcode::G_FDIV || Opc == TargetOpcode::G_FMAD || Opc == TargetOpcode::G_FMA"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5003, __extension__
__PRETTY_FUNCTION__))
;
5004
5005 Register Dst = MI.getOperand(0).getReg();
5006 Register X = MI.getOperand(1).getReg();
5007 Register Y = MI.getOperand(2).getReg();
5008 LLT Type = MRI.getType(Dst);
5009
5010 // fold (fadd x, fneg(y)) -> (fsub x, y)
5011 // fold (fadd fneg(y), x) -> (fsub x, y)
5012 // G_ADD is commutative so both cases are checked by m_GFAdd
5013 if (mi_match(Dst, MRI, m_GFAdd(m_Reg(X), m_GFNeg(m_Reg(Y)))) &&
5014 isLegalOrBeforeLegalizer({TargetOpcode::G_FSUB, {Type}})) {
5015 Opc = TargetOpcode::G_FSUB;
5016 }
5017 /// fold (fsub x, fneg(y)) -> (fadd x, y)
5018 else if (mi_match(Dst, MRI, m_GFSub(m_Reg(X), m_GFNeg(m_Reg(Y)))) &&
5019 isLegalOrBeforeLegalizer({TargetOpcode::G_FADD, {Type}})) {
5020 Opc = TargetOpcode::G_FADD;
5021 }
5022 // fold (fmul fneg(x), fneg(y)) -> (fmul x, y)
5023 // fold (fdiv fneg(x), fneg(y)) -> (fdiv x, y)
5024 // fold (fmad fneg(x), fneg(y), z) -> (fmad x, y, z)
5025 // fold (fma fneg(x), fneg(y), z) -> (fma x, y, z)
5026 else if ((Opc == TargetOpcode::G_FMUL || Opc == TargetOpcode::G_FDIV ||
5027 Opc == TargetOpcode::G_FMAD || Opc == TargetOpcode::G_FMA) &&
5028 mi_match(X, MRI, m_GFNeg(m_Reg(X))) &&
5029 mi_match(Y, MRI, m_GFNeg(m_Reg(Y)))) {
5030 // no opcode change
5031 } else
5032 return false;
5033
5034 MatchInfo = [=, &MI](MachineIRBuilder &B) {
5035 Observer.changingInstr(MI);
5036 MI.setDesc(B.getTII().get(Opc));
5037 MI.getOperand(1).setReg(X);
5038 MI.getOperand(2).setReg(Y);
5039 Observer.changedInstr(MI);
5040 };
5041 return true;
5042}
5043
5044bool CombinerHelper::matchFsubToFneg(MachineInstr &MI, Register &MatchInfo) {
5045 assert(MI.getOpcode() == TargetOpcode::G_FSUB)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_FSUB
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_FSUB"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5045, __extension__
__PRETTY_FUNCTION__))
;
5046
5047 Register LHS = MI.getOperand(1).getReg();
5048 MatchInfo = MI.getOperand(2).getReg();
5049 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
5050
5051 const auto LHSCst = Ty.isVector()
5052 ? getFConstantSplat(LHS, MRI, /* allowUndef */ true)
5053 : getFConstantVRegValWithLookThrough(LHS, MRI);
5054 if (!LHSCst)
5055 return false;
5056
5057 // -0.0 is always allowed
5058 if (LHSCst->Value.isNegZero())
5059 return true;
5060
5061 // +0.0 is only allowed if nsz is set.
5062 if (LHSCst->Value.isPosZero())
5063 return MI.getFlag(MachineInstr::FmNsz);
5064
5065 return false;
5066}
5067
5068void CombinerHelper::applyFsubToFneg(MachineInstr &MI, Register &MatchInfo) {
5069 Builder.setInstrAndDebugLoc(MI);
5070 Register Dst = MI.getOperand(0).getReg();
5071 Builder.buildFNeg(
5072 Dst, Builder.buildFCanonicalize(MRI.getType(Dst), MatchInfo).getReg(0));
5073 eraseInst(MI);
5074}
5075
5076/// Checks if \p MI is TargetOpcode::G_FMUL and contractable either
5077/// due to global flags or MachineInstr flags.
5078static bool isContractableFMul(MachineInstr &MI, bool AllowFusionGlobally) {
5079 if (MI.getOpcode() != TargetOpcode::G_FMUL)
5080 return false;
5081 return AllowFusionGlobally || MI.getFlag(MachineInstr::MIFlag::FmContract);
5082}
5083
5084static bool hasMoreUses(const MachineInstr &MI0, const MachineInstr &MI1,
5085 const MachineRegisterInfo &MRI) {
5086 return std::distance(MRI.use_instr_nodbg_begin(MI0.getOperand(0).getReg()),
5087 MRI.use_instr_nodbg_end()) >
5088 std::distance(MRI.use_instr_nodbg_begin(MI1.getOperand(0).getReg()),
5089 MRI.use_instr_nodbg_end());
5090}
5091
5092bool CombinerHelper::canCombineFMadOrFMA(MachineInstr &MI,
5093 bool &AllowFusionGlobally,
5094 bool &HasFMAD, bool &Aggressive,
5095 bool CanReassociate) {
5096
5097 auto *MF = MI.getMF();
5098 const auto &TLI = *MF->getSubtarget().getTargetLowering();
5099 const TargetOptions &Options = MF->getTarget().Options;
5100 LLT DstType = MRI.getType(MI.getOperand(0).getReg());
5101
5102 if (CanReassociate &&
5103 !(Options.UnsafeFPMath || MI.getFlag(MachineInstr::MIFlag::FmReassoc)))
5104 return false;
5105
5106 // Floating-point multiply-add with intermediate rounding.
5107 HasFMAD = (!isPreLegalize() && TLI.isFMADLegal(MI, DstType));
5108 // Floating-point multiply-add without intermediate rounding.
5109 bool HasFMA = TLI.isFMAFasterThanFMulAndFAdd(*MF, DstType) &&
5110 isLegalOrBeforeLegalizer({TargetOpcode::G_FMA, {DstType}});
5111 // No valid opcode, do not combine.
5112 if (!HasFMAD && !HasFMA)
5113 return false;
5114
5115 AllowFusionGlobally = Options.AllowFPOpFusion == FPOpFusion::Fast ||
5116 Options.UnsafeFPMath || HasFMAD;
5117 // If the addition is not contractable, do not combine.
5118 if (!AllowFusionGlobally && !MI.getFlag(MachineInstr::MIFlag::FmContract))
5119 return false;
5120
5121 Aggressive = TLI.enableAggressiveFMAFusion(DstType);
5122 return true;
5123}
5124
5125bool CombinerHelper::matchCombineFAddFMulToFMadOrFMA(
5126 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
5127 assert(MI.getOpcode() == TargetOpcode::G_FADD)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_FADD
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_FADD"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5127, __extension__
__PRETTY_FUNCTION__))
;
5128
5129 bool AllowFusionGlobally, HasFMAD, Aggressive;
5130 if (!canCombineFMadOrFMA(MI, AllowFusionGlobally, HasFMAD, Aggressive))
5131 return false;
5132
5133 Register Op1 = MI.getOperand(1).getReg();
5134 Register Op2 = MI.getOperand(2).getReg();
5135 DefinitionAndSourceRegister LHS = {MRI.getVRegDef(Op1), Op1};
5136 DefinitionAndSourceRegister RHS = {MRI.getVRegDef(Op2), Op2};
5137 unsigned PreferredFusedOpcode =
5138 HasFMAD ? TargetOpcode::G_FMAD : TargetOpcode::G_FMA;
5139
5140 // If we have two choices trying to fold (fadd (fmul u, v), (fmul x, y)),
5141 // prefer to fold the multiply with fewer uses.
5142 if (Aggressive && isContractableFMul(*LHS.MI, AllowFusionGlobally) &&
5143 isContractableFMul(*RHS.MI, AllowFusionGlobally)) {
5144 if (hasMoreUses(*LHS.MI, *RHS.MI, MRI))
5145 std::swap(LHS, RHS);
5146 }
5147
5148 // fold (fadd (fmul x, y), z) -> (fma x, y, z)
5149 if (isContractableFMul(*LHS.MI, AllowFusionGlobally) &&
5150 (Aggressive || MRI.hasOneNonDBGUse(LHS.Reg))) {
5151 MatchInfo = [=, &MI](MachineIRBuilder &B) {
5152 B.buildInstr(PreferredFusedOpcode, {MI.getOperand(0).getReg()},
5153 {LHS.MI->getOperand(1).getReg(),
5154 LHS.MI->getOperand(2).getReg(), RHS.Reg});
5155 };
5156 return true;
5157 }
5158
5159 // fold (fadd x, (fmul y, z)) -> (fma y, z, x)
5160 if (isContractableFMul(*RHS.MI, AllowFusionGlobally) &&
5161 (Aggressive || MRI.hasOneNonDBGUse(RHS.Reg))) {
5162 MatchInfo = [=, &MI](MachineIRBuilder &B) {
5163 B.buildInstr(PreferredFusedOpcode, {MI.getOperand(0).getReg()},
5164 {RHS.MI->getOperand(1).getReg(),
5165 RHS.MI->getOperand(2).getReg(), LHS.Reg});
5166 };
5167 return true;
5168 }
5169
5170 return false;
5171}
5172
5173bool CombinerHelper::matchCombineFAddFpExtFMulToFMadOrFMA(
5174 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
5175 assert(MI.getOpcode() == TargetOpcode::G_FADD)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_FADD
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_FADD"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5175, __extension__
__PRETTY_FUNCTION__))
;
5176
5177 bool AllowFusionGlobally, HasFMAD, Aggressive;
5178 if (!canCombineFMadOrFMA(MI, AllowFusionGlobally, HasFMAD, Aggressive))
5179 return false;
5180
5181 const auto &TLI = *MI.getMF()->getSubtarget().getTargetLowering();
5182 Register Op1 = MI.getOperand(1).getReg();
5183 Register Op2 = MI.getOperand(2).getReg();
5184 DefinitionAndSourceRegister LHS = {MRI.getVRegDef(Op1), Op1};
5185 DefinitionAndSourceRegister RHS = {MRI.getVRegDef(Op2), Op2};
5186 LLT DstType = MRI.getType(MI.getOperand(0).getReg());
5187
5188 unsigned PreferredFusedOpcode =
5189 HasFMAD ? TargetOpcode::G_FMAD : TargetOpcode::G_FMA;
5190
5191 // If we have two choices trying to fold (fadd (fmul u, v), (fmul x, y)),
5192 // prefer to fold the multiply with fewer uses.
5193 if (Aggressive && isContractableFMul(*LHS.MI, AllowFusionGlobally) &&
5194 isContractableFMul(*RHS.MI, AllowFusionGlobally)) {
5195 if (hasMoreUses(*LHS.MI, *RHS.MI, MRI))
5196 std::swap(LHS, RHS);
5197 }
5198
5199 // fold (fadd (fpext (fmul x, y)), z) -> (fma (fpext x), (fpext y), z)
5200 MachineInstr *FpExtSrc;
5201 if (mi_match(LHS.Reg, MRI, m_GFPExt(m_MInstr(FpExtSrc))) &&
5202 isContractableFMul(*FpExtSrc, AllowFusionGlobally) &&
5203 TLI.isFPExtFoldable(MI, PreferredFusedOpcode, DstType,
5204 MRI.getType(FpExtSrc->getOperand(1).getReg()))) {
5205 MatchInfo = [=, &MI](MachineIRBuilder &B) {
5206 auto FpExtX = B.buildFPExt(DstType, FpExtSrc->getOperand(1).getReg());
5207 auto FpExtY = B.buildFPExt(DstType, FpExtSrc->getOperand(2).getReg());
5208 B.buildInstr(PreferredFusedOpcode, {MI.getOperand(0).getReg()},
5209 {FpExtX.getReg(0), FpExtY.getReg(0), RHS.Reg});
5210 };
5211 return true;
5212 }
5213
5214 // fold (fadd z, (fpext (fmul x, y))) -> (fma (fpext x), (fpext y), z)
5215 // Note: Commutes FADD operands.
5216 if (mi_match(RHS.Reg, MRI, m_GFPExt(m_MInstr(FpExtSrc))) &&
5217 isContractableFMul(*FpExtSrc, AllowFusionGlobally) &&
5218 TLI.isFPExtFoldable(MI, PreferredFusedOpcode, DstType,
5219 MRI.getType(FpExtSrc->getOperand(1).getReg()))) {
5220 MatchInfo = [=, &MI](MachineIRBuilder &B) {
5221 auto FpExtX = B.buildFPExt(DstType, FpExtSrc->getOperand(1).getReg());
5222 auto FpExtY = B.buildFPExt(DstType, FpExtSrc->getOperand(2).getReg());
5223 B.buildInstr(PreferredFusedOpcode, {MI.getOperand(0).getReg()},
5224 {FpExtX.getReg(0), FpExtY.getReg(0), LHS.Reg});
5225 };
5226 return true;
5227 }
5228
5229 return false;
5230}
5231
5232bool CombinerHelper::matchCombineFAddFMAFMulToFMadOrFMA(
5233 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
5234 assert(MI.getOpcode() == TargetOpcode::G_FADD)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_FADD
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_FADD"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5234, __extension__
__PRETTY_FUNCTION__))
;
5235
5236 bool AllowFusionGlobally, HasFMAD, Aggressive;
5237 if (!canCombineFMadOrFMA(MI, AllowFusionGlobally, HasFMAD, Aggressive, true))
5238 return false;
5239
5240 Register Op1 = MI.getOperand(1).getReg();
5241 Register Op2 = MI.getOperand(2).getReg();
5242 DefinitionAndSourceRegister LHS = {MRI.getVRegDef(Op1), Op1};
5243 DefinitionAndSourceRegister RHS = {MRI.getVRegDef(Op2), Op2};
5244 LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
5245
5246 unsigned PreferredFusedOpcode =
5247 HasFMAD ? TargetOpcode::G_FMAD : TargetOpcode::G_FMA;
5248
5249 // If we have two choices trying to fold (fadd (fmul u, v), (fmul x, y)),
5250 // prefer to fold the multiply with fewer uses.
5251 if (Aggressive && isContractableFMul(*LHS.MI, AllowFusionGlobally) &&
5252 isContractableFMul(*RHS.MI, AllowFusionGlobally)) {
5253 if (hasMoreUses(*LHS.MI, *RHS.MI, MRI))
5254 std::swap(LHS, RHS);
5255 }
5256
5257 MachineInstr *FMA = nullptr;
5258 Register Z;
5259 // fold (fadd (fma x, y, (fmul u, v)), z) -> (fma x, y, (fma u, v, z))
5260 if (LHS.MI->getOpcode() == PreferredFusedOpcode &&
5261 (MRI.getVRegDef(LHS.MI->getOperand(3).getReg())->getOpcode() ==
5262 TargetOpcode::G_FMUL) &&
5263 MRI.hasOneNonDBGUse(LHS.MI->getOperand(0).getReg()) &&
5264 MRI.hasOneNonDBGUse(LHS.MI->getOperand(3).getReg())) {
5265 FMA = LHS.MI;
5266 Z = RHS.Reg;
5267 }
5268 // fold (fadd z, (fma x, y, (fmul u, v))) -> (fma x, y, (fma u, v, z))
5269 else if (RHS.MI->getOpcode() == PreferredFusedOpcode &&
5270 (MRI.getVRegDef(RHS.MI->getOperand(3).getReg())->getOpcode() ==
5271 TargetOpcode::G_FMUL) &&
5272 MRI.hasOneNonDBGUse(RHS.MI->getOperand(0).getReg()) &&
5273 MRI.hasOneNonDBGUse(RHS.MI->getOperand(3).getReg())) {
5274 Z = LHS.Reg;
5275 FMA = RHS.MI;
5276 }
5277
5278 if (FMA) {
5279 MachineInstr *FMulMI = MRI.getVRegDef(FMA->getOperand(3).getReg());
5280 Register X = FMA->getOperand(1).getReg();
5281 Register Y = FMA->getOperand(2).getReg();
5282 Register U = FMulMI->getOperand(1).getReg();
5283 Register V = FMulMI->getOperand(2).getReg();
5284
5285 MatchInfo = [=, &MI](MachineIRBuilder &B) {
5286 Register InnerFMA = MRI.createGenericVirtualRegister(DstTy);
5287 B.buildInstr(PreferredFusedOpcode, {InnerFMA}, {U, V, Z});
5288 B.buildInstr(PreferredFusedOpcode, {MI.getOperand(0).getReg()},
5289 {X, Y, InnerFMA});
5290 };
5291 return true;
5292 }
5293
5294 return false;
5295}
5296
5297bool CombinerHelper::matchCombineFAddFpExtFMulToFMadOrFMAAggressive(
5298 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
5299 assert(MI.getOpcode() == TargetOpcode::G_FADD)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_FADD
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_FADD"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5299, __extension__
__PRETTY_FUNCTION__))
;
5300
5301 bool AllowFusionGlobally, HasFMAD, Aggressive;
5302 if (!canCombineFMadOrFMA(MI, AllowFusionGlobally, HasFMAD, Aggressive))
5303 return false;
5304
5305 if (!Aggressive)
5306 return false;
5307
5308 const auto &TLI = *MI.getMF()->getSubtarget().getTargetLowering();
5309 LLT DstType = MRI.getType(MI.getOperand(0).getReg());
5310 Register Op1 = MI.getOperand(1).getReg();
5311 Register Op2 = MI.getOperand(2).getReg();
5312 DefinitionAndSourceRegister LHS = {MRI.getVRegDef(Op1), Op1};
5313 DefinitionAndSourceRegister RHS = {MRI.getVRegDef(Op2), Op2};
5314
5315 unsigned PreferredFusedOpcode =
5316 HasFMAD ? TargetOpcode::G_FMAD : TargetOpcode::G_FMA;
5317
5318 // If we have two choices trying to fold (fadd (fmul u, v), (fmul x, y)),
5319 // prefer to fold the multiply with fewer uses.
5320 if (Aggressive && isContractableFMul(*LHS.MI, AllowFusionGlobally) &&
5321 isContractableFMul(*RHS.MI, AllowFusionGlobally)) {
5322 if (hasMoreUses(*LHS.MI, *RHS.MI, MRI))
5323 std::swap(LHS, RHS);
5324 }
5325
5326 // Builds: (fma x, y, (fma (fpext u), (fpext v), z))
5327 auto buildMatchInfo = [=, &MI](Register U, Register V, Register Z, Register X,
5328 Register Y, MachineIRBuilder &B) {
5329 Register FpExtU = B.buildFPExt(DstType, U).getReg(0);
5330 Register FpExtV = B.buildFPExt(DstType, V).getReg(0);
5331 Register InnerFMA =
5332 B.buildInstr(PreferredFusedOpcode, {DstType}, {FpExtU, FpExtV, Z})
5333 .getReg(0);
5334 B.buildInstr(PreferredFusedOpcode, {MI.getOperand(0).getReg()},
5335 {X, Y, InnerFMA});
5336 };
5337
5338 MachineInstr *FMulMI, *FMAMI;
5339 // fold (fadd (fma x, y, (fpext (fmul u, v))), z)
5340 // -> (fma x, y, (fma (fpext u), (fpext v), z))
5341 if (LHS.MI->getOpcode() == PreferredFusedOpcode &&
5342 mi_match(LHS.MI->getOperand(3).getReg(), MRI,
5343 m_GFPExt(m_MInstr(FMulMI))) &&
5344 isContractableFMul(*FMulMI, AllowFusionGlobally) &&
5345 TLI.isFPExtFoldable(MI, PreferredFusedOpcode, DstType,
5346 MRI.getType(FMulMI->getOperand(0).getReg()))) {
5347 MatchInfo = [=](MachineIRBuilder &B) {
5348 buildMatchInfo(FMulMI->getOperand(1).getReg(),
5349 FMulMI->getOperand(2).getReg(), RHS.Reg,
5350 LHS.MI->getOperand(1).getReg(),
5351 LHS.MI->getOperand(2).getReg(), B);
5352 };
5353 return true;
5354 }
5355
5356 // fold (fadd (fpext (fma x, y, (fmul u, v))), z)
5357 // -> (fma (fpext x), (fpext y), (fma (fpext u), (fpext v), z))
5358 // FIXME: This turns two single-precision and one double-precision
5359 // operation into two double-precision operations, which might not be
5360 // interesting for all targets, especially GPUs.
5361 if (mi_match(LHS.Reg, MRI, m_GFPExt(m_MInstr(FMAMI))) &&
5362 FMAMI->getOpcode() == PreferredFusedOpcode) {
5363 MachineInstr *FMulMI = MRI.getVRegDef(FMAMI->getOperand(3).getReg());
5364 if (isContractableFMul(*FMulMI, AllowFusionGlobally) &&
5365 TLI.isFPExtFoldable(MI, PreferredFusedOpcode, DstType,
5366 MRI.getType(FMAMI->getOperand(0).getReg()))) {
5367 MatchInfo = [=](MachineIRBuilder &B) {
5368 Register X = FMAMI->getOperand(1).getReg();
5369 Register Y = FMAMI->getOperand(2).getReg();
5370 X = B.buildFPExt(DstType, X).getReg(0);
5371 Y = B.buildFPExt(DstType, Y).getReg(0);
5372 buildMatchInfo(FMulMI->getOperand(1).getReg(),
5373 FMulMI->getOperand(2).getReg(), RHS.Reg, X, Y, B);
5374 };
5375
5376 return true;
5377 }
5378 }
5379
5380 // fold (fadd z, (fma x, y, (fpext (fmul u, v)))
5381 // -> (fma x, y, (fma (fpext u), (fpext v), z))
5382 if (RHS.MI->getOpcode() == PreferredFusedOpcode &&
5383 mi_match(RHS.MI->getOperand(3).getReg(), MRI,
5384 m_GFPExt(m_MInstr(FMulMI))) &&
5385 isContractableFMul(*FMulMI, AllowFusionGlobally) &&
5386 TLI.isFPExtFoldable(MI, PreferredFusedOpcode, DstType,
5387 MRI.getType(FMulMI->getOperand(0).getReg()))) {
5388 MatchInfo = [=](MachineIRBuilder &B) {
5389 buildMatchInfo(FMulMI->getOperand(1).getReg(),
5390 FMulMI->getOperand(2).getReg(), LHS.Reg,
5391 RHS.MI->getOperand(1).getReg(),
5392 RHS.MI->getOperand(2).getReg(), B);
5393 };
5394 return true;
5395 }
5396
5397 // fold (fadd z, (fpext (fma x, y, (fmul u, v)))
5398 // -> (fma (fpext x), (fpext y), (fma (fpext u), (fpext v), z))
5399 // FIXME: This turns two single-precision and one double-precision
5400 // operation into two double-precision operations, which might not be
5401 // interesting for all targets, especially GPUs.
5402 if (mi_match(RHS.Reg, MRI, m_GFPExt(m_MInstr(FMAMI))) &&
5403 FMAMI->getOpcode() == PreferredFusedOpcode) {
5404 MachineInstr *FMulMI = MRI.getVRegDef(FMAMI->getOperand(3).getReg());
5405 if (isContractableFMul(*FMulMI, AllowFusionGlobally) &&
5406 TLI.isFPExtFoldable(MI, PreferredFusedOpcode, DstType,
5407 MRI.getType(FMAMI->getOperand(0).getReg()))) {
5408 MatchInfo = [=](MachineIRBuilder &B) {
5409 Register X = FMAMI->getOperand(1).getReg();
5410 Register Y = FMAMI->getOperand(2).getReg();
5411 X = B.buildFPExt(DstType, X).getReg(0);
5412 Y = B.buildFPExt(DstType, Y).getReg(0);
5413 buildMatchInfo(FMulMI->getOperand(1).getReg(),
5414 FMulMI->getOperand(2).getReg(), LHS.Reg, X, Y, B);
5415 };
5416 return true;
5417 }
5418 }
5419
5420 return false;
5421}
5422
5423bool CombinerHelper::matchCombineFSubFMulToFMadOrFMA(
5424 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
5425 assert(MI.getOpcode() == TargetOpcode::G_FSUB)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_FSUB
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_FSUB"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5425, __extension__
__PRETTY_FUNCTION__))
;
5426
5427 bool AllowFusionGlobally, HasFMAD, Aggressive;
5428 if (!canCombineFMadOrFMA(MI, AllowFusionGlobally, HasFMAD, Aggressive))
5429 return false;
5430
5431 Register Op1 = MI.getOperand(1).getReg();
5432 Register Op2 = MI.getOperand(2).getReg();
5433 DefinitionAndSourceRegister LHS = {MRI.getVRegDef(Op1), Op1};
5434 DefinitionAndSourceRegister RHS = {MRI.getVRegDef(Op2), Op2};
5435 LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
5436
5437 // If we have two choices trying to fold (fadd (fmul u, v), (fmul x, y)),
5438 // prefer to fold the multiply with fewer uses.
5439 int FirstMulHasFewerUses = true;
5440 if (isContractableFMul(*LHS.MI, AllowFusionGlobally) &&
5441 isContractableFMul(*RHS.MI, AllowFusionGlobally) &&
5442 hasMoreUses(*LHS.MI, *RHS.MI, MRI))
5443 FirstMulHasFewerUses = false;
5444
5445 unsigned PreferredFusedOpcode =
5446 HasFMAD ? TargetOpcode::G_FMAD : TargetOpcode::G_FMA;
5447
5448 // fold (fsub (fmul x, y), z) -> (fma x, y, -z)
5449 if (FirstMulHasFewerUses &&
5450 (isContractableFMul(*LHS.MI, AllowFusionGlobally) &&
5451 (Aggressive || MRI.hasOneNonDBGUse(LHS.Reg)))) {
5452 MatchInfo = [=, &MI](MachineIRBuilder &B) {
5453 Register NegZ = B.buildFNeg(DstTy, RHS.Reg).getReg(0);
5454 B.buildInstr(PreferredFusedOpcode, {MI.getOperand(0).getReg()},
5455 {LHS.MI->getOperand(1).getReg(),
5456 LHS.MI->getOperand(2).getReg(), NegZ});
5457 };
5458 return true;
5459 }
5460 // fold (fsub x, (fmul y, z)) -> (fma -y, z, x)
5461 else if ((isContractableFMul(*RHS.MI, AllowFusionGlobally) &&
5462 (Aggressive || MRI.hasOneNonDBGUse(RHS.Reg)))) {
5463 MatchInfo = [=, &MI](MachineIRBuilder &B) {
5464 Register NegY =
5465 B.buildFNeg(DstTy, RHS.MI->getOperand(1).getReg()).getReg(0);
5466 B.buildInstr(PreferredFusedOpcode, {MI.getOperand(0).getReg()},
5467 {NegY, RHS.MI->getOperand(2).getReg(), LHS.Reg});
5468 };
5469 return true;
5470 }
5471
5472 return false;
5473}
5474
5475bool CombinerHelper::matchCombineFSubFNegFMulToFMadOrFMA(
5476 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
5477 assert(MI.getOpcode() == TargetOpcode::G_FSUB)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_FSUB
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_FSUB"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5477, __extension__
__PRETTY_FUNCTION__))
;
5478
5479 bool AllowFusionGlobally, HasFMAD, Aggressive;
5480 if (!canCombineFMadOrFMA(MI, AllowFusionGlobally, HasFMAD, Aggressive))
5481 return false;
5482
5483 Register LHSReg = MI.getOperand(1).getReg();
5484 Register RHSReg = MI.getOperand(2).getReg();
5485 LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
5486
5487 unsigned PreferredFusedOpcode =
5488 HasFMAD ? TargetOpcode::G_FMAD : TargetOpcode::G_FMA;
5489
5490 MachineInstr *FMulMI;
5491 // fold (fsub (fneg (fmul x, y)), z) -> (fma (fneg x), y, (fneg z))
5492 if (mi_match(LHSReg, MRI, m_GFNeg(m_MInstr(FMulMI))) &&
5493 (Aggressive || (MRI.hasOneNonDBGUse(LHSReg) &&
5494 MRI.hasOneNonDBGUse(FMulMI->getOperand(0).getReg()))) &&
5495 isContractableFMul(*FMulMI, AllowFusionGlobally)) {
5496 MatchInfo = [=, &MI](MachineIRBuilder &B) {
5497 Register NegX =
5498 B.buildFNeg(DstTy, FMulMI->getOperand(1).getReg()).getReg(0);
5499 Register NegZ = B.buildFNeg(DstTy, RHSReg).getReg(0);
5500 B.buildInstr(PreferredFusedOpcode, {MI.getOperand(0).getReg()},
5501 {NegX, FMulMI->getOperand(2).getReg(), NegZ});
5502 };
5503 return true;
5504 }
5505
5506 // fold (fsub x, (fneg (fmul, y, z))) -> (fma y, z, x)
5507 if (mi_match(RHSReg, MRI, m_GFNeg(m_MInstr(FMulMI))) &&
5508 (Aggressive || (MRI.hasOneNonDBGUse(RHSReg) &&
5509 MRI.hasOneNonDBGUse(FMulMI->getOperand(0).getReg()))) &&
5510 isContractableFMul(*FMulMI, AllowFusionGlobally)) {
5511 MatchInfo = [=, &MI](MachineIRBuilder &B) {
5512 B.buildInstr(PreferredFusedOpcode, {MI.getOperand(0).getReg()},
5513 {FMulMI->getOperand(1).getReg(),
5514 FMulMI->getOperand(2).getReg(), LHSReg});
5515 };
5516 return true;
5517 }
5518
5519 return false;
5520}
5521
5522bool CombinerHelper::matchCombineFSubFpExtFMulToFMadOrFMA(
5523 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
5524 assert(MI.getOpcode() == TargetOpcode::G_FSUB)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_FSUB
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_FSUB"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5524, __extension__
__PRETTY_FUNCTION__))
;
5525
5526 bool AllowFusionGlobally, HasFMAD, Aggressive;
5527 if (!canCombineFMadOrFMA(MI, AllowFusionGlobally, HasFMAD, Aggressive))
5528 return false;
5529
5530 Register LHSReg = MI.getOperand(1).getReg();
5531 Register RHSReg = MI.getOperand(2).getReg();
5532 LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
5533
5534 unsigned PreferredFusedOpcode =
5535 HasFMAD ? TargetOpcode::G_FMAD : TargetOpcode::G_FMA;
5536
5537 MachineInstr *FMulMI;
5538 // fold (fsub (fpext (fmul x, y)), z) -> (fma (fpext x), (fpext y), (fneg z))
5539 if (mi_match(LHSReg, MRI, m_GFPExt(m_MInstr(FMulMI))) &&
5540 isContractableFMul(*FMulMI, AllowFusionGlobally) &&
5541 (Aggressive || MRI.hasOneNonDBGUse(LHSReg))) {
5542 MatchInfo = [=, &MI](MachineIRBuilder &B) {
5543 Register FpExtX =
5544 B.buildFPExt(DstTy, FMulMI->getOperand(1).getReg()).getReg(0);
5545 Register FpExtY =
5546 B.buildFPExt(DstTy, FMulMI->getOperand(2).getReg()).getReg(0);
5547 Register NegZ = B.buildFNeg(DstTy, RHSReg).getReg(0);
5548 B.buildInstr(PreferredFusedOpcode, {MI.getOperand(0).getReg()},
5549 {FpExtX, FpExtY, NegZ});
5550 };
5551 return true;
5552 }
5553
5554 // fold (fsub x, (fpext (fmul y, z))) -> (fma (fneg (fpext y)), (fpext z), x)
5555 if (mi_match(RHSReg, MRI, m_GFPExt(m_MInstr(FMulMI))) &&
5556 isContractableFMul(*FMulMI, AllowFusionGlobally) &&
5557 (Aggressive || MRI.hasOneNonDBGUse(RHSReg))) {
5558 MatchInfo = [=, &MI](MachineIRBuilder &B) {
5559 Register FpExtY =
5560 B.buildFPExt(DstTy, FMulMI->getOperand(1).getReg()).getReg(0);
5561 Register NegY = B.buildFNeg(DstTy, FpExtY).getReg(0);
5562 Register FpExtZ =
5563 B.buildFPExt(DstTy, FMulMI->getOperand(2).getReg()).getReg(0);
5564 B.buildInstr(PreferredFusedOpcode, {MI.getOperand(0).getReg()},
5565 {NegY, FpExtZ, LHSReg});
5566 };
5567 return true;
5568 }
5569
5570 return false;
5571}
5572
5573bool CombinerHelper::matchCombineFSubFpExtFNegFMulToFMadOrFMA(
5574 MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
5575 assert(MI.getOpcode() == TargetOpcode::G_FSUB)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_FSUB
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_FSUB"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5575, __extension__
__PRETTY_FUNCTION__))
;
5576
5577 bool AllowFusionGlobally, HasFMAD, Aggressive;
5578 if (!canCombineFMadOrFMA(MI, AllowFusionGlobally, HasFMAD, Aggressive))
5579 return false;
5580
5581 const auto &TLI = *MI.getMF()->getSubtarget().getTargetLowering();
5582 LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
5583 Register LHSReg = MI.getOperand(1).getReg();
5584 Register RHSReg = MI.getOperand(2).getReg();
5585
5586 unsigned PreferredFusedOpcode =
5587 HasFMAD ? TargetOpcode::G_FMAD : TargetOpcode::G_FMA;
5588
5589 auto buildMatchInfo = [=](Register Dst, Register X, Register Y, Register Z,
5590 MachineIRBuilder &B) {
5591 Register FpExtX = B.buildFPExt(DstTy, X).getReg(0);
5592 Register FpExtY = B.buildFPExt(DstTy, Y).getReg(0);
5593 B.buildInstr(PreferredFusedOpcode, {Dst}, {FpExtX, FpExtY, Z});
5594 };
5595
5596 MachineInstr *FMulMI;
5597 // fold (fsub (fpext (fneg (fmul x, y))), z) ->
5598 // (fneg (fma (fpext x), (fpext y), z))
5599 // fold (fsub (fneg (fpext (fmul x, y))), z) ->
5600 // (fneg (fma (fpext x), (fpext y), z))
5601 if ((mi_match(LHSReg, MRI, m_GFPExt(m_GFNeg(m_MInstr(FMulMI)))) ||
5602 mi_match(LHSReg, MRI, m_GFNeg(m_GFPExt(m_MInstr(FMulMI))))) &&
5603 isContractableFMul(*FMulMI, AllowFusionGlobally) &&
5604 TLI.isFPExtFoldable(MI, PreferredFusedOpcode, DstTy,
5605 MRI.getType(FMulMI->getOperand(0).getReg()))) {
5606 MatchInfo = [=, &MI](MachineIRBuilder &B) {
5607 Register FMAReg = MRI.createGenericVirtualRegister(DstTy);
5608 buildMatchInfo(FMAReg, FMulMI->getOperand(1).getReg(),
5609 FMulMI->getOperand(2).getReg(), RHSReg, B);
5610 B.buildFNeg(MI.getOperand(0).getReg(), FMAReg);
5611 };
5612 return true;
5613 }
5614
5615 // fold (fsub x, (fpext (fneg (fmul y, z)))) -> (fma (fpext y), (fpext z), x)
5616 // fold (fsub x, (fneg (fpext (fmul y, z)))) -> (fma (fpext y), (fpext z), x)
5617 if ((mi_match(RHSReg, MRI, m_GFPExt(m_GFNeg(m_MInstr(FMulMI)))) ||
5618 mi_match(RHSReg, MRI, m_GFNeg(m_GFPExt(m_MInstr(FMulMI))))) &&
5619 isContractableFMul(*FMulMI, AllowFusionGlobally) &&
5620 TLI.isFPExtFoldable(MI, PreferredFusedOpcode, DstTy,
5621 MRI.getType(FMulMI->getOperand(0).getReg()))) {
5622 MatchInfo = [=, &MI](MachineIRBuilder &B) {
5623 buildMatchInfo(MI.getOperand(0).getReg(), FMulMI->getOperand(1).getReg(),
5624 FMulMI->getOperand(2).getReg(), LHSReg, B);
5625 };
5626 return true;
5627 }
5628
5629 return false;
5630}
5631
5632bool CombinerHelper::matchSelectToLogical(MachineInstr &MI,
5633 BuildFnTy &MatchInfo) {
5634 GSelect &Sel = cast<GSelect>(MI);
5635 Register DstReg = Sel.getReg(0);
5636 Register Cond = Sel.getCondReg();
5637 Register TrueReg = Sel.getTrueReg();
5638 Register FalseReg = Sel.getFalseReg();
5639
5640 auto *TrueDef = getDefIgnoringCopies(TrueReg, MRI);
5641 auto *FalseDef = getDefIgnoringCopies(FalseReg, MRI);
5642
5643 const LLT CondTy = MRI.getType(Cond);
5644 const LLT OpTy = MRI.getType(TrueReg);
5645 if (CondTy != OpTy || OpTy.getScalarSizeInBits() != 1)
5646 return false;
5647
5648 // We have a boolean select.
5649
5650 // select Cond, Cond, F --> or Cond, F
5651 // select Cond, 1, F --> or Cond, F
5652 auto MaybeCstTrue = isConstantOrConstantSplatVector(*TrueDef, MRI);
5653 if (Cond == TrueReg || (MaybeCstTrue && MaybeCstTrue->isOne())) {
5654 MatchInfo = [=](MachineIRBuilder &MIB) {
5655 MIB.buildOr(DstReg, Cond, FalseReg);
5656 };
5657 return true;
5658 }
5659
5660 // select Cond, T, Cond --> and Cond, T
5661 // select Cond, T, 0 --> and Cond, T
5662 auto MaybeCstFalse = isConstantOrConstantSplatVector(*FalseDef, MRI);
5663 if (Cond == FalseReg || (MaybeCstFalse && MaybeCstFalse->isZero())) {
5664 MatchInfo = [=](MachineIRBuilder &MIB) {
5665 MIB.buildAnd(DstReg, Cond, TrueReg);
5666 };
5667 return true;
5668 }
5669
5670 // select Cond, T, 1 --> or (not Cond), T
5671 if (MaybeCstFalse && MaybeCstFalse->isOne()) {
5672 MatchInfo = [=](MachineIRBuilder &MIB) {
5673 MIB.buildOr(DstReg, MIB.buildNot(OpTy, Cond), TrueReg);
5674 };
5675 return true;
5676 }
5677
5678 // select Cond, 0, F --> and (not Cond), F
5679 if (MaybeCstTrue && MaybeCstTrue->isZero()) {
5680 MatchInfo = [=](MachineIRBuilder &MIB) {
5681 MIB.buildAnd(DstReg, MIB.buildNot(OpTy, Cond), FalseReg);
5682 };
5683 return true;
5684 }
5685 return false;
5686}
5687
5688bool CombinerHelper::matchCombineFMinMaxNaN(MachineInstr &MI,
5689 unsigned &IdxToPropagate) {
5690 bool PropagateNaN;
5691 switch (MI.getOpcode()) {
5692 default:
5693 return false;
5694 case TargetOpcode::G_FMINNUM:
5695 case TargetOpcode::G_FMAXNUM:
5696 PropagateNaN = false;
5697 break;
5698 case TargetOpcode::G_FMINIMUM:
5699 case TargetOpcode::G_FMAXIMUM:
5700 PropagateNaN = true;
5701 break;
5702 }
5703
5704 auto MatchNaN = [&](unsigned Idx) {
5705 Register MaybeNaNReg = MI.getOperand(Idx).getReg();
5706 const ConstantFP *MaybeCst = getConstantFPVRegVal(MaybeNaNReg, MRI);
5707 if (!MaybeCst || !MaybeCst->getValueAPF().isNaN())
5708 return false;
5709 IdxToPropagate = PropagateNaN ? Idx : (Idx == 1 ? 2 : 1);
5710 return true;
5711 };
5712
5713 return MatchNaN(1) || MatchNaN(2);
5714}
5715
5716bool CombinerHelper::matchAddSubSameReg(MachineInstr &MI, Register &Src) {
5717 assert(MI.getOpcode() == TargetOpcode::G_ADD && "Expected a G_ADD")(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_ADD
&& "Expected a G_ADD") ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_ADD && \"Expected a G_ADD\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5717, __extension__
__PRETTY_FUNCTION__))
;
5718 Register LHS = MI.getOperand(1).getReg();
5719 Register RHS = MI.getOperand(2).getReg();
5720
5721 // Helper lambda to check for opportunities for
5722 // A + (B - A) -> B
5723 // (B - A) + A -> B
5724 auto CheckFold = [&](Register MaybeSub, Register MaybeSameReg) {
5725 Register Reg;
5726 return mi_match(MaybeSub, MRI, m_GSub(m_Reg(Src), m_Reg(Reg))) &&
5727 Reg == MaybeSameReg;
5728 };
5729 return CheckFold(LHS, RHS) || CheckFold(RHS, LHS);
5730}
5731
5732bool CombinerHelper::matchBuildVectorIdentityFold(MachineInstr &MI,
5733 Register &MatchInfo) {
5734 // This combine folds the following patterns:
5735 //
5736 // G_BUILD_VECTOR_TRUNC (G_BITCAST(x), G_LSHR(G_BITCAST(x), k))
5737 // G_BUILD_VECTOR(G_TRUNC(G_BITCAST(x)), G_TRUNC(G_LSHR(G_BITCAST(x), k)))
5738 // into
5739 // x
5740 // if
5741 // k == sizeof(VecEltTy)/2
5742 // type(x) == type(dst)
5743 //
5744 // G_BUILD_VECTOR(G_TRUNC(G_BITCAST(x)), undef)
5745 // into
5746 // x
5747 // if
5748 // type(x) == type(dst)
5749
5750 LLT DstVecTy = MRI.getType(MI.getOperand(0).getReg());
5751 LLT DstEltTy = DstVecTy.getElementType();
5752
5753 Register Lo, Hi;
5754
5755 if (mi_match(
1
Taking false branch
5756 MI, MRI,
5757 m_GBuildVector(m_GTrunc(m_GBitcast(m_Reg(Lo))), m_GImplicitDef()))) {
5758 MatchInfo = Lo;
5759 return MRI.getType(MatchInfo) == DstVecTy;
5760 }
5761
5762 std::optional<ValueAndVReg> ShiftAmount;
5763 const auto LoPattern = m_GBitcast(m_Reg(Lo));
5764 const auto HiPattern = m_GLShr(m_GBitcast(m_Reg(Hi)), m_GCst(ShiftAmount));
5765 if (mi_match(
2
Taking false branch
5766 MI, MRI,
5767 m_any_of(m_GBuildVectorTrunc(LoPattern, HiPattern),
5768 m_GBuildVector(m_GTrunc(LoPattern), m_GTrunc(HiPattern))))) {
5769 if (Lo == Hi && ShiftAmount->Value == DstEltTy.getSizeInBits()) {
5770 MatchInfo = Lo;
5771 return MRI.getType(MatchInfo) == DstVecTy;
5772 }
5773 }
5774
5775 return false;
3
Calling implicit destructor for 'optional<llvm::ValueAndVReg>'
4
Calling implicit destructor for '_Optional_base<llvm::ValueAndVReg, false, false>'
5
Calling '~_Optional_payload'
5776}
5777
5778bool CombinerHelper::matchTruncBuildVectorFold(MachineInstr &MI,
5779 Register &MatchInfo) {
5780 // Replace (G_TRUNC (G_BITCAST (G_BUILD_VECTOR x, y)) with just x
5781 // if type(x) == type(G_TRUNC)
5782 if (!mi_match(MI.getOperand(1).getReg(), MRI,
5783 m_GBitcast(m_GBuildVector(m_Reg(MatchInfo), m_Reg()))))
5784 return false;
5785
5786 return MRI.getType(MatchInfo) == MRI.getType(MI.getOperand(0).getReg());
5787}
5788
5789bool CombinerHelper::matchTruncLshrBuildVectorFold(MachineInstr &MI,
5790 Register &MatchInfo) {
5791 // Replace (G_TRUNC (G_LSHR (G_BITCAST (G_BUILD_VECTOR x, y)), K)) with
5792 // y if K == size of vector element type
5793 std::optional<ValueAndVReg> ShiftAmt;
5794 if (!mi_match(MI.getOperand(1).getReg(), MRI,
5795 m_GLShr(m_GBitcast(m_GBuildVector(m_Reg(), m_Reg(MatchInfo))),
5796 m_GCst(ShiftAmt))))
5797 return false;
5798
5799 LLT MatchTy = MRI.getType(MatchInfo);
5800 return ShiftAmt->Value.getZExtValue() == MatchTy.getSizeInBits() &&
5801 MatchTy == MRI.getType(MI.getOperand(0).getReg());
5802}
5803
5804unsigned CombinerHelper::getFPMinMaxOpcForSelect(
5805 CmpInst::Predicate Pred, LLT DstTy,
5806 SelectPatternNaNBehaviour VsNaNRetVal) const {
5807 assert(VsNaNRetVal != SelectPatternNaNBehaviour::NOT_APPLICABLE &&(static_cast <bool> (VsNaNRetVal != SelectPatternNaNBehaviour
::NOT_APPLICABLE && "Expected a NaN behaviour?") ? void
(0) : __assert_fail ("VsNaNRetVal != SelectPatternNaNBehaviour::NOT_APPLICABLE && \"Expected a NaN behaviour?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5808, __extension__
__PRETTY_FUNCTION__))
5808 "Expected a NaN behaviour?")(static_cast <bool> (VsNaNRetVal != SelectPatternNaNBehaviour
::NOT_APPLICABLE && "Expected a NaN behaviour?") ? void
(0) : __assert_fail ("VsNaNRetVal != SelectPatternNaNBehaviour::NOT_APPLICABLE && \"Expected a NaN behaviour?\""
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5808, __extension__
__PRETTY_FUNCTION__))
;
5809 // Choose an opcode based off of legality or the behaviour when one of the
5810 // LHS/RHS may be NaN.
5811 switch (Pred) {
5812 default:
5813 return 0;
5814 case CmpInst::FCMP_UGT:
5815 case CmpInst::FCMP_UGE:
5816 case CmpInst::FCMP_OGT:
5817 case CmpInst::FCMP_OGE:
5818 if (VsNaNRetVal == SelectPatternNaNBehaviour::RETURNS_OTHER)
5819 return TargetOpcode::G_FMAXNUM;
5820 if (VsNaNRetVal == SelectPatternNaNBehaviour::RETURNS_NAN)
5821 return TargetOpcode::G_FMAXIMUM;
5822 if (isLegal({TargetOpcode::G_FMAXNUM, {DstTy}}))
5823 return TargetOpcode::G_FMAXNUM;
5824 if (isLegal({TargetOpcode::G_FMAXIMUM, {DstTy}}))
5825 return TargetOpcode::G_FMAXIMUM;
5826 return 0;
5827 case CmpInst::FCMP_ULT:
5828 case CmpInst::FCMP_ULE:
5829 case CmpInst::FCMP_OLT:
5830 case CmpInst::FCMP_OLE:
5831 if (VsNaNRetVal == SelectPatternNaNBehaviour::RETURNS_OTHER)
5832 return TargetOpcode::G_FMINNUM;
5833 if (VsNaNRetVal == SelectPatternNaNBehaviour::RETURNS_NAN)
5834 return TargetOpcode::G_FMINIMUM;
5835 if (isLegal({TargetOpcode::G_FMINNUM, {DstTy}}))
5836 return TargetOpcode::G_FMINNUM;
5837 if (!isLegal({TargetOpcode::G_FMINIMUM, {DstTy}}))
5838 return 0;
5839 return TargetOpcode::G_FMINIMUM;
5840 }
5841}
5842
5843CombinerHelper::SelectPatternNaNBehaviour
5844CombinerHelper::computeRetValAgainstNaN(Register LHS, Register RHS,
5845 bool IsOrderedComparison) const {
5846 bool LHSSafe = isKnownNeverNaN(LHS, MRI);
5847 bool RHSSafe = isKnownNeverNaN(RHS, MRI);
5848 // Completely unsafe.
5849 if (!LHSSafe && !RHSSafe)
5850 return SelectPatternNaNBehaviour::NOT_APPLICABLE;
5851 if (LHSSafe && RHSSafe)
5852 return SelectPatternNaNBehaviour::RETURNS_ANY;
5853 // An ordered comparison will return false when given a NaN, so it
5854 // returns the RHS.
5855 if (IsOrderedComparison)
5856 return LHSSafe ? SelectPatternNaNBehaviour::RETURNS_NAN
5857 : SelectPatternNaNBehaviour::RETURNS_OTHER;
5858 // An unordered comparison will return true when given a NaN, so it
5859 // returns the LHS.
5860 return LHSSafe ? SelectPatternNaNBehaviour::RETURNS_OTHER
5861 : SelectPatternNaNBehaviour::RETURNS_NAN;
5862}
5863
5864bool CombinerHelper::matchFPSelectToMinMax(Register Dst, Register Cond,
5865 Register TrueVal, Register FalseVal,
5866 BuildFnTy &MatchInfo) {
5867 // Match: select (fcmp cond x, y) x, y
5868 // select (fcmp cond x, y) y, x
5869 // And turn it into fminnum/fmaxnum or fmin/fmax based off of the condition.
5870 LLT DstTy = MRI.getType(Dst);
5871 // Bail out early on pointers, since we'll never want to fold to a min/max.
5872 if (DstTy.isPointer())
5873 return false;
5874 // Match a floating point compare with a less-than/greater-than predicate.
5875 // TODO: Allow multiple users of the compare if they are all selects.
5876 CmpInst::Predicate Pred;
5877 Register CmpLHS, CmpRHS;
5878 if (!mi_match(Cond, MRI,
5879 m_OneNonDBGUse(
5880 m_GFCmp(m_Pred(Pred), m_Reg(CmpLHS), m_Reg(CmpRHS)))) ||
5881 CmpInst::isEquality(Pred))
5882 return false;
5883 SelectPatternNaNBehaviour ResWithKnownNaNInfo =
5884 computeRetValAgainstNaN(CmpLHS, CmpRHS, CmpInst::isOrdered(Pred));
5885 if (ResWithKnownNaNInfo == SelectPatternNaNBehaviour::NOT_APPLICABLE)
5886 return false;
5887 if (TrueVal == CmpRHS && FalseVal == CmpLHS) {
5888 std::swap(CmpLHS, CmpRHS);
5889 Pred = CmpInst::getSwappedPredicate(Pred);
5890 if (ResWithKnownNaNInfo == SelectPatternNaNBehaviour::RETURNS_NAN)
5891 ResWithKnownNaNInfo = SelectPatternNaNBehaviour::RETURNS_OTHER;
5892 else if (ResWithKnownNaNInfo == SelectPatternNaNBehaviour::RETURNS_OTHER)
5893 ResWithKnownNaNInfo = SelectPatternNaNBehaviour::RETURNS_NAN;
5894 }
5895 if (TrueVal != CmpLHS || FalseVal != CmpRHS)
5896 return false;
5897 // Decide what type of max/min this should be based off of the predicate.
5898 unsigned Opc = getFPMinMaxOpcForSelect(Pred, DstTy, ResWithKnownNaNInfo);
5899 if (!Opc || !isLegal({Opc, {DstTy}}))
5900 return false;
5901 // Comparisons between signed zero and zero may have different results...
5902 // unless we have fmaximum/fminimum. In that case, we know -0 < 0.
5903 if (Opc != TargetOpcode::G_FMAXIMUM && Opc != TargetOpcode::G_FMINIMUM) {
5904 // We don't know if a comparison between two 0s will give us a consistent
5905 // result. Be conservative and only proceed if at least one side is
5906 // non-zero.
5907 auto KnownNonZeroSide = getFConstantVRegValWithLookThrough(CmpLHS, MRI);
5908 if (!KnownNonZeroSide || !KnownNonZeroSide->Value.isNonZero()) {
5909 KnownNonZeroSide = getFConstantVRegValWithLookThrough(CmpRHS, MRI);
5910 if (!KnownNonZeroSide || !KnownNonZeroSide->Value.isNonZero())
5911 return false;
5912 }
5913 }
5914 MatchInfo = [=](MachineIRBuilder &B) {
5915 B.buildInstr(Opc, {Dst}, {CmpLHS, CmpRHS});
5916 };
5917 return true;
5918}
5919
5920bool CombinerHelper::matchSimplifySelectToMinMax(MachineInstr &MI,
5921 BuildFnTy &MatchInfo) {
5922 // TODO: Handle integer cases.
5923 assert(MI.getOpcode() == TargetOpcode::G_SELECT)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_SELECT
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_SELECT"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5923, __extension__
__PRETTY_FUNCTION__))
;
5924 // Condition may be fed by a truncated compare.
5925 Register Cond = MI.getOperand(1).getReg();
5926 Register MaybeTrunc;
5927 if (mi_match(Cond, MRI, m_OneNonDBGUse(m_GTrunc(m_Reg(MaybeTrunc)))))
5928 Cond = MaybeTrunc;
5929 Register Dst = MI.getOperand(0).getReg();
5930 Register TrueVal = MI.getOperand(2).getReg();
5931 Register FalseVal = MI.getOperand(3).getReg();
5932 return matchFPSelectToMinMax(Dst, Cond, TrueVal, FalseVal, MatchInfo);
5933}
5934
5935bool CombinerHelper::matchRedundantBinOpInEquality(MachineInstr &MI,
5936 BuildFnTy &MatchInfo) {
5937 assert(MI.getOpcode() == TargetOpcode::G_ICMP)(static_cast <bool> (MI.getOpcode() == TargetOpcode::G_ICMP
) ? void (0) : __assert_fail ("MI.getOpcode() == TargetOpcode::G_ICMP"
, "llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp", 5937, __extension__
__PRETTY_FUNCTION__))
;
5938 // (X + Y) == X --> Y == 0
5939 // (X + Y) != X --> Y != 0
5940 // (X - Y) == X --> Y == 0
5941 // (X - Y) != X --> Y != 0
5942 // (X ^ Y) == X --> Y == 0
5943 // (X ^ Y) != X --> Y != 0
5944 Register Dst = MI.getOperand(0).getReg();
5945 CmpInst::Predicate Pred;
5946 Register X, Y, OpLHS, OpRHS;
5947 bool MatchedSub = mi_match(
5948 Dst, MRI,
5949 m_c_GICmp(m_Pred(Pred), m_Reg(X), m_GSub(m_Reg(OpLHS), m_Reg(Y))));
5950 if (MatchedSub && X != OpLHS)
5951 return false;
5952 if (!MatchedSub) {
5953 if (!mi_match(Dst, MRI,
5954 m_c_GICmp(m_Pred(Pred), m_Reg(X),
5955 m_any_of(m_GAdd(m_Reg(OpLHS), m_Reg(OpRHS)),
5956 m_GXor(m_Reg(OpLHS), m_Reg(OpRHS))))))
5957 return false;
5958 Y = X == OpLHS ? OpRHS : X == OpRHS ? OpLHS : Register();
5959 }
5960 MatchInfo = [=](MachineIRBuilder &B) {
5961 auto Zero = B.buildConstant(MRI.getType(Y), 0);
5962 B.buildICmp(Pred, Dst, Y, Zero);
5963 };
5964 return CmpInst::isEquality(Pred) && Y.isValid();
5965}
5966
5967bool CombinerHelper::matchShiftsTooBig(MachineInstr &MI) {
5968 Register ShiftReg = MI.getOperand(2).getReg();
5969 LLT ResTy = MRI.getType(MI.getOperand(0).getReg());
5970 auto IsShiftTooBig = [&](const Constant *C) {
5971 auto *CI = dyn_cast<ConstantInt>(C);
5972 return CI && CI->uge(ResTy.getScalarSizeInBits());
5973 };
5974 return matchUnaryPredicate(MRI, ShiftReg, IsShiftTooBig);
5975}
5976
5977bool CombinerHelper::tryCombine(MachineInstr &MI) {
5978 if (tryCombineCopy(MI))
5979 return true;
5980 if (tryCombineExtendingLoads(MI))
5981 return true;
5982 if (tryCombineIndexedLoadStore(MI))
5983 return true;
5984 return false;
5985}

/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/optional

1// <optional> -*- C++ -*-
2
3// Copyright (C) 2013-2020 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/optional
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_OPTIONAL1
30#define _GLIBCXX_OPTIONAL1 1
31
32#pragma GCC system_header
33
34#if __cplusplus201703L >= 201703L
35
36#include <utility>
37#include <type_traits>
38#include <exception>
39#include <new>
40#include <initializer_list>
41#include <bits/exception_defines.h>
42#include <bits/functional_hash.h>
43#include <bits/enable_special_members.h>
44#if __cplusplus201703L > 201703L
45# include <compare>
46#endif
47
48namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
49{
50_GLIBCXX_BEGIN_NAMESPACE_VERSION
51
52 /**
53 * @addtogroup utilities
54 * @{
55 */
56
57#define __cpp_lib_optional201606L 201606L
58
59 template<typename _Tp>
60 class optional;
61
62 /// Tag type to disengage optional objects.
63 struct nullopt_t
64 {
65 // Do not user-declare default constructor at all for
66 // optional_value = {} syntax to work.
67 // nullopt_t() = delete;
68
69 // Used for constructing nullopt.
70 enum class _Construct { _Token };
71
72 // Must be constexpr for nullopt_t to be literal.
73 explicit constexpr nullopt_t(_Construct) { }
74 };
75
76 /// Tag to disengage optional objects.
77 inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };
78
79 /**
80 * @brief Exception class thrown when a disengaged optional object is
81 * dereferenced.
82 * @ingroup exceptions
83 */
84 class bad_optional_access : public exception
85 {
86 public:
87 bad_optional_access() { }
88
89 virtual const char* what() const noexcept override
90 { return "bad optional access"; }
91
92 virtual ~bad_optional_access() noexcept = default;
93 };
94
95 void
96 __throw_bad_optional_access()
97 __attribute__((__noreturn__));
98
99 // XXX Does not belong here.
100 inline void
101 __throw_bad_optional_access()
102 { _GLIBCXX_THROW_OR_ABORT(bad_optional_access())(__builtin_abort()); }
103
104 // This class template manages construction/destruction of
105 // the contained value for a std::optional.
106 template <typename _Tp>
107 struct _Optional_payload_base
108 {
109 using _Stored_type = remove_const_t<_Tp>;
110
111 _Optional_payload_base() = default;
112 ~_Optional_payload_base() = default;
20
Calling '~_Storage'
113
114 template<typename... _Args>
115 constexpr
116 _Optional_payload_base(in_place_t __tag, _Args&&... __args)
117 : _M_payload(__tag, std::forward<_Args>(__args)...),
118 _M_engaged(true)
119 { }
120
121 template<typename _Up, typename... _Args>
122 constexpr
123 _Optional_payload_base(std::initializer_list<_Up> __il,
124 _Args&&... __args)
125 : _M_payload(__il, std::forward<_Args>(__args)...),
126 _M_engaged(true)
127 { }
128
129 // Constructor used by _Optional_base copy constructor when the
130 // contained value is not trivially copy constructible.
131 constexpr
132 _Optional_payload_base(bool __engaged,
133 const _Optional_payload_base& __other)
134 {
135 if (__other._M_engaged)
136 this->_M_construct(__other._M_get());
137 }
138
139 // Constructor used by _Optional_base move constructor when the
140 // contained value is not trivially move constructible.
141 constexpr
142 _Optional_payload_base(bool __engaged,
143 _Optional_payload_base&& __other)
144 {
145 if (__other._M_engaged)
146 this->_M_construct(std::move(__other._M_get()));
147 }
148
149 // Copy constructor is only used to when the contained value is
150 // trivially copy constructible.
151 _Optional_payload_base(const _Optional_payload_base&) = default;
152
153 // Move constructor is only used to when the contained value is
154 // trivially copy constructible.
155 _Optional_payload_base(_Optional_payload_base&&) = default;
156
157 _Optional_payload_base&
158 operator=(const _Optional_payload_base&) = default;
159
160 _Optional_payload_base&
161 operator=(_Optional_payload_base&&) = default;
162
163 // used to perform non-trivial copy assignment.
164 constexpr void
165 _M_copy_assign(const _Optional_payload_base& __other)
166 {
167 if (this->_M_engaged && __other._M_engaged)
168 this->_M_get() = __other._M_get();
169 else
170 {
171 if (__other._M_engaged)
172 this->_M_construct(__other._M_get());
173 else
174 this->_M_reset();
175 }
176 }
177
178 // used to perform non-trivial move assignment.
179 constexpr void
180 _M_move_assign(_Optional_payload_base&& __other)
181 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
182 is_nothrow_move_assignable<_Tp>>)
183 {
184 if (this->_M_engaged && __other._M_engaged)
185 this->_M_get() = std::move(__other._M_get());
186 else
187 {
188 if (__other._M_engaged)
189 this->_M_construct(std::move(__other._M_get()));
190 else
191 this->_M_reset();
192 }
193 }
194
195 struct _Empty_byte { };
196
197 template<typename _Up, bool = is_trivially_destructible_v<_Up>>
198 union _Storage
199 {
200 constexpr _Storage() noexcept : _M_empty() { }
201
202 template<typename... _Args>
203 constexpr
204 _Storage(in_place_t, _Args&&... __args)
205 : _M_value(std::forward<_Args>(__args)...)
206 { }
207
208 template<typename _Vp, typename... _Args>
209 constexpr
210 _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
211 : _M_value(__il, std::forward<_Args>(__args)...)
212 { }
213
214 _Empty_byte _M_empty;
215 _Up _M_value;
216 };
217
218 template<typename _Up>
219 union _Storage<_Up, false>
220 {
221 constexpr _Storage() noexcept : _M_empty() { }
222
223 template<typename... _Args>
224 constexpr
225 _Storage(in_place_t, _Args&&... __args)
226 : _M_value(std::forward<_Args>(__args)...)
227 { }
228
229 template<typename _Vp, typename... _Args>
230 constexpr
231 _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
232 : _M_value(__il, std::forward<_Args>(__args)...)
233 { }
234
235 // User-provided destructor is needed when _Up has non-trivial dtor.
236 ~_Storage() { }
21
Calling implicit destructor for 'ValueAndVReg'
22
Calling '~APInt'
237
238 _Empty_byte _M_empty;
239 _Up _M_value;
240 };
241
242 _Storage<_Stored_type> _M_payload;
243
244 bool _M_engaged = false;
245
246 template<typename... _Args>
247 void
248 _M_construct(_Args&&... __args)
249 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
250 {
251 ::new ((void *) std::__addressof(this->_M_payload))
252 _Stored_type(std::forward<_Args>(__args)...);
253 this->_M_engaged = true;
254 }
255
256 constexpr void
257 _M_destroy() noexcept
258 {
259 _M_engaged = false;
260 _M_payload._M_value.~_Stored_type();
10
Calling implicit destructor for 'ValueAndVReg'
11
Calling '~APInt'
14
Returning from '~APInt'
15
Returning; memory was released
261 }
262
263 // The _M_get() operations have _M_engaged as a precondition.
264 // They exist to access the contained value with the appropriate
265 // const-qualification, because _M_payload has had the const removed.
266
267 constexpr _Tp&
268 _M_get() noexcept
269 { return this->_M_payload._M_value; }
270
271 constexpr const _Tp&
272 _M_get() const noexcept
273 { return this->_M_payload._M_value; }
274
275 // _M_reset is a 'safe' operation with no precondition.
276 constexpr void
277 _M_reset() noexcept
278 {
279 if (this->_M_engaged)
7
Assuming field '_M_engaged' is true
8
Taking true branch
280 _M_destroy();
9
Calling '_Optional_payload_base::_M_destroy'
16
Returning; memory was released
281 }
282 };
283
284 // Class template that manages the payload for optionals.
285 template <typename _Tp,
286 bool /*_HasTrivialDestructor*/ =
287 is_trivially_destructible_v<_Tp>,
288 bool /*_HasTrivialCopy */ =
289 is_trivially_copy_assignable_v<_Tp>
290 && is_trivially_copy_constructible_v<_Tp>,
291 bool /*_HasTrivialMove */ =
292 is_trivially_move_assignable_v<_Tp>
293 && is_trivially_move_constructible_v<_Tp>>
294 struct _Optional_payload;
295
296 // Payload for potentially-constexpr optionals (trivial copy/move/destroy).
297 template <typename _Tp>
298 struct _Optional_payload<_Tp, true, true, true>
299 : _Optional_payload_base<_Tp>
300 {
301 using _Optional_payload_base<_Tp>::_Optional_payload_base;
302
303 _Optional_payload() = default;
304 };
305
306 // Payload for optionals with non-trivial copy construction/assignment.
307 template <typename _Tp>
308 struct _Optional_payload<_Tp, true, false, true>
309 : _Optional_payload_base<_Tp>
310 {
311 using _Optional_payload_base<_Tp>::_Optional_payload_base;
312
313 _Optional_payload() = default;
314 ~_Optional_payload() = default;
315 _Optional_payload(const _Optional_payload&) = default;
316 _Optional_payload(_Optional_payload&&) = default;
317 _Optional_payload& operator=(_Optional_payload&&) = default;
318
319 // Non-trivial copy assignment.
320 constexpr
321 _Optional_payload&
322 operator=(const _Optional_payload& __other)
323 {
324 this->_M_copy_assign(__other);
325 return *this;
326 }
327 };
328
329 // Payload for optionals with non-trivial move construction/assignment.
330 template <typename _Tp>
331 struct _Optional_payload<_Tp, true, true, false>
332 : _Optional_payload_base<_Tp>
333 {
334 using _Optional_payload_base<_Tp>::_Optional_payload_base;
335
336 _Optional_payload() = default;
337 ~_Optional_payload() = default;
338 _Optional_payload(const _Optional_payload&) = default;
339 _Optional_payload(_Optional_payload&&) = default;
340 _Optional_payload& operator=(const _Optional_payload&) = default;
341
342 // Non-trivial move assignment.
343 constexpr
344 _Optional_payload&
345 operator=(_Optional_payload&& __other)
346 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
347 is_nothrow_move_assignable<_Tp>>)
348 {
349 this->_M_move_assign(std::move(__other));
350 return *this;
351 }
352 };
353
354 // Payload for optionals with non-trivial copy and move assignment.
355 template <typename _Tp>
356 struct _Optional_payload<_Tp, true, false, false>
357 : _Optional_payload_base<_Tp>
358 {
359 using _Optional_payload_base<_Tp>::_Optional_payload_base;
360
361 _Optional_payload() = default;
362 ~_Optional_payload() = default;
19
Calling defaulted destructor for '_Optional_payload_base<llvm::ValueAndVReg>'
363 _Optional_payload(const _Optional_payload&) = default;
364 _Optional_payload(_Optional_payload&&) = default;
365
366 // Non-trivial copy assignment.
367 constexpr
368 _Optional_payload&
369 operator=(const _Optional_payload& __other)
370 {
371 this->_M_copy_assign(__other);
372 return *this;
373 }
374
375 // Non-trivial move assignment.
376 constexpr
377 _Optional_payload&
378 operator=(_Optional_payload&& __other)
379 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
380 is_nothrow_move_assignable<_Tp>>)
381 {
382 this->_M_move_assign(std::move(__other));
383 return *this;
384 }
385 };
386
387 // Payload for optionals with non-trivial destructors.
388 template <typename _Tp, bool _Copy, bool _Move>
389 struct _Optional_payload<_Tp, false, _Copy, _Move>
390 : _Optional_payload<_Tp, true, false, false>
391 {
392 // Base class implements all the constructors and assignment operators:
393 using _Optional_payload<_Tp, true, false, false>::_Optional_payload;
394 _Optional_payload() = default;
395 _Optional_payload(const _Optional_payload&) = default;
396 _Optional_payload(_Optional_payload&&) = default;
397 _Optional_payload& operator=(const _Optional_payload&) = default;
398 _Optional_payload& operator=(_Optional_payload&&) = default;
399
400 // Destructor needs to destroy the contained value:
401 ~_Optional_payload() { this->_M_reset(); }
6
Calling '_Optional_payload_base::_M_reset'
17
Returning; memory was released
18
Calling defaulted destructor for '_Optional_payload<llvm::ValueAndVReg, true, false, false>'
402 };
403
404 // Common base class for _Optional_base<T> to avoid repeating these
405 // member functions in each specialization.
406 template<typename _Tp, typename _Dp>
407 class _Optional_base_impl
408 {
409 protected:
410 using _Stored_type = remove_const_t<_Tp>;
411
412 // The _M_construct operation has !_M_engaged as a precondition
413 // while _M_destruct has _M_engaged as a precondition.
414 template<typename... _Args>
415 void
416 _M_construct(_Args&&... __args)
417 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
418 {
419 ::new
420 (std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload))
421 _Stored_type(std::forward<_Args>(__args)...);
422 static_cast<_Dp*>(this)->_M_payload._M_engaged = true;
423 }
424
425 void
426 _M_destruct() noexcept
427 { static_cast<_Dp*>(this)->_M_payload._M_destroy(); }
428
429 // _M_reset is a 'safe' operation with no precondition.
430 constexpr void
431 _M_reset() noexcept
432 { static_cast<_Dp*>(this)->_M_payload._M_reset(); }
433
434 constexpr bool _M_is_engaged() const noexcept
435 { return static_cast<const _Dp*>(this)->_M_payload._M_engaged; }
436
437 // The _M_get operations have _M_engaged as a precondition.
438 constexpr _Tp&
439 _M_get() noexcept
440 {
441 __glibcxx_assert(this->_M_is_engaged())do { if (! (this->_M_is_engaged())) std::__replacement_assert
("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/optional"
, 441, __PRETTY_FUNCTION__, "this->_M_is_engaged()"); } while
(false)
;
442 return static_cast<_Dp*>(this)->_M_payload._M_get();
443 }
444
445 constexpr const _Tp&
446 _M_get() const noexcept
447 {
448 __glibcxx_assert(this->_M_is_engaged())do { if (! (this->_M_is_engaged())) std::__replacement_assert
("/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/optional"
, 448, __PRETTY_FUNCTION__, "this->_M_is_engaged()"); } while
(false)
;
449 return static_cast<const _Dp*>(this)->_M_payload._M_get();
450 }
451 };
452
453 /**
454 * @brief Class template that provides copy/move constructors of optional.
455 *
456 * Such a separate base class template is necessary in order to
457 * conditionally make copy/move constructors trivial.
458 *
459 * When the contained value is trivially copy/move constructible,
460 * the copy/move constructors of _Optional_base will invoke the
461 * trivial copy/move constructor of _Optional_payload. Otherwise,
462 * they will invoke _Optional_payload(bool, const _Optional_payload&)
463 * or _Optional_payload(bool, _Optional_payload&&) to initialize
464 * the contained value, if copying/moving an engaged optional.
465 *
466 * Whether the other special members are trivial is determined by the
467 * _Optional_payload<_Tp> specialization used for the _M_payload member.
468 *
469 * @see optional, _Enable_special_members
470 */
471 template<typename _Tp,
472 bool = is_trivially_copy_constructible_v<_Tp>,
473 bool = is_trivially_move_constructible_v<_Tp>>
474 struct _Optional_base
475 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
476 {
477 // Constructors for disengaged optionals.
478 constexpr _Optional_base() = default;
479
480 // Constructors for engaged optionals.
481 template<typename... _Args,
482 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
483 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
484 : _M_payload(in_place,
485 std::forward<_Args>(__args)...) { }
486
487 template<typename _Up, typename... _Args,
488 enable_if_t<is_constructible_v<_Tp,
489 initializer_list<_Up>&,
490 _Args&&...>, bool> = false>
491 constexpr explicit _Optional_base(in_place_t,
492 initializer_list<_Up> __il,
493 _Args&&... __args)
494 : _M_payload(in_place,
495 __il, std::forward<_Args>(__args)...)
496 { }
497
498 // Copy and move constructors.
499 constexpr _Optional_base(const _Optional_base& __other)
500 : _M_payload(__other._M_payload._M_engaged,
501 __other._M_payload)
502 { }
503
504 constexpr _Optional_base(_Optional_base&& __other)
505 noexcept(is_nothrow_move_constructible_v<_Tp>)
506 : _M_payload(__other._M_payload._M_engaged,
507 std::move(__other._M_payload))
508 { }
509
510 // Assignment operators.
511 _Optional_base& operator=(const _Optional_base&) = default;
512 _Optional_base& operator=(_Optional_base&&) = default;
513
514 _Optional_payload<_Tp> _M_payload;
515 };
516
517 template<typename _Tp>
518 struct _Optional_base<_Tp, false, true>
519 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
520 {
521 // Constructors for disengaged optionals.
522 constexpr _Optional_base() = default;
523
524 // Constructors for engaged optionals.
525 template<typename... _Args,
526 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
527 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
528 : _M_payload(in_place,
529 std::forward<_Args>(__args)...) { }
530
531 template<typename _Up, typename... _Args,
532 enable_if_t<is_constructible_v<_Tp,
533 initializer_list<_Up>&,
534 _Args&&...>, bool> = false>
535 constexpr explicit _Optional_base(in_place_t,
536 initializer_list<_Up> __il,
537 _Args&&... __args)
538 : _M_payload(in_place,
539 __il, std::forward<_Args>(__args)...)
540 { }
541
542 // Copy and move constructors.
543 constexpr _Optional_base(const _Optional_base& __other)
544 : _M_payload(__other._M_payload._M_engaged,
545 __other._M_payload)
546 { }
547
548 constexpr _Optional_base(_Optional_base&& __other) = default;
549
550 // Assignment operators.
551 _Optional_base& operator=(const _Optional_base&) = default;
552 _Optional_base& operator=(_Optional_base&&) = default;
553
554 _Optional_payload<_Tp> _M_payload;
555 };
556
557 template<typename _Tp>
558 struct _Optional_base<_Tp, true, false>
559 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
560 {
561 // Constructors for disengaged optionals.
562 constexpr _Optional_base() = default;
563
564 // Constructors for engaged optionals.
565 template<typename... _Args,
566 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
567 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
568 : _M_payload(in_place,
569 std::forward<_Args>(__args)...) { }
570
571 template<typename _Up, typename... _Args,
572 enable_if_t<is_constructible_v<_Tp,
573 initializer_list<_Up>&,
574 _Args&&...>, bool> = false>
575 constexpr explicit _Optional_base(in_place_t,
576 initializer_list<_Up> __il,
577 _Args&&... __args)
578 : _M_payload(in_place,
579 __il, std::forward<_Args>(__args)...)
580 { }
581
582 // Copy and move constructors.
583 constexpr _Optional_base(const _Optional_base& __other) = default;
584
585 constexpr _Optional_base(_Optional_base&& __other)
586 noexcept(is_nothrow_move_constructible_v<_Tp>)
587 : _M_payload(__other._M_payload._M_engaged,
588 std::move(__other._M_payload))
589 { }
590
591 // Assignment operators.
592 _Optional_base& operator=(const _Optional_base&) = default;
593 _Optional_base& operator=(_Optional_base&&) = default;
594
595 _Optional_payload<_Tp> _M_payload;
596 };
597
598 template<typename _Tp>
599 struct _Optional_base<_Tp, true, true>
600 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
601 {
602 // Constructors for disengaged optionals.
603 constexpr _Optional_base() = default;
604
605 // Constructors for engaged optionals.
606 template<typename... _Args,
607 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
608 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
609 : _M_payload(in_place,
610 std::forward<_Args>(__args)...) { }
611
612 template<typename _Up, typename... _Args,
613 enable_if_t<is_constructible_v<_Tp,
614 initializer_list<_Up>&,
615 _Args&&...>, bool> = false>
616 constexpr explicit _Optional_base(in_place_t,
617 initializer_list<_Up> __il,
618 _Args&&... __args)
619 : _M_payload(in_place,
620 __il, std::forward<_Args>(__args)...)
621 { }
622
623 // Copy and move constructors.
624 constexpr _Optional_base(const _Optional_base& __other) = default;
625 constexpr _Optional_base(_Optional_base&& __other) = default;
626
627 // Assignment operators.
628 _Optional_base& operator=(const _Optional_base&) = default;
629 _Optional_base& operator=(_Optional_base&&) = default;
630
631 _Optional_payload<_Tp> _M_payload;
632 };
633
634 template<typename _Tp>
635 class optional;
636
637 template<typename _Tp, typename _Up>
638 using __converts_from_optional =
639 __or_<is_constructible<_Tp, const optional<_Up>&>,
640 is_constructible<_Tp, optional<_Up>&>,
641 is_constructible<_Tp, const optional<_Up>&&>,
642 is_constructible<_Tp, optional<_Up>&&>,
643 is_convertible<const optional<_Up>&, _Tp>,
644 is_convertible<optional<_Up>&, _Tp>,
645 is_convertible<const optional<_Up>&&, _Tp>,
646 is_convertible<optional<_Up>&&, _Tp>>;
647
648 template<typename _Tp, typename _Up>
649 using __assigns_from_optional =
650 __or_<is_assignable<_Tp&, const optional<_Up>&>,
651 is_assignable<_Tp&, optional<_Up>&>,
652 is_assignable<_Tp&, const optional<_Up>&&>,
653 is_assignable<_Tp&, optional<_Up>&&>>;
654
655 /**
656 * @brief Class template for optional values.
657 */
658 template<typename _Tp>
659 class optional
660 : private _Optional_base<_Tp>,
661 private _Enable_copy_move<
662 // Copy constructor.
663 is_copy_constructible_v<_Tp>,
664 // Copy assignment.
665 __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
666 // Move constructor.
667 is_move_constructible_v<_Tp>,
668 // Move assignment.
669 __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
670 // Unique tag type.
671 optional<_Tp>>
672 {
673 static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);
674 static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);
675 static_assert(!is_reference_v<_Tp>);
676
677 private:
678 using _Base = _Optional_base<_Tp>;
679
680 // SFINAE helpers
681 template<typename _Up>
682 using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>;
683 template<typename _Up>
684 using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>;
685 template<typename... _Cond>
686 using _Requires = enable_if_t<__and_v<_Cond...>, bool>;
687
688 public:
689 using value_type = _Tp;
690
691 constexpr optional() = default;
692
693 constexpr optional(nullopt_t) noexcept { }
694
695 // Converting constructors for engaged optionals.
696 template<typename _Up = _Tp,
697 _Requires<__not_self<_Up>, __not_tag<_Up>,
698 is_constructible<_Tp, _Up&&>,
699 is_convertible<_Up&&, _Tp>> = true>
700 constexpr
701 optional(_Up&& __t)
702 : _Base(std::in_place, std::forward<_Up>(__t)) { }
703
704 template<typename _Up = _Tp,
705 _Requires<__not_self<_Up>, __not_tag<_Up>,
706 is_constructible<_Tp, _Up&&>,
707 __not_<is_convertible<_Up&&, _Tp>>> = false>
708 explicit constexpr
709 optional(_Up&& __t)
710 : _Base(std::in_place, std::forward<_Up>(__t)) { }
711
712 template<typename _Up,
713 _Requires<__not_<is_same<_Tp, _Up>>,
714 is_constructible<_Tp, const _Up&>,
715 is_convertible<const _Up&, _Tp>,
716 __not_<__converts_from_optional<_Tp, _Up>>> = true>
717 constexpr
718 optional(const optional<_Up>& __t)
719 {
720 if (__t)
721 emplace(*__t);
722 }
723
724 template<typename _Up,
725 _Requires<__not_<is_same<_Tp, _Up>>,
726 is_constructible<_Tp, const _Up&>,
727 __not_<is_convertible<const _Up&, _Tp>>,
728 __not_<__converts_from_optional<_Tp, _Up>>> = false>
729 explicit constexpr
730 optional(const optional<_Up>& __t)
731 {
732 if (__t)
733 emplace(*__t);
734 }
735
736 template <typename _Up,
737 _Requires<__not_<is_same<_Tp, _Up>>,
738 is_constructible<_Tp, _Up&&>,
739 is_convertible<_Up&&, _Tp>,
740 __not_<__converts_from_optional<_Tp, _Up>>> = true>
741 constexpr
742 optional(optional<_Up>&& __t)
743 {
744 if (__t)
745 emplace(std::move(*__t));
746 }
747
748 template <typename _Up,
749 _Requires<__not_<is_same<_Tp, _Up>>,
750 is_constructible<_Tp, _Up&&>,
751 __not_<is_convertible<_Up&&, _Tp>>,
752 __not_<__converts_from_optional<_Tp, _Up>>> = false>
753 explicit constexpr
754 optional(optional<_Up>&& __t)
755 {
756 if (__t)
757 emplace(std::move(*__t));
758 }
759
760 template<typename... _Args,
761 _Requires<is_constructible<_Tp, _Args&&...>> = false>
762 explicit constexpr
763 optional(in_place_t, _Args&&... __args)
764 : _Base(std::in_place, std::forward<_Args>(__args)...) { }
765
766 template<typename _Up, typename... _Args,
767 _Requires<is_constructible<_Tp,
768 initializer_list<_Up>&,
769 _Args&&...>> = false>
770 explicit constexpr
771 optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
772 : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
773
774 // Assignment operators.
775 optional&
776 operator=(nullopt_t) noexcept
777 {
778 this->_M_reset();
779 return *this;
780 }
781
782 template<typename _Up = _Tp>
783 enable_if_t<__and_v<__not_self<_Up>,
784 __not_<__and_<is_scalar<_Tp>,
785 is_same<_Tp, decay_t<_Up>>>>,
786 is_constructible<_Tp, _Up>,
787 is_assignable<_Tp&, _Up>>,
788 optional&>
789 operator=(_Up&& __u)
790 {
791 if (this->_M_is_engaged())
792 this->_M_get() = std::forward<_Up>(__u);
793 else
794 this->_M_construct(std::forward<_Up>(__u));
795
796 return *this;
797 }
798
799 template<typename _Up>
800 enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
801 is_constructible<_Tp, const _Up&>,
802 is_assignable<_Tp&, _Up>,
803 __not_<__converts_from_optional<_Tp, _Up>>,
804 __not_<__assigns_from_optional<_Tp, _Up>>>,
805 optional&>
806 operator=(const optional<_Up>& __u)
807 {
808 if (__u)
809 {
810 if (this->_M_is_engaged())
811 this->_M_get() = *__u;
812 else
813 this->_M_construct(*__u);
814 }
815 else
816 {
817 this->_M_reset();
818 }
819 return *this;
820 }
821
822 template<typename _Up>
823 enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
824 is_constructible<_Tp, _Up>,
825 is_assignable<_Tp&, _Up>,
826 __not_<__converts_from_optional<_Tp, _Up>>,
827 __not_<__assigns_from_optional<_Tp, _Up>>>,
828 optional&>
829 operator=(optional<_Up>&& __u)
830 {
831 if (__u)
832 {
833 if (this->_M_is_engaged())
834 this->_M_get() = std::move(*__u);
835 else
836 this->_M_construct(std::move(*__u));
837 }
838 else
839 {
840 this->_M_reset();
841 }
842
843 return *this;
844 }
845
846 template<typename... _Args>
847 enable_if_t<is_constructible_v<_Tp, _Args&&...>, _Tp&>
848 emplace(_Args&&... __args)
849 {
850 this->_M_reset();
851 this->_M_construct(std::forward<_Args>(__args)...);
852 return this->_M_get();
853 }
854
855 template<typename _Up, typename... _Args>
856 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&,
857 _Args&&...>, _Tp&>
858 emplace(initializer_list<_Up> __il, _Args&&... __args)
859 {
860 this->_M_reset();
861 this->_M_construct(__il, std::forward<_Args>(__args)...);
862 return this->_M_get();
863 }
864
865 // Destructor is implicit, implemented in _Optional_base.
866
867 // Swap.
868 void
869 swap(optional& __other)
870 noexcept(is_nothrow_move_constructible_v<_Tp>
871 && is_nothrow_swappable_v<_Tp>)
872 {
873 using std::swap;
874
875 if (this->_M_is_engaged() && __other._M_is_engaged())
876 swap(this->_M_get(), __other._M_get());
877 else if (this->_M_is_engaged())
878 {
879 __other._M_construct(std::move(this->_M_get()));
880 this->_M_destruct();
881 }
882 else if (__other._M_is_engaged())
883 {
884 this->_M_construct(std::move(__other._M_get()));
885 __other._M_destruct();
886 }
887 }
888
889 // Observers.
890 constexpr const _Tp*
891 operator->() const
892 { return std::__addressof(this->_M_get()); }
893
894 constexpr _Tp*
895 operator->()
896 { return std::__addressof(this->_M_get()); }
897
898 constexpr const _Tp&
899 operator*() const&
900 { return this->_M_get(); }
901
902 constexpr _Tp&
903 operator*()&
904 { return this->_M_get(); }
905
906 constexpr _Tp&&
907 operator*()&&
908 { return std::move(this->_M_get()); }
909
910 constexpr const _Tp&&
911 operator*() const&&
912 { return std::move(this->_M_get()); }
913
914 constexpr explicit operator bool() const noexcept
915 { return this->_M_is_engaged(); }
916
917 constexpr bool has_value() const noexcept
918 { return this->_M_is_engaged(); }
919
920 constexpr const _Tp&
921 value() const&
922 {
923 return this->_M_is_engaged()
924 ? this->_M_get()
925 : (__throw_bad_optional_access(), this->_M_get());
926 }
927
928 constexpr _Tp&
929 value()&
930 {
931 return this->_M_is_engaged()
932 ? this->_M_get()
933 : (__throw_bad_optional_access(), this->_M_get());
934 }
935
936 constexpr _Tp&&
937 value()&&
938 {
939 return this->_M_is_engaged()
940 ? std::move(this->_M_get())
941 : (__throw_bad_optional_access(), std::move(this->_M_get()));
942 }
943
944 constexpr const _Tp&&
945 value() const&&
946 {
947 return this->_M_is_engaged()
948 ? std::move(this->_M_get())
949 : (__throw_bad_optional_access(), std::move(this->_M_get()));
950 }
951
952 template<typename _Up>
953 constexpr _Tp
954 value_or(_Up&& __u) const&
955 {
956 static_assert(is_copy_constructible_v<_Tp>);
957 static_assert(is_convertible_v<_Up&&, _Tp>);
958
959 return this->_M_is_engaged()
960 ? this->_M_get() : static_cast<_Tp>(std::forward<_Up>(__u));
961 }
962
963 template<typename _Up>
964 constexpr _Tp
965 value_or(_Up&& __u) &&
966 {
967 static_assert(is_move_constructible_v<_Tp>);
968 static_assert(is_convertible_v<_Up&&, _Tp>);
969
970 return this->_M_is_engaged()
971 ? std::move(this->_M_get())
972 : static_cast<_Tp>(std::forward<_Up>(__u));
973 }
974
975 void reset() noexcept { this->_M_reset(); }
976 };
977
978 template<typename _Tp>
979 using __optional_relop_t =
980 enable_if_t<is_convertible<_Tp, bool>::value, bool>;
981
982 template<typename _Tp, typename _Up>
983 using __optional_eq_t = __optional_relop_t<
984 decltype(std::declval<const _Tp&>() == std::declval<const _Up&>())
985 >;
986
987 template<typename _Tp, typename _Up>
988 using __optional_ne_t = __optional_relop_t<
989 decltype(std::declval<const _Tp&>() != std::declval<const _Up&>())
990 >;
991
992 template<typename _Tp, typename _Up>
993 using __optional_lt_t = __optional_relop_t<
994 decltype(std::declval<const _Tp&>() < std::declval<const _Up&>())
995 >;
996
997 template<typename _Tp, typename _Up>
998 using __optional_gt_t = __optional_relop_t<
999 decltype(std::declval<const _Tp&>() > std::declval<const _Up&>())
1000 >;
1001
1002 template<typename _Tp, typename _Up>
1003 using __optional_le_t = __optional_relop_t<
1004 decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>())
1005 >;
1006
1007 template<typename _Tp, typename _Up>
1008 using __optional_ge_t = __optional_relop_t<
1009 decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>())
1010 >;
1011
1012 // Comparisons between optional values.
1013 template<typename _Tp, typename _Up>
1014 constexpr auto
1015 operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1016 -> __optional_eq_t<_Tp, _Up>
1017 {
1018 return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
1019 && (!__lhs || *__lhs == *__rhs);
1020 }
1021
1022 template<typename _Tp, typename _Up>
1023 constexpr auto
1024 operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1025 -> __optional_ne_t<_Tp, _Up>
1026 {
1027 return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
1028 || (static_cast<bool>(__lhs) && *__lhs != *__rhs);
1029 }
1030
1031 template<typename _Tp, typename _Up>
1032 constexpr auto
1033 operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1034 -> __optional_lt_t<_Tp, _Up>
1035 {
1036 return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
1037 }
1038
1039 template<typename _Tp, typename _Up>
1040 constexpr auto
1041 operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1042 -> __optional_gt_t<_Tp, _Up>
1043 {
1044 return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
1045 }
1046
1047 template<typename _Tp, typename _Up>
1048 constexpr auto
1049 operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1050 -> __optional_le_t<_Tp, _Up>
1051 {
1052 return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
1053 }
1054
1055 template<typename _Tp, typename _Up>
1056 constexpr auto
1057 operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
1058 -> __optional_ge_t<_Tp, _Up>
1059 {
1060 return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
1061 }
1062
1063#ifdef __cpp_lib_three_way_comparison
1064 template<typename _Tp, three_way_comparable_with<_Tp> _Up>
1065 constexpr compare_three_way_result_t<_Tp, _Up>
1066 operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y)
1067 {
1068 return __x && __y ? *__x <=> *__y : bool(__x) <=> bool(__y);
1069 }
1070#endif
1071
1072 // Comparisons with nullopt.
1073 template<typename _Tp>
1074 constexpr bool
1075 operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
1076 { return !__lhs; }
1077
1078#ifdef __cpp_lib_three_way_comparison
1079 template<typename _Tp>
1080 constexpr strong_ordering
1081 operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept
1082 { return bool(__x) <=> false; }
1083#else
1084 template<typename _Tp>
1085 constexpr bool
1086 operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
1087 { return !__rhs; }
1088
1089 template<typename _Tp>
1090 constexpr bool
1091 operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1092 { return static_cast<bool>(__lhs); }
1093
1094 template<typename _Tp>
1095 constexpr bool
1096 operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1097 { return static_cast<bool>(__rhs); }
1098
1099 template<typename _Tp>
1100 constexpr bool
1101 operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1102 { return false; }
1103
1104 template<typename _Tp>
1105 constexpr bool
1106 operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
1107 { return static_cast<bool>(__rhs); }
1108
1109 template<typename _Tp>
1110 constexpr bool
1111 operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
1112 { return static_cast<bool>(__lhs); }
1113
1114 template<typename _Tp>
1115 constexpr bool
1116 operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1117 { return false; }
1118
1119 template<typename _Tp>
1120 constexpr bool
1121 operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
1122 { return !__lhs; }
1123
1124 template<typename _Tp>
1125 constexpr bool
1126 operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
1127 { return true; }
1128
1129 template<typename _Tp>
1130 constexpr bool
1131 operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
1132 { return true; }
1133
1134 template<typename _Tp>
1135 constexpr bool
1136 operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
1137 { return !__rhs; }
1138#endif // three-way-comparison
1139
1140 // Comparisons with value type.
1141 template<typename _Tp, typename _Up>
1142 constexpr auto
1143 operator==(const optional<_Tp>& __lhs, const _Up& __rhs)
1144 -> __optional_eq_t<_Tp, _Up>
1145 { return __lhs && *__lhs == __rhs; }
1146
1147 template<typename _Tp, typename _Up>
1148 constexpr auto
1149 operator==(const _Up& __lhs, const optional<_Tp>& __rhs)
1150 -> __optional_eq_t<_Up, _Tp>
1151 { return __rhs && __lhs == *__rhs; }
1152
1153 template<typename _Tp, typename _Up>
1154 constexpr auto
1155 operator!=(const optional<_Tp>& __lhs, const _Up& __rhs)
1156 -> __optional_ne_t<_Tp, _Up>
1157 { return !__lhs || *__lhs != __rhs; }
1158
1159 template<typename _Tp, typename _Up>
1160 constexpr auto
1161 operator!=(const _Up& __lhs, const optional<_Tp>& __rhs)
1162 -> __optional_ne_t<_Up, _Tp>
1163 { return !__rhs || __lhs != *__rhs; }
1164
1165 template<typename _Tp, typename _Up>
1166 constexpr auto
1167 operator<(const optional<_Tp>& __lhs, const _Up& __rhs)
1168 -> __optional_lt_t<_Tp, _Up>
1169 { return !__lhs || *__lhs < __rhs; }
1170
1171 template<typename _Tp, typename _Up>
1172 constexpr auto
1173 operator<(const _Up& __lhs, const optional<_Tp>& __rhs)
1174 -> __optional_lt_t<_Up, _Tp>
1175 { return __rhs && __lhs < *__rhs; }
1176
1177 template<typename _Tp, typename _Up>
1178 constexpr auto
1179 operator>(const optional<_Tp>& __lhs, const _Up& __rhs)
1180 -> __optional_gt_t<_Tp, _Up>
1181 { return __lhs && *__lhs > __rhs; }
1182
1183 template<typename _Tp, typename _Up>
1184 constexpr auto
1185 operator>(const _Up& __lhs, const optional<_Tp>& __rhs)
1186 -> __optional_gt_t<_Up, _Tp>
1187 { return !__rhs || __lhs > *__rhs; }
1188
1189 template<typename _Tp, typename _Up>
1190 constexpr auto
1191 operator<=(const optional<_Tp>& __lhs, const _Up& __rhs)
1192 -> __optional_le_t<_Tp, _Up>
1193 { return !__lhs || *__lhs <= __rhs; }
1194
1195 template<typename _Tp, typename _Up>
1196 constexpr auto
1197 operator<=(const _Up& __lhs, const optional<_Tp>& __rhs)
1198 -> __optional_le_t<_Up, _Tp>
1199 { return __rhs && __lhs <= *__rhs; }
1200
1201 template<typename _Tp, typename _Up>
1202 constexpr auto
1203 operator>=(const optional<_Tp>& __lhs, const _Up& __rhs)
1204 -> __optional_ge_t<_Tp, _Up>
1205 { return __lhs && *__lhs >= __rhs; }
1206
1207 template<typename _Tp, typename _Up>
1208 constexpr auto
1209 operator>=(const _Up& __lhs, const optional<_Tp>& __rhs)
1210 -> __optional_ge_t<_Up, _Tp>
1211 { return !__rhs || __lhs >= *__rhs; }
1212
1213#ifdef __cpp_lib_three_way_comparison
1214 template<typename _Tp, typename _Up>
1215 constexpr compare_three_way_result_t<_Tp, _Up>
1216 operator<=>(const optional<_Tp>& __x, const _Up& __v)
1217 { return bool(__x) ? *__x <=> __v : strong_ordering::less; }
1218#endif
1219
1220 // Swap and creation functions.
1221
1222 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1223 // 2748. swappable traits for optionals
1224 template<typename _Tp>
1225 inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
1226 swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
1227 noexcept(noexcept(__lhs.swap(__rhs)))
1228 { __lhs.swap(__rhs); }
1229
1230 template<typename _Tp>
1231 enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
1232 swap(optional<_Tp>&, optional<_Tp>&) = delete;
1233
1234 template<typename _Tp>
1235 constexpr optional<decay_t<_Tp>>
1236 make_optional(_Tp&& __t)
1237 { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
1238
1239 template<typename _Tp, typename ..._Args>
1240 constexpr optional<_Tp>
1241 make_optional(_Args&&... __args)
1242 { return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; }
1243
1244 template<typename _Tp, typename _Up, typename ..._Args>
1245 constexpr optional<_Tp>
1246 make_optional(initializer_list<_Up> __il, _Args&&... __args)
1247 { return optional<_Tp> { in_place, __il, std::forward<_Args>(__args)... }; }
1248
1249 // Hash.
1250
1251 template<typename _Tp, typename _Up = remove_const_t<_Tp>,
1252 bool = __poison_hash<_Up>::__enable_hash_call>
1253 struct __optional_hash_call_base
1254 {
1255 size_t
1256 operator()(const optional<_Tp>& __t) const
1257 noexcept(noexcept(hash<_Up>{}(*__t)))
1258 {
1259 // We pick an arbitrary hash for disengaged optionals which hopefully
1260 // usual values of _Tp won't typically hash to.
1261 constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
1262 return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
1263 }
1264 };
1265
1266 template<typename _Tp, typename _Up>
1267 struct __optional_hash_call_base<_Tp, _Up, false> {};
1268
1269 template<typename _Tp>
1270 struct hash<optional<_Tp>>
1271 : private __poison_hash<remove_const_t<_Tp>>,
1272 public __optional_hash_call_base<_Tp>
1273 {
1274 using result_type [[__deprecated__]] = size_t;
1275 using argument_type [[__deprecated__]] = optional<_Tp>;
1276 };
1277
1278 template<typename _Tp>
1279 struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
1280 { };
1281
1282 /// @}
1283
1284#if __cpp_deduction_guides201703L >= 201606
1285 template <typename _Tp> optional(_Tp) -> optional<_Tp>;
1286#endif
1287
1288_GLIBCXX_END_NAMESPACE_VERSION
1289} // namespace std
1290
1291#endif // C++17
1292
1293#endif // _GLIBCXX_OPTIONAL

/build/source/llvm/include/llvm/CodeGen/GlobalISel/Utils.h

1//==-- llvm/CodeGen/GlobalISel/Utils.h ---------------------------*- C++ -*-==//
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/// \file This file declares the API of helper functions used throughout the
10/// GlobalISel pipeline.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CODEGEN_GLOBALISEL_UTILS_H
15#define LLVM_CODEGEN_GLOBALISEL_UTILS_H
16
17#include "GISelWorkList.h"
18#include "llvm/ADT/APFloat.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/CodeGen/LowLevelType.h"
21#include "llvm/CodeGen/Register.h"
22#include "llvm/IR/DebugLoc.h"
23#include "llvm/Support/Alignment.h"
24#include "llvm/Support/Casting.h"
25#include <cstdint>
26
27namespace llvm {
28
29class AnalysisUsage;
30class LostDebugLocObserver;
31class MachineBasicBlock;
32class BlockFrequencyInfo;
33class GISelKnownBits;
34class MachineFunction;
35class MachineInstr;
36class MachineOperand;
37class MachineOptimizationRemarkEmitter;
38class MachineOptimizationRemarkMissed;
39struct MachinePointerInfo;
40class MachineRegisterInfo;
41class MCInstrDesc;
42class ProfileSummaryInfo;
43class RegisterBankInfo;
44class TargetInstrInfo;
45class TargetLowering;
46class TargetPassConfig;
47class TargetRegisterInfo;
48class TargetRegisterClass;
49class ConstantFP;
50class APFloat;
51
52// Convenience macros for dealing with vector reduction opcodes.
53#define GISEL_VECREDUCE_CASES_ALLcase TargetOpcode::G_VECREDUCE_SEQ_FADD: case TargetOpcode::G_VECREDUCE_SEQ_FMUL
: case TargetOpcode::G_VECREDUCE_FADD: case TargetOpcode::G_VECREDUCE_FMUL
: case TargetOpcode::G_VECREDUCE_FMAX: case TargetOpcode::G_VECREDUCE_FMIN
: case TargetOpcode::G_VECREDUCE_ADD: case TargetOpcode::G_VECREDUCE_MUL
: case TargetOpcode::G_VECREDUCE_AND: case TargetOpcode::G_VECREDUCE_OR
: case TargetOpcode::G_VECREDUCE_XOR: case TargetOpcode::G_VECREDUCE_SMAX
: case TargetOpcode::G_VECREDUCE_SMIN: case TargetOpcode::G_VECREDUCE_UMAX
: case TargetOpcode::G_VECREDUCE_UMIN:
\
54 case TargetOpcode::G_VECREDUCE_SEQ_FADD: \
55 case TargetOpcode::G_VECREDUCE_SEQ_FMUL: \
56 case TargetOpcode::G_VECREDUCE_FADD: \
57 case TargetOpcode::G_VECREDUCE_FMUL: \
58 case TargetOpcode::G_VECREDUCE_FMAX: \
59 case TargetOpcode::G_VECREDUCE_FMIN: \
60 case TargetOpcode::G_VECREDUCE_ADD: \
61 case TargetOpcode::G_VECREDUCE_MUL: \
62 case TargetOpcode::G_VECREDUCE_AND: \
63 case TargetOpcode::G_VECREDUCE_OR: \
64 case TargetOpcode::G_VECREDUCE_XOR: \
65 case TargetOpcode::G_VECREDUCE_SMAX: \
66 case TargetOpcode::G_VECREDUCE_SMIN: \
67 case TargetOpcode::G_VECREDUCE_UMAX: \
68 case TargetOpcode::G_VECREDUCE_UMIN:
69
70#define GISEL_VECREDUCE_CASES_NONSEQcase TargetOpcode::G_VECREDUCE_FADD: case TargetOpcode::G_VECREDUCE_FMUL
: case TargetOpcode::G_VECREDUCE_FMAX: case TargetOpcode::G_VECREDUCE_FMIN
: case TargetOpcode::G_VECREDUCE_ADD: case TargetOpcode::G_VECREDUCE_MUL
: case TargetOpcode::G_VECREDUCE_AND: case TargetOpcode::G_VECREDUCE_OR
: case TargetOpcode::G_VECREDUCE_XOR: case TargetOpcode::G_VECREDUCE_SMAX
: case TargetOpcode::G_VECREDUCE_SMIN: case TargetOpcode::G_VECREDUCE_UMAX
: case TargetOpcode::G_VECREDUCE_UMIN:
\
71 case TargetOpcode::G_VECREDUCE_FADD: \
72 case TargetOpcode::G_VECREDUCE_FMUL: \
73 case TargetOpcode::G_VECREDUCE_FMAX: \
74 case TargetOpcode::G_VECREDUCE_FMIN: \
75 case TargetOpcode::G_VECREDUCE_ADD: \
76 case TargetOpcode::G_VECREDUCE_MUL: \
77 case TargetOpcode::G_VECREDUCE_AND: \
78 case TargetOpcode::G_VECREDUCE_OR: \
79 case TargetOpcode::G_VECREDUCE_XOR: \
80 case TargetOpcode::G_VECREDUCE_SMAX: \
81 case TargetOpcode::G_VECREDUCE_SMIN: \
82 case TargetOpcode::G_VECREDUCE_UMAX: \
83 case TargetOpcode::G_VECREDUCE_UMIN:
84
85/// Try to constrain Reg to the specified register class. If this fails,
86/// create a new virtual register in the correct class.
87///
88/// \return The virtual register constrained to the right register class.
89Register constrainRegToClass(MachineRegisterInfo &MRI,
90 const TargetInstrInfo &TII,
91 const RegisterBankInfo &RBI, Register Reg,
92 const TargetRegisterClass &RegClass);
93
94/// Constrain the Register operand OpIdx, so that it is now constrained to the
95/// TargetRegisterClass passed as an argument (RegClass).
96/// If this fails, create a new virtual register in the correct class and insert
97/// a COPY before \p InsertPt if it is a use or after if it is a definition.
98/// In both cases, the function also updates the register of RegMo. The debug
99/// location of \p InsertPt is used for the new copy.
100///
101/// \return The virtual register constrained to the right register class.
102Register constrainOperandRegClass(const MachineFunction &MF,
103 const TargetRegisterInfo &TRI,
104 MachineRegisterInfo &MRI,
105 const TargetInstrInfo &TII,
106 const RegisterBankInfo &RBI,
107 MachineInstr &InsertPt,
108 const TargetRegisterClass &RegClass,
109 MachineOperand &RegMO);
110
111/// Try to constrain Reg so that it is usable by argument OpIdx of the provided
112/// MCInstrDesc \p II. If this fails, create a new virtual register in the
113/// correct class and insert a COPY before \p InsertPt if it is a use or after
114/// if it is a definition. In both cases, the function also updates the register
115/// of RegMo.
116/// This is equivalent to constrainOperandRegClass(..., RegClass, ...)
117/// with RegClass obtained from the MCInstrDesc. The debug location of \p
118/// InsertPt is used for the new copy.
119///
120/// \return The virtual register constrained to the right register class.
121Register constrainOperandRegClass(const MachineFunction &MF,
122 const TargetRegisterInfo &TRI,
123 MachineRegisterInfo &MRI,
124 const TargetInstrInfo &TII,
125 const RegisterBankInfo &RBI,
126 MachineInstr &InsertPt, const MCInstrDesc &II,
127 MachineOperand &RegMO, unsigned OpIdx);
128
129/// Mutate the newly-selected instruction \p I to constrain its (possibly
130/// generic) virtual register operands to the instruction's register class.
131/// This could involve inserting COPYs before (for uses) or after (for defs).
132/// This requires the number of operands to match the instruction description.
133/// \returns whether operand regclass constraining succeeded.
134///
135// FIXME: Not all instructions have the same number of operands. We should
136// probably expose a constrain helper per operand and let the target selector
137// constrain individual registers, like fast-isel.
138bool constrainSelectedInstRegOperands(MachineInstr &I,
139 const TargetInstrInfo &TII,
140 const TargetRegisterInfo &TRI,
141 const RegisterBankInfo &RBI);
142
143/// Check if DstReg can be replaced with SrcReg depending on the register
144/// constraints.
145bool canReplaceReg(Register DstReg, Register SrcReg, MachineRegisterInfo &MRI);
146
147/// Check whether an instruction \p MI is dead: it only defines dead virtual
148/// registers, and doesn't have other side effects.
149bool isTriviallyDead(const MachineInstr &MI, const MachineRegisterInfo &MRI);
150
151/// Report an ISel error as a missed optimization remark to the LLVMContext's
152/// diagnostic stream. Set the FailedISel MachineFunction property.
153void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
154 MachineOptimizationRemarkEmitter &MORE,
155 MachineOptimizationRemarkMissed &R);
156
157void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
158 MachineOptimizationRemarkEmitter &MORE,
159 const char *PassName, StringRef Msg,
160 const MachineInstr &MI);
161
162/// Report an ISel warning as a missed optimization remark to the LLVMContext's
163/// diagnostic stream.
164void reportGISelWarning(MachineFunction &MF, const TargetPassConfig &TPC,
165 MachineOptimizationRemarkEmitter &MORE,
166 MachineOptimizationRemarkMissed &R);
167
168/// If \p VReg is defined by a G_CONSTANT, return the corresponding value.
169std::optional<APInt> getIConstantVRegVal(Register VReg,
170 const MachineRegisterInfo &MRI);
171
172/// If \p VReg is defined by a G_CONSTANT fits in int64_t returns it.
173std::optional<int64_t> getIConstantVRegSExtVal(Register VReg,
174 const MachineRegisterInfo &MRI);
175
176/// Simple struct used to hold a constant integer value and a virtual
177/// register.
178struct ValueAndVReg {
179 APInt Value;
180 Register VReg;
181};
182
183/// If \p VReg is defined by a statically evaluable chain of instructions rooted
184/// on a G_CONSTANT returns its APInt value and def register.
185std::optional<ValueAndVReg>
186getIConstantVRegValWithLookThrough(Register VReg,
187 const MachineRegisterInfo &MRI,
188 bool LookThroughInstrs = true);
189
190/// If \p VReg is defined by a statically evaluable chain of instructions rooted
191/// on a G_CONSTANT or G_FCONSTANT returns its value as APInt and def register.
192std::optional<ValueAndVReg> getAnyConstantVRegValWithLookThrough(
193 Register VReg, const MachineRegisterInfo &MRI,
194 bool LookThroughInstrs = true, bool LookThroughAnyExt = false);
195
196struct FPValueAndVReg {
197 APFloat Value;
198 Register VReg;
199};
200
201/// If \p VReg is defined by a statically evaluable chain of instructions rooted
202/// on a G_FCONSTANT returns its APFloat value and def register.
203std::optional<FPValueAndVReg>
204getFConstantVRegValWithLookThrough(Register VReg,
205 const MachineRegisterInfo &MRI,
206 bool LookThroughInstrs = true);
207
208const ConstantFP* getConstantFPVRegVal(Register VReg,
209 const MachineRegisterInfo &MRI);
210
211/// See if Reg is defined by an single def instruction that is
212/// Opcode. Also try to do trivial folding if it's a COPY with
213/// same types. Returns null otherwise.
214MachineInstr *getOpcodeDef(unsigned Opcode, Register Reg,
215 const MachineRegisterInfo &MRI);
216
217/// Simple struct used to hold a Register value and the instruction which
218/// defines it.
219struct DefinitionAndSourceRegister {
220 MachineInstr *MI;
221 Register Reg;
222};
223
224/// Find the def instruction for \p Reg, and underlying value Register folding
225/// away any copies.
226///
227/// Also walks through hints such as G_ASSERT_ZEXT.
228std::optional<DefinitionAndSourceRegister>
229getDefSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI);
230
231/// Find the def instruction for \p Reg, folding away any trivial copies. May
232/// return nullptr if \p Reg is not a generic virtual register.
233///
234/// Also walks through hints such as G_ASSERT_ZEXT.
235MachineInstr *getDefIgnoringCopies(Register Reg,
236 const MachineRegisterInfo &MRI);
237
238/// Find the source register for \p Reg, folding away any trivial copies. It
239/// will be an output register of the instruction that getDefIgnoringCopies
240/// returns. May return an invalid register if \p Reg is not a generic virtual
241/// register.
242///
243/// Also walks through hints such as G_ASSERT_ZEXT.
244Register getSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI);
245
246// Templated variant of getOpcodeDef returning a MachineInstr derived T.
247/// See if Reg is defined by an single def instruction of type T
248/// Also try to do trivial folding if it's a COPY with
249/// same types. Returns null otherwise.
250template <class T>
251T *getOpcodeDef(Register Reg, const MachineRegisterInfo &MRI) {
252 MachineInstr *DefMI = getDefIgnoringCopies(Reg, MRI);
253 return dyn_cast_or_null<T>(DefMI);
254}
255
256/// Returns an APFloat from Val converted to the appropriate size.
257APFloat getAPFloatFromSize(double Val, unsigned Size);
258
259/// Modify analysis usage so it preserves passes required for the SelectionDAG
260/// fallback.
261void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU);
262
263std::optional<APInt> ConstantFoldBinOp(unsigned Opcode, const Register Op1,
264 const Register Op2,
265 const MachineRegisterInfo &MRI);
266std::optional<APFloat> ConstantFoldFPBinOp(unsigned Opcode, const Register Op1,
267 const Register Op2,
268 const MachineRegisterInfo &MRI);
269
270/// Tries to constant fold a vector binop with sources \p Op1 and \p Op2.
271/// Returns an empty vector on failure.
272SmallVector<APInt> ConstantFoldVectorBinop(unsigned Opcode, const Register Op1,
273 const Register Op2,
274 const MachineRegisterInfo &MRI);
275
276std::optional<APInt> ConstantFoldExtOp(unsigned Opcode, const Register Op1,
277 uint64_t Imm,
278 const MachineRegisterInfo &MRI);
279
280std::optional<APFloat> ConstantFoldIntToFloat(unsigned Opcode, LLT DstTy,
281 Register Src,
282 const MachineRegisterInfo &MRI);
283
284/// Tries to constant fold a G_CTLZ operation on \p Src. If \p Src is a vector
285/// then it tries to do an element-wise constant fold.
286std::optional<SmallVector<unsigned>>
287ConstantFoldCTLZ(Register Src, const MachineRegisterInfo &MRI);
288
289/// Test if the given value is known to have exactly one bit set. This differs
290/// from computeKnownBits in that it doesn't necessarily determine which bit is
291/// set.
292bool isKnownToBeAPowerOfTwo(Register Val, const MachineRegisterInfo &MRI,
293 GISelKnownBits *KnownBits = nullptr);
294
295/// Returns true if \p Val can be assumed to never be a NaN. If \p SNaN is true,
296/// this returns if \p Val can be assumed to never be a signaling NaN.
297bool isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI,
298 bool SNaN = false);
299
300/// Returns true if \p Val can be assumed to never be a signaling NaN.
301inline bool isKnownNeverSNaN(Register Val, const MachineRegisterInfo &MRI) {
302 return isKnownNeverNaN(Val, MRI, true);
303}
304
305Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO);
306
307/// Return a virtual register corresponding to the incoming argument register \p
308/// PhysReg. This register is expected to have class \p RC, and optional type \p
309/// RegTy. This assumes all references to the register will use the same type.
310///
311/// If there is an existing live-in argument register, it will be returned.
312/// This will also ensure there is a valid copy
313Register getFunctionLiveInPhysReg(MachineFunction &MF,
314 const TargetInstrInfo &TII,
315 MCRegister PhysReg,
316 const TargetRegisterClass &RC,
317 const DebugLoc &DL, LLT RegTy = LLT());
318
319/// Return the least common multiple type of \p OrigTy and \p TargetTy, by changing the
320/// number of vector elements or scalar bitwidth. The intent is a
321/// G_MERGE_VALUES, G_BUILD_VECTOR, or G_CONCAT_VECTORS can be constructed from
322/// \p OrigTy elements, and unmerged into \p TargetTy
323LLVM_READNONE__attribute__((__const__))
324LLT getLCMType(LLT OrigTy, LLT TargetTy);
325
326LLVM_READNONE__attribute__((__const__))
327/// Return smallest type that covers both \p OrigTy and \p TargetTy and is
328/// multiple of TargetTy.
329LLT getCoverTy(LLT OrigTy, LLT TargetTy);
330
331/// Return a type where the total size is the greatest common divisor of \p
332/// OrigTy and \p TargetTy. This will try to either change the number of vector
333/// elements, or bitwidth of scalars. The intent is the result type can be used
334/// as the result of a G_UNMERGE_VALUES from \p OrigTy, and then some
335/// combination of G_MERGE_VALUES, G_BUILD_VECTOR and G_CONCAT_VECTORS (possibly
336/// with intermediate casts) can re-form \p TargetTy.
337///
338/// If these are vectors with different element types, this will try to produce
339/// a vector with a compatible total size, but the element type of \p OrigTy. If
340/// this can't be satisfied, this will produce a scalar smaller than the
341/// original vector elements.
342///
343/// In the worst case, this returns LLT::scalar(1)
344LLVM_READNONE__attribute__((__const__))
345LLT getGCDType(LLT OrigTy, LLT TargetTy);
346
347/// Represents a value which can be a Register or a constant.
348///
349/// This is useful in situations where an instruction may have an interesting
350/// register operand or interesting constant operand. For a concrete example,
351/// \see getVectorSplat.
352class RegOrConstant {
353 int64_t Cst;
354 Register Reg;
355 bool IsReg;
356
357public:
358 explicit RegOrConstant(Register Reg) : Reg(Reg), IsReg(true) {}
359 explicit RegOrConstant(int64_t Cst) : Cst(Cst), IsReg(false) {}
360 bool isReg() const { return IsReg; }
361 bool isCst() const { return !IsReg; }
362 Register getReg() const {
363 assert(isReg() && "Expected a register!")(static_cast <bool> (isReg() && "Expected a register!"
) ? void (0) : __assert_fail ("isReg() && \"Expected a register!\""
, "llvm/include/llvm/CodeGen/GlobalISel/Utils.h", 363, __extension__
__PRETTY_FUNCTION__))
;
364 return Reg;
365 }
366 int64_t getCst() const {
367 assert(isCst() && "Expected a constant!")(static_cast <bool> (isCst() && "Expected a constant!"
) ? void (0) : __assert_fail ("isCst() && \"Expected a constant!\""
, "llvm/include/llvm/CodeGen/GlobalISel/Utils.h", 367, __extension__
__PRETTY_FUNCTION__))
;
368 return Cst;
369 }
370};
371
372/// \returns The splat index of a G_SHUFFLE_VECTOR \p MI when \p MI is a splat.
373/// If \p MI is not a splat, returns std::nullopt.
374std::optional<int> getSplatIndex(MachineInstr &MI);
375
376/// \returns the scalar integral splat value of \p Reg if possible.
377std::optional<APInt> getIConstantSplatVal(const Register Reg,
378 const MachineRegisterInfo &MRI);
379
380/// \returns the scalar integral splat value defined by \p MI if possible.
381std::optional<APInt> getIConstantSplatVal(const MachineInstr &MI,
382 const MachineRegisterInfo &MRI);
383
384/// \returns the scalar sign extended integral splat value of \p Reg if
385/// possible.
386std::optional<int64_t> getIConstantSplatSExtVal(const Register Reg,
387 const MachineRegisterInfo &MRI);
388
389/// \returns the scalar sign extended integral splat value defined by \p MI if
390/// possible.
391std::optional<int64_t> getIConstantSplatSExtVal(const MachineInstr &MI,
392 const MachineRegisterInfo &MRI);
393
394/// Returns a floating point scalar constant of a build vector splat if it
395/// exists. When \p AllowUndef == true some elements can be undef but not all.
396std::optional<FPValueAndVReg> getFConstantSplat(Register VReg,
397 const MachineRegisterInfo &MRI,
398 bool AllowUndef = true);
399
400/// Return true if the specified register is defined by G_BUILD_VECTOR or
401/// G_BUILD_VECTOR_TRUNC where all of the elements are \p SplatValue or undef.
402bool isBuildVectorConstantSplat(const Register Reg,
403 const MachineRegisterInfo &MRI,
404 int64_t SplatValue, bool AllowUndef);
405
406/// Return true if the specified instruction is a G_BUILD_VECTOR or
407/// G_BUILD_VECTOR_TRUNC where all of the elements are \p SplatValue or undef.
408bool isBuildVectorConstantSplat(const MachineInstr &MI,
409 const MachineRegisterInfo &MRI,
410 int64_t SplatValue, bool AllowUndef);
411
412/// Return true if the specified instruction is a G_BUILD_VECTOR or
413/// G_BUILD_VECTOR_TRUNC where all of the elements are 0 or undef.
414bool isBuildVectorAllZeros(const MachineInstr &MI,
415 const MachineRegisterInfo &MRI,
416 bool AllowUndef = false);
417
418/// Return true if the specified instruction is a G_BUILD_VECTOR or
419/// G_BUILD_VECTOR_TRUNC where all of the elements are ~0 or undef.
420bool isBuildVectorAllOnes(const MachineInstr &MI,
421 const MachineRegisterInfo &MRI,
422 bool AllowUndef = false);
423
424/// Return true if the specified instruction is known to be a constant, or a
425/// vector of constants.
426///
427/// If \p AllowFP is true, this will consider G_FCONSTANT in addition to
428/// G_CONSTANT. If \p AllowOpaqueConstants is true, constant-like instructions
429/// such as G_GLOBAL_VALUE will also be considered.
430bool isConstantOrConstantVector(const MachineInstr &MI,
431 const MachineRegisterInfo &MRI,
432 bool AllowFP = true,
433 bool AllowOpaqueConstants = true);
434
435/// Return true if the value is a constant 0 integer or a splatted vector of a
436/// constant 0 integer (with no undefs if \p AllowUndefs is false). This will
437/// handle G_BUILD_VECTOR and G_BUILD_VECTOR_TRUNC as truncation is not an issue
438/// for null values.
439bool isNullOrNullSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI,
440 bool AllowUndefs = false);
441
442/// Return true if the value is a constant -1 integer or a splatted vector of a
443/// constant -1 integer (with no undefs if \p AllowUndefs is false).
444bool isAllOnesOrAllOnesSplat(const MachineInstr &MI,
445 const MachineRegisterInfo &MRI,
446 bool AllowUndefs = false);
447
448/// \returns a value when \p MI is a vector splat. The splat can be either a
449/// Register or a constant.
450///
451/// Examples:
452///
453/// \code
454/// %reg = COPY $physreg
455/// %reg_splat = G_BUILD_VECTOR %reg, %reg, ..., %reg
456/// \endcode
457///
458/// If called on the G_BUILD_VECTOR above, this will return a RegOrConstant
459/// containing %reg.
460///
461/// \code
462/// %cst = G_CONSTANT iN 4
463/// %constant_splat = G_BUILD_VECTOR %cst, %cst, ..., %cst
464/// \endcode
465///
466/// In the above case, this will return a RegOrConstant containing 4.
467std::optional<RegOrConstant> getVectorSplat(const MachineInstr &MI,
468 const MachineRegisterInfo &MRI);
469
470/// Determines if \p MI defines a constant integer or a build vector of
471/// constant integers. Treats undef values as constants.
472bool isConstantOrConstantVector(MachineInstr &MI,
473 const MachineRegisterInfo &MRI);
474
475/// Determines if \p MI defines a constant integer or a splat vector of
476/// constant integers.
477/// \returns the scalar constant or std::nullopt.
478std::optional<APInt>
479isConstantOrConstantSplatVector(MachineInstr &MI,
480 const MachineRegisterInfo &MRI);
481
482/// Attempt to match a unary predicate against a scalar/splat constant or every
483/// element of a constant G_BUILD_VECTOR. If \p ConstVal is null, the source
484/// value was undef.
485bool matchUnaryPredicate(const MachineRegisterInfo &MRI, Register Reg,
486 std::function<bool(const Constant *ConstVal)> Match,
487 bool AllowUndefs = false);
488
489/// Returns true if given the TargetLowering's boolean contents information,
490/// the value \p Val contains a true value.
491bool isConstTrueVal(const TargetLowering &TLI, int64_t Val, bool IsVector,
492 bool IsFP);
493/// \returns true if given the TargetLowering's boolean contents information,
494/// the value \p Val contains a false value.
495bool isConstFalseVal(const TargetLowering &TLI, int64_t Val, bool IsVector,
496 bool IsFP);
497
498/// Returns an integer representing true, as defined by the
499/// TargetBooleanContents.
500int64_t getICmpTrueVal(const TargetLowering &TLI, bool IsVector, bool IsFP);
501
502/// Returns true if the given block should be optimized for size.
503bool shouldOptForSize(const MachineBasicBlock &MBB, ProfileSummaryInfo *PSI,
504 BlockFrequencyInfo *BFI);
505
506using SmallInstListTy = GISelWorkList<4>;
507void saveUsesAndErase(MachineInstr &MI, MachineRegisterInfo &MRI,
508 LostDebugLocObserver *LocObserver,
509 SmallInstListTy &DeadInstChain);
510void eraseInstrs(ArrayRef<MachineInstr *> DeadInstrs, MachineRegisterInfo &MRI,
511 LostDebugLocObserver *LocObserver = nullptr);
512void eraseInstr(MachineInstr &MI, MachineRegisterInfo &MRI,
513 LostDebugLocObserver *LocObserver = nullptr);
514
515/// Assuming the instruction \p MI is going to be deleted, attempt to salvage
516/// debug users of \p MI by writing the effect of \p MI in a DIExpression.
517void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI);
518
519} // End namespace llvm.
520#endif

/build/source/llvm/include/llvm/ADT/APInt.h

1//===-- llvm/ADT/APInt.h - For Arbitrary Precision Integer -----*- C++ -*--===//
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/// \file
10/// This file implements a class to represent arbitrary precision
11/// integral constant values and operations on them.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_ADT_APINT_H
16#define LLVM_ADT_APINT_H
17
18#include "llvm/Support/Compiler.h"
19#include "llvm/Support/MathExtras.h"
20#include <cassert>
21#include <climits>
22#include <cstring>
23#include <optional>
24#include <utility>
25
26namespace llvm {
27class FoldingSetNodeID;
28class StringRef;
29class hash_code;
30class raw_ostream;
31
32template <typename T> class SmallVectorImpl;
33template <typename T> class ArrayRef;
34template <typename T, typename Enable> struct DenseMapInfo;
35
36class APInt;
37
38inline APInt operator-(APInt);
39
40//===----------------------------------------------------------------------===//
41// APInt Class
42//===----------------------------------------------------------------------===//
43
44/// Class for arbitrary precision integers.
45///
46/// APInt is a functional replacement for common case unsigned integer type like
47/// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width
48/// integer sizes and large integer value types such as 3-bits, 15-bits, or more
49/// than 64-bits of precision. APInt provides a variety of arithmetic operators
50/// and methods to manipulate integer values of any bit-width. It supports both
51/// the typical integer arithmetic and comparison operations as well as bitwise
52/// manipulation.
53///
54/// The class has several invariants worth noting:
55/// * All bit, byte, and word positions are zero-based.
56/// * Once the bit width is set, it doesn't change except by the Truncate,
57/// SignExtend, or ZeroExtend operations.
58/// * All binary operators must be on APInt instances of the same bit width.
59/// Attempting to use these operators on instances with different bit
60/// widths will yield an assertion.
61/// * The value is stored canonically as an unsigned value. For operations
62/// where it makes a difference, there are both signed and unsigned variants
63/// of the operation. For example, sdiv and udiv. However, because the bit
64/// widths must be the same, operations such as Mul and Add produce the same
65/// results regardless of whether the values are interpreted as signed or
66/// not.
67/// * In general, the class tries to follow the style of computation that LLVM
68/// uses in its IR. This simplifies its use for LLVM.
69/// * APInt supports zero-bit-width values, but operations that require bits
70/// are not defined on it (e.g. you cannot ask for the sign of a zero-bit
71/// integer). This means that operations like zero extension and logical
72/// shifts are defined, but sign extension and ashr is not. Zero bit values
73/// compare and hash equal to themselves, and countLeadingZeros returns 0.
74///
75class [[nodiscard]] APInt {
76public:
77 typedef uint64_t WordType;
78
79 /// This enum is used to hold the constants we needed for APInt.
80 enum : unsigned {
81 /// Byte size of a word.
82 APINT_WORD_SIZE = sizeof(WordType),
83 /// Bits in a word.
84 APINT_BITS_PER_WORD = APINT_WORD_SIZE * CHAR_BIT8
85 };
86
87 enum class Rounding {
88 DOWN,
89 TOWARD_ZERO,
90 UP,
91 };
92
93 static constexpr WordType WORDTYPE_MAX = ~WordType(0);
94
95 /// \name Constructors
96 /// @{
97
98 /// Create a new APInt of numBits width, initialized as val.
99 ///
100 /// If isSigned is true then val is treated as if it were a signed value
101 /// (i.e. as an int64_t) and the appropriate sign extension to the bit width
102 /// will be done. Otherwise, no sign extension occurs (high order bits beyond
103 /// the range of val are zero filled).
104 ///
105 /// \param numBits the bit width of the constructed APInt
106 /// \param val the initial value of the APInt
107 /// \param isSigned how to treat signedness of val
108 APInt(unsigned numBits, uint64_t val, bool isSigned = false)
109 : BitWidth(numBits) {
110 if (isSingleWord()) {
111 U.VAL = val;
112 clearUnusedBits();
113 } else {
114 initSlowCase(val, isSigned);
115 }
116 }
117
118 /// Construct an APInt of numBits width, initialized as bigVal[].
119 ///
120 /// Note that bigVal.size() can be smaller or larger than the corresponding
121 /// bit width but any extraneous bits will be dropped.
122 ///
123 /// \param numBits the bit width of the constructed APInt
124 /// \param bigVal a sequence of words to form the initial value of the APInt
125 APInt(unsigned numBits, ArrayRef<uint64_t> bigVal);
126
127 /// Equivalent to APInt(numBits, ArrayRef<uint64_t>(bigVal, numWords)), but
128 /// deprecated because this constructor is prone to ambiguity with the
129 /// APInt(unsigned, uint64_t, bool) constructor.
130 ///
131 /// If this overload is ever deleted, care should be taken to prevent calls
132 /// from being incorrectly captured by the APInt(unsigned, uint64_t, bool)
133 /// constructor.
134 APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
135
136 /// Construct an APInt from a string representation.
137 ///
138 /// This constructor interprets the string \p str in the given radix. The
139 /// interpretation stops when the first character that is not suitable for the
140 /// radix is encountered, or the end of the string. Acceptable radix values
141 /// are 2, 8, 10, 16, and 36. It is an error for the value implied by the
142 /// string to require more bits than numBits.
143 ///
144 /// \param numBits the bit width of the constructed APInt
145 /// \param str the string to be interpreted
146 /// \param radix the radix to use for the conversion
147 APInt(unsigned numBits, StringRef str, uint8_t radix);
148
149 /// Default constructor that creates an APInt with a 1-bit zero value.
150 explicit APInt() { U.VAL = 0; }
151
152 /// Copy Constructor.
153 APInt(const APInt &that) : BitWidth(that.BitWidth) {
154 if (isSingleWord())
155 U.VAL = that.U.VAL;
156 else
157 initSlowCase(that);
158 }
159
160 /// Move Constructor.
161 APInt(APInt &&that) : BitWidth(that.BitWidth) {
162 memcpy(&U, &that.U, sizeof(U));
163 that.BitWidth = 0;
164 }
165
166 /// Destructor.
167 ~APInt() {
168 if (needsCleanup())
12
Taking true branch
23
Taking true branch
169 delete[] U.pVal;
13
Memory is released
24
Attempt to free released memory
170 }
171
172 /// @}
173 /// \name Value Generators
174 /// @{
175
176 /// Get the '0' value for the specified bit-width.
177 static APInt getZero(unsigned numBits) { return APInt(numBits, 0); }
178
179 LLVM_DEPRECATED("use getZero instead", "getZero")__attribute__((deprecated("use getZero instead", "getZero")))
180 static APInt getNullValue(unsigned numBits) { return getZero(numBits); }
181
182 /// Return an APInt zero bits wide.
183 static APInt getZeroWidth() { return getZero(0); }
184
185 /// Gets maximum unsigned value of APInt for specific bit width.
186 static APInt getMaxValue(unsigned numBits) { return getAllOnes(numBits); }
187
188 /// Gets maximum signed value of APInt for a specific bit width.
189 static APInt getSignedMaxValue(unsigned numBits) {
190 APInt API = getAllOnes(numBits);
191 API.clearBit(numBits - 1);
192 return API;
193 }
194
195 /// Gets minimum unsigned value of APInt for a specific bit width.
196 static APInt getMinValue(unsigned numBits) { return APInt(numBits, 0); }
197
198 /// Gets minimum signed value of APInt for a specific bit width.
199 static APInt getSignedMinValue(unsigned numBits) {
200 APInt API(numBits, 0);
201 API.setBit(numBits - 1);
202 return API;
203 }
204
205 /// Get the SignMask for a specific bit width.
206 ///
207 /// This is just a wrapper function of getSignedMinValue(), and it helps code
208 /// readability when we want to get a SignMask.
209 static APInt getSignMask(unsigned BitWidth) {
210 return getSignedMinValue(BitWidth);
211 }
212
213 /// Return an APInt of a specified width with all bits set.
214 static APInt getAllOnes(unsigned numBits) {
215 return APInt(numBits, WORDTYPE_MAX, true);
216 }
217
218 LLVM_DEPRECATED("use getAllOnes instead", "getAllOnes")__attribute__((deprecated("use getAllOnes instead", "getAllOnes"
)))
219 static APInt getAllOnesValue(unsigned numBits) { return getAllOnes(numBits); }
220
221 /// Return an APInt with exactly one bit set in the result.
222 static APInt getOneBitSet(unsigned numBits, unsigned BitNo) {
223 APInt Res(numBits, 0);
224 Res.setBit(BitNo);
225 return Res;
226 }
227
228 /// Get a value with a block of bits set.
229 ///
230 /// Constructs an APInt value that has a contiguous range of bits set. The
231 /// bits from loBit (inclusive) to hiBit (exclusive) will be set. All other
232 /// bits will be zero. For example, with parameters(32, 0, 16) you would get
233 /// 0x0000FFFF. Please call getBitsSetWithWrap if \p loBit may be greater than
234 /// \p hiBit.
235 ///
236 /// \param numBits the intended bit width of the result
237 /// \param loBit the index of the lowest bit set.
238 /// \param hiBit the index of the highest bit set.
239 ///
240 /// \returns An APInt value with the requested bits set.
241 static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit) {
242 APInt Res(numBits, 0);
243 Res.setBits(loBit, hiBit);
244 return Res;
245 }
246
247 /// Wrap version of getBitsSet.
248 /// If \p hiBit is bigger than \p loBit, this is same with getBitsSet.
249 /// If \p hiBit is not bigger than \p loBit, the set bits "wrap". For example,
250 /// with parameters (32, 28, 4), you would get 0xF000000F.
251 /// If \p hiBit is equal to \p loBit, you would get a result with all bits
252 /// set.
253 static APInt getBitsSetWithWrap(unsigned numBits, unsigned loBit,
254 unsigned hiBit) {
255 APInt Res(numBits, 0);
256 Res.setBitsWithWrap(loBit, hiBit);
257 return Res;
258 }
259
260 /// Constructs an APInt value that has a contiguous range of bits set. The
261 /// bits from loBit (inclusive) to numBits (exclusive) will be set. All other
262 /// bits will be zero. For example, with parameters(32, 12) you would get
263 /// 0xFFFFF000.
264 ///
265 /// \param numBits the intended bit width of the result
266 /// \param loBit the index of the lowest bit to set.
267 ///
268 /// \returns An APInt value with the requested bits set.
269 static APInt getBitsSetFrom(unsigned numBits, unsigned loBit) {
270 APInt Res(numBits, 0);
271 Res.setBitsFrom(loBit);
272 return Res;
273 }
274
275 /// Constructs an APInt value that has the top hiBitsSet bits set.
276 ///
277 /// \param numBits the bitwidth of the result
278 /// \param hiBitsSet the number of high-order bits set in the result.
279 static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet) {
280 APInt Res(numBits, 0);
281 Res.setHighBits(hiBitsSet);
282 return Res;
283 }
284
285 /// Constructs an APInt value that has the bottom loBitsSet bits set.
286 ///
287 /// \param numBits the bitwidth of the result
288 /// \param loBitsSet the number of low-order bits set in the result.
289 static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet) {
290 APInt Res(numBits, 0);
291 Res.setLowBits(loBitsSet);
292 return Res;
293 }
294
295 /// Return a value containing V broadcasted over NewLen bits.
296 static APInt getSplat(unsigned NewLen, const APInt &V);
297
298 /// @}
299 /// \name Value Tests
300 /// @{
301
302 /// Determine if this APInt just has one word to store value.
303 ///
304 /// \returns true if the number of bits <= 64, false otherwise.
305 bool isSingleWord() const { return BitWidth <= APINT_BITS_PER_WORD; }
306
307 /// Determine sign of this APInt.
308 ///
309 /// This tests the high bit of this APInt to determine if it is set.
310 ///
311 /// \returns true if this APInt is negative, false otherwise
312 bool isNegative() const { return (*this)[BitWidth - 1]; }
313
314 /// Determine if this APInt Value is non-negative (>= 0)
315 ///
316 /// This tests the high bit of the APInt to determine if it is unset.
317 bool isNonNegative() const { return !isNegative(); }
318
319 /// Determine if sign bit of this APInt is set.
320 ///
321 /// This tests the high bit of this APInt to determine if it is set.
322 ///
323 /// \returns true if this APInt has its sign bit set, false otherwise.
324 bool isSignBitSet() const { return (*this)[BitWidth - 1]; }
325
326 /// Determine if sign bit of this APInt is clear.
327 ///
328 /// This tests the high bit of this APInt to determine if it is clear.
329 ///
330 /// \returns true if this APInt has its sign bit clear, false otherwise.
331 bool isSignBitClear() const { return !isSignBitSet(); }
332
333 /// Determine if this APInt Value is positive.
334 ///
335 /// This tests if the value of this APInt is positive (> 0). Note
336 /// that 0 is not a positive value.
337 ///
338 /// \returns true if this APInt is positive.
339 bool isStrictlyPositive() const { return isNonNegative() && !isZero(); }
340
341 /// Determine if this APInt Value is non-positive (<= 0).
342 ///
343 /// \returns true if this APInt is non-positive.
344 bool isNonPositive() const { return !isStrictlyPositive(); }
345
346 /// Determine if this APInt Value only has the specified bit set.
347 ///
348 /// \returns true if this APInt only has the specified bit set.
349 bool isOneBitSet(unsigned BitNo) const {
350 return (*this)[BitNo] && popcount() == 1;
351 }
352
353 /// Determine if all bits are set. This is true for zero-width values.
354 bool isAllOnes() const {
355 if (BitWidth == 0)
356 return true;
357 if (isSingleWord())
358 return U.VAL == WORDTYPE_MAX >> (APINT_BITS_PER_WORD - BitWidth);
359 return countTrailingOnesSlowCase() == BitWidth;
360 }
361
362 LLVM_DEPRECATED("use isAllOnes instead", "isAllOnes")__attribute__((deprecated("use isAllOnes instead", "isAllOnes"
)))
363 bool isAllOnesValue() const { return isAllOnes(); }
364
365 /// Determine if this value is zero, i.e. all bits are clear.
366 bool isZero() const {
367 if (isSingleWord())
368 return U.VAL == 0;
369 return countLeadingZerosSlowCase() == BitWidth;
370 }
371
372 LLVM_DEPRECATED("use isZero instead", "isZero")__attribute__((deprecated("use isZero instead", "isZero")))
373 bool isNullValue() const { return isZero(); }
374
375 /// Determine if this is a value of 1.
376 ///
377 /// This checks to see if the value of this APInt is one.
378 bool isOne() const {
379 if (isSingleWord())
380 return U.VAL == 1;
381 return countLeadingZerosSlowCase() == BitWidth - 1;
382 }
383
384 LLVM_DEPRECATED("use isOne instead", "isOne")__attribute__((deprecated("use isOne instead", "isOne")))
385 bool isOneValue() const { return isOne(); }
386
387 /// Determine if this is the largest unsigned value.
388 ///
389 /// This checks to see if the value of this APInt is the maximum unsigned
390 /// value for the APInt's bit width.
391 bool isMaxValue() const { return isAllOnes(); }
392
393 /// Determine if this is the largest signed value.
394 ///
395 /// This checks to see if the value of this APInt is the maximum signed
396 /// value for the APInt's bit width.
397 bool isMaxSignedValue() const {
398 if (isSingleWord()) {
399 assert(BitWidth && "zero width values not allowed")(static_cast <bool> (BitWidth && "zero width values not allowed"
) ? void (0) : __assert_fail ("BitWidth && \"zero width values not allowed\""
, "llvm/include/llvm/ADT/APInt.h", 399, __extension__ __PRETTY_FUNCTION__
))
;
400 return U.VAL == ((WordType(1) << (BitWidth - 1)) - 1);
401 }
402 return !isNegative() && countTrailingOnesSlowCase() == BitWidth - 1;
403 }
404
405 /// Determine if this is the smallest unsigned value.
406 ///
407 /// This checks to see if the value of this APInt is the minimum unsigned
408 /// value for the APInt's bit width.
409 bool isMinValue() const { return isZero(); }
410
411 /// Determine if this is the smallest signed value.
412 ///
413 /// This checks to see if the value of this APInt is the minimum signed
414 /// value for the APInt's bit width.
415 bool isMinSignedValue() const {
416 if (isSingleWord()) {
417 assert(BitWidth && "zero width values not allowed")(static_cast <bool> (BitWidth && "zero width values not allowed"
) ? void (0) : __assert_fail ("BitWidth && \"zero width values not allowed\""
, "llvm/include/llvm/ADT/APInt.h", 417, __extension__ __PRETTY_FUNCTION__
))
;
418 return U.VAL == (WordType(1) << (BitWidth - 1));
419 }
420 return isNegative() && countTrailingZerosSlowCase() == BitWidth - 1;
421 }
422
423 /// Check if this APInt has an N-bits unsigned integer value.
424 bool isIntN(unsigned N) const { return getActiveBits() <= N; }
425
426 /// Check if this APInt has an N-bits signed integer value.
427 bool isSignedIntN(unsigned N) const { return getSignificantBits() <= N; }
428
429 /// Check if this APInt's value is a power of two greater than zero.
430 ///
431 /// \returns true if the argument APInt value is a power of two > 0.
432 bool isPowerOf2() const {
433 if (isSingleWord()) {
434 assert(BitWidth && "zero width values not allowed")(static_cast <bool> (BitWidth && "zero width values not allowed"
) ? void (0) : __assert_fail ("BitWidth && \"zero width values not allowed\""
, "llvm/include/llvm/ADT/APInt.h", 434, __extension__ __PRETTY_FUNCTION__
))
;
435 return isPowerOf2_64(U.VAL);
436 }
437 return countPopulationSlowCase() == 1;
438 }
439
440 /// Check if this APInt's negated value is a power of two greater than zero.
441 bool isNegatedPowerOf2() const {
442 assert(BitWidth && "zero width values not allowed")(static_cast <bool> (BitWidth && "zero width values not allowed"
) ? void (0) : __assert_fail ("BitWidth && \"zero width values not allowed\""
, "llvm/include/llvm/ADT/APInt.h", 442, __extension__ __PRETTY_FUNCTION__
))
;
443 if (isNonNegative())
444 return false;
445 // NegatedPowerOf2 - shifted mask in the top bits.
446 unsigned LO = countl_one();
447 unsigned TZ = countr_zero();
448 return (LO + TZ) == BitWidth;
449 }
450
451 /// Check if the APInt's value is returned by getSignMask.
452 ///
453 /// \returns true if this is the value returned by getSignMask.
454 bool isSignMask() const { return isMinSignedValue(); }
455
456 /// Convert APInt to a boolean value.
457 ///
458 /// This converts the APInt to a boolean value as a test against zero.
459 bool getBoolValue() const { return !isZero(); }
460
461 /// If this value is smaller than the specified limit, return it, otherwise
462 /// return the limit value. This causes the value to saturate to the limit.
463 uint64_t getLimitedValue(uint64_t Limit = UINT64_MAX(18446744073709551615UL)) const {
464 return ugt(Limit) ? Limit : getZExtValue();
465 }
466
467 /// Check if the APInt consists of a repeated bit pattern.
468 ///
469 /// e.g. 0x01010101 satisfies isSplat(8).
470 /// \param SplatSizeInBits The size of the pattern in bits. Must divide bit
471 /// width without remainder.
472 bool isSplat(unsigned SplatSizeInBits) const;
473
474 /// \returns true if this APInt value is a sequence of \param numBits ones
475 /// starting at the least significant bit with the remainder zero.
476 bool isMask(unsigned numBits) const {
477 assert(numBits != 0 && "numBits must be non-zero")(static_cast <bool> (numBits != 0 && "numBits must be non-zero"
) ? void (0) : __assert_fail ("numBits != 0 && \"numBits must be non-zero\""
, "llvm/include/llvm/ADT/APInt.h", 477, __extension__ __PRETTY_FUNCTION__
))
;
478 assert(numBits <= BitWidth && "numBits out of range")(static_cast <bool> (numBits <= BitWidth && "numBits out of range"
) ? void (0) : __assert_fail ("numBits <= BitWidth && \"numBits out of range\""
, "llvm/include/llvm/ADT/APInt.h", 478, __extension__ __PRETTY_FUNCTION__
))
;
479 if (isSingleWord())
480 return U.VAL == (WORDTYPE_MAX >> (APINT_BITS_PER_WORD - numBits));
481 unsigned Ones = countTrailingOnesSlowCase();
482 return (numBits == Ones) &&
483 ((Ones + countLeadingZerosSlowCase()) == BitWidth);
484 }
485
486 /// \returns true if this APInt is a non-empty sequence of ones starting at
487 /// the least significant bit with the remainder zero.
488 /// Ex. isMask(0x0000FFFFU) == true.
489 bool isMask() const {
490 if (isSingleWord())
491 return isMask_64(U.VAL);
492 unsigned Ones = countTrailingOnesSlowCase();
493 return (Ones > 0) && ((Ones + countLeadingZerosSlowCase()) == BitWidth);
494 }
495
496 /// Return true if this APInt value contains a non-empty sequence of ones with
497 /// the remainder zero.
498 bool isShiftedMask() const {
499 if (isSingleWord())
500 return isShiftedMask_64(U.VAL);
501 unsigned Ones = countPopulationSlowCase();
502 unsigned LeadZ = countLeadingZerosSlowCase();
503 return (Ones + LeadZ + countr_zero()) == BitWidth;
504 }
505
506 /// Return true if this APInt value contains a non-empty sequence of ones with
507 /// the remainder zero. If true, \p MaskIdx will specify the index of the
508 /// lowest set bit and \p MaskLen is updated to specify the length of the
509 /// mask, else neither are updated.
510 bool isShiftedMask(unsigned &MaskIdx, unsigned &MaskLen) const {
511 if (isSingleWord())
512 return isShiftedMask_64(U.VAL, MaskIdx, MaskLen);
513 unsigned Ones = countPopulationSlowCase();
514 unsigned LeadZ = countLeadingZerosSlowCase();
515 unsigned TrailZ = countTrailingZerosSlowCase();
516 if ((Ones + LeadZ + TrailZ) != BitWidth)
517 return false;
518 MaskLen = Ones;
519 MaskIdx = TrailZ;
520 return true;
521 }
522
523 /// Compute an APInt containing numBits highbits from this APInt.
524 ///
525 /// Get an APInt with the same BitWidth as this APInt, just zero mask the low
526 /// bits and right shift to the least significant bit.
527 ///
528 /// \returns the high "numBits" bits of this APInt.
529 APInt getHiBits(unsigned numBits) const;
530
531 /// Compute an APInt containing numBits lowbits from this APInt.
532 ///
533 /// Get an APInt with the same BitWidth as this APInt, just zero mask the high
534 /// bits.
535 ///
536 /// \returns the low "numBits" bits of this APInt.
537 APInt getLoBits(unsigned numBits) const;
538
539 /// Determine if two APInts have the same value, after zero-extending
540 /// one of them (if needed!) to ensure that the bit-widths match.
541 static bool isSameValue(const APInt &I1, const APInt &I2) {
542 if (I1.getBitWidth() == I2.getBitWidth())
543 return I1 == I2;
544
545 if (I1.getBitWidth() > I2.getBitWidth())
546 return I1 == I2.zext(I1.getBitWidth());
547
548 return I1.zext(I2.getBitWidth()) == I2;
549 }
550
551 /// Overload to compute a hash_code for an APInt value.
552 friend hash_code hash_value(const APInt &Arg);
553
554 /// This function returns a pointer to the internal storage of the APInt.
555 /// This is useful for writing out the APInt in binary form without any
556 /// conversions.
557 const uint64_t *getRawData() const {
558 if (isSingleWord())
559 return &U.VAL;
560 return &U.pVal[0];
561 }
562
563 /// @}
564 /// \name Unary Operators
565 /// @{
566
567 /// Postfix increment operator. Increment *this by 1.
568 ///
569 /// \returns a new APInt value representing the original value of *this.
570 APInt operator++(int) {
571 APInt API(*this);
572 ++(*this);
573 return API;
574 }
575
576 /// Prefix increment operator.
577 ///
578 /// \returns *this incremented by one
579 APInt &operator++();
580
581 /// Postfix decrement operator. Decrement *this by 1.
582 ///
583 /// \returns a new APInt value representing the original value of *this.
584 APInt operator--(int) {
585 APInt API(*this);
586 --(*this);
587 return API;
588 }
589
590 /// Prefix decrement operator.
591 ///
592 /// \returns *this decremented by one.
593 APInt &operator--();
594
595 /// Logical negation operation on this APInt returns true if zero, like normal
596 /// integers.
597 bool operator!() const { return isZero(); }
598
599 /// @}
600 /// \name Assignment Operators
601 /// @{
602
603 /// Copy assignment operator.
604 ///
605 /// \returns *this after assignment of RHS.
606 APInt &operator=(const APInt &RHS) {
607 // The common case (both source or dest being inline) doesn't require
608 // allocation or deallocation.
609 if (isSingleWord() && RHS.isSingleWord()) {
610 U.VAL = RHS.U.VAL;
611 BitWidth = RHS.BitWidth;
612 return *this;
613 }
614
615 assignSlowCase(RHS);
616 return *this;
617 }
618
619 /// Move assignment operator.
620 APInt &operator=(APInt &&that) {
621#ifdef EXPENSIVE_CHECKS
622 // Some std::shuffle implementations still do self-assignment.
623 if (this == &that)
624 return *this;
625#endif
626 assert(this != &that && "Self-move not supported")(static_cast <bool> (this != &that && "Self-move not supported"
) ? void (0) : __assert_fail ("this != &that && \"Self-move not supported\""
, "llvm/include/llvm/ADT/APInt.h", 626, __extension__ __PRETTY_FUNCTION__
))
;
627 if (!isSingleWord())
628 delete[] U.pVal;
629
630 // Use memcpy so that type based alias analysis sees both VAL and pVal
631 // as modified.
632 memcpy(&U, &that.U, sizeof(U));
633
634 BitWidth = that.BitWidth;
635 that.BitWidth = 0;
636 return *this;
637 }
638
639 /// Assignment operator.
640 ///
641 /// The RHS value is assigned to *this. If the significant bits in RHS exceed
642 /// the bit width, the excess bits are truncated. If the bit width is larger
643 /// than 64, the value is zero filled in the unspecified high order bits.
644 ///
645 /// \returns *this after assignment of RHS value.
646 APInt &operator=(uint64_t RHS) {
647 if (isSingleWord()) {
648 U.VAL = RHS;
649 return clearUnusedBits();
650 }
651 U.pVal[0] = RHS;
652 memset(U.pVal + 1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
653 return *this;
654 }
655
656 /// Bitwise AND assignment operator.
657 ///
658 /// Performs a bitwise AND operation on this APInt and RHS. The result is
659 /// assigned to *this.
660 ///
661 /// \returns *this after ANDing with RHS.
662 APInt &operator&=(const APInt &RHS) {
663 assert(BitWidth == RHS.BitWidth && "Bit widths must be the same")(static_cast <bool> (BitWidth == RHS.BitWidth &&
"Bit widths must be the same") ? void (0) : __assert_fail ("BitWidth == RHS.BitWidth && \"Bit widths must be the same\""
, "llvm/include/llvm/ADT/APInt.h", 663, __extension__ __PRETTY_FUNCTION__
))
;
664 if (isSingleWord())
665 U.VAL &= RHS.U.VAL;
666 else
667 andAssignSlowCase(RHS);
668 return *this;
669 }
670
671 /// Bitwise AND assignment operator.
672 ///
673 /// Performs a bitwise AND operation on this APInt and RHS. RHS is
674 /// logically zero-extended or truncated to match the bit-width of
675 /// the LHS.
676 APInt &operator&=(uint64_t RHS) {
677 if (isSingleWord()) {
678 U.VAL &= RHS;
679 return *this;
680 }
681 U.pVal[0] &= RHS;
682 memset(U.pVal + 1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
683 return *this;
684 }
685
686 /// Bitwise OR assignment operator.
687 ///
688 /// Performs a bitwise OR operation on this APInt and RHS. The result is
689 /// assigned *this;
690 ///
691 /// \returns *this after ORing with RHS.
692 APInt &operator|=(const APInt &RHS) {
693 assert(BitWidth == RHS.BitWidth && "Bit widths must be the same")(static_cast <bool> (BitWidth == RHS.BitWidth &&
"Bit widths must be the same") ? void (0) : __assert_fail ("BitWidth == RHS.BitWidth && \"Bit widths must be the same\""
, "llvm/include/llvm/ADT/APInt.h", 693, __extension__ __PRETTY_FUNCTION__
))
;
694 if (isSingleWord())
695 U.VAL |= RHS.U.VAL;
696 else
697 orAssignSlowCase(RHS);
698 return *this;
699 }
700
701 /// Bitwise OR assignment operator.
702 ///
703 /// Performs a bitwise OR operation on this APInt and RHS. RHS is
704 /// logically zero-extended or truncated to match the bit-width of
705 /// the LHS.
706 APInt &operator|=(uint64_t RHS) {
707 if (isSingleWord()) {
708 U.VAL |= RHS;
709 return clearUnusedBits();
710 }
711 U.pVal[0] |= RHS;
712 return *this;
713 }
714
715 /// Bitwise XOR assignment operator.
716 ///
717 /// Performs a bitwise XOR operation on this APInt and RHS. The result is
718 /// assigned to *this.
719 ///
720 /// \returns *this after XORing with RHS.
721 APInt &operator^=(const APInt &RHS) {
722 assert(BitWidth == RHS.BitWidth && "Bit widths must be the same")(static_cast <bool> (BitWidth == RHS.BitWidth &&
"Bit widths must be the same") ? void (0) : __assert_fail ("BitWidth == RHS.BitWidth && \"Bit widths must be the same\""
, "llvm/include/llvm/ADT/APInt.h", 722, __extension__ __PRETTY_FUNCTION__
))
;
723 if (isSingleWord())
724 U.VAL ^= RHS.U.VAL;
725 else
726 xorAssignSlowCase(RHS);
727 return *this;
728 }
729
730 /// Bitwise XOR assignment operator.
731 ///
732 /// Performs a bitwise XOR operation on this APInt and RHS. RHS is
733 /// logically zero-extended or truncated to match the bit-width of
734 /// the LHS.
735 APInt &operator^=(uint64_t RHS) {
736 if (isSingleWord()) {
737 U.VAL ^= RHS;
738 return clearUnusedBits();
739 }
740 U.pVal[0] ^= RHS;
741 return *this;
742 }
743
744 /// Multiplication assignment operator.
745 ///
746 /// Multiplies this APInt by RHS and assigns the result to *this.
747 ///
748 /// \returns *this
749 APInt &operator*=(const APInt &RHS);
750 APInt &operator*=(uint64_t RHS);
751
752 /// Addition assignment operator.
753 ///
754 /// Adds RHS to *this and assigns the result to *this.
755 ///
756 /// \returns *this
757 APInt &operator+=(const APInt &RHS);
758 APInt &operator+=(uint64_t RHS);
759
760 /// Subtraction assignment operator.
761 ///
762 /// Subtracts RHS from *this and assigns the result to *this.
763 ///
764 /// \returns *this
765 APInt &operator-=(const APInt &RHS);
766 APInt &operator-=(uint64_t RHS);
767
768 /// Left-shift assignment function.
769 ///
770 /// Shifts *this left by shiftAmt and assigns the result to *this.
771 ///
772 /// \returns *this after shifting left by ShiftAmt
773 APInt &operator<<=(unsigned ShiftAmt) {
774 assert(ShiftAmt <= BitWidth && "Invalid shift amount")(static_cast <bool> (ShiftAmt <= BitWidth &&
"Invalid shift amount") ? void (0) : __assert_fail ("ShiftAmt <= BitWidth && \"Invalid shift amount\""
, "llvm/include/llvm/ADT/APInt.h", 774, __extension__ __PRETTY_FUNCTION__
))
;
775 if (isSingleWord()) {
776 if (ShiftAmt == BitWidth)
777 U.VAL = 0;
778 else
779 U.VAL <<= ShiftAmt;
780 return clearUnusedBits();
781 }
782 shlSlowCase(ShiftAmt);
783 return *this;
784 }
785
786 /// Left-shift assignment function.
787 ///
788 /// Shifts *this left by shiftAmt and assigns the result to *this.
789 ///
790 /// \returns *this after shifting left by ShiftAmt
791 APInt &operator<<=(const APInt &ShiftAmt);
792
793 /// @}
794 /// \name Binary Operators
795 /// @{
796
797 /// Multiplication operator.
798 ///
799 /// Multiplies this APInt by RHS and returns the result.
800 APInt operator*(const APInt &RHS) const;
801
802 /// Left logical shift operator.
803 ///
804 /// Shifts this APInt left by \p Bits and returns the result.
805 APInt operator<<(unsigned Bits) const { return shl(Bits); }
806
807 /// Left logical shift operator.
808 ///
809 /// Shifts this APInt left by \p Bits and returns the result.
810 APInt operator<<(const APInt &Bits) const { return shl(Bits); }
811
812 /// Arithmetic right-shift function.
813 ///
814 /// Arithmetic right-shift this APInt by shiftAmt.
815 APInt ashr(unsigned ShiftAmt) const {
816 APInt R(*this);
817 R.ashrInPlace(ShiftAmt);
818 return R;
819 }
820
821 /// Arithmetic right-shift this APInt by ShiftAmt in place.
822 void ashrInPlace(unsigned ShiftAmt) {
823 assert(ShiftAmt <= BitWidth && "Invalid shift amount")(static_cast <bool> (ShiftAmt <= BitWidth &&
"Invalid shift amount") ? void (0) : __assert_fail ("ShiftAmt <= BitWidth && \"Invalid shift amount\""
, "llvm/include/llvm/ADT/APInt.h", 823, __extension__ __PRETTY_FUNCTION__
))
;
824 if (isSingleWord()) {
825 int64_t SExtVAL = SignExtend64(U.VAL, BitWidth);
826 if (ShiftAmt == BitWidth)
827 U.VAL = SExtVAL >> (APINT_BITS_PER_WORD - 1); // Fill with sign bit.
828 else
829 U.VAL = SExtVAL >> ShiftAmt;
830 clearUnusedBits();
831 return;
832 }
833 ashrSlowCase(ShiftAmt);
834 }
835
836 /// Logical right-shift function.
837 ///
838 /// Logical right-shift this APInt by shiftAmt.
839 APInt lshr(unsigned shiftAmt) const {
840 APInt R(*this);
841 R.lshrInPlace(shiftAmt);
842 return R;
843 }
844
845 /// Logical right-shift this APInt by ShiftAmt in place.
846 void lshrInPlace(unsigned ShiftAmt) {
847 assert(ShiftAmt <= BitWidth && "Invalid shift amount")(static_cast <bool> (ShiftAmt <= BitWidth &&
"Invalid shift amount") ? void (0) : __assert_fail ("ShiftAmt <= BitWidth && \"Invalid shift amount\""
, "llvm/include/llvm/ADT/APInt.h", 847, __extension__ __PRETTY_FUNCTION__
))
;
848 if (isSingleWord()) {
849 if (ShiftAmt == BitWidth)
850 U.VAL = 0;
851 else
852 U.VAL >>= ShiftAmt;
853 return;
854 }
855 lshrSlowCase(ShiftAmt);
856 }
857
858 /// Left-shift function.
859 ///
860 /// Left-shift this APInt by shiftAmt.
861 APInt shl(unsigned shiftAmt) const {
862 APInt R(*this);
863 R <<= shiftAmt;
864 return R;
865 }
866
867 /// relative logical shift right
868 APInt relativeLShr(int RelativeShift) const {
869 return RelativeShift > 0 ? lshr(RelativeShift) : shl(-RelativeShift);
870 }
871
872 /// relative logical shift left
873 APInt relativeLShl(int RelativeShift) const {
874 return relativeLShr(-RelativeShift);
875 }
876
877 /// relative arithmetic shift right
878 APInt relativeAShr(int RelativeShift) const {
879 return RelativeShift > 0 ? ashr(RelativeShift) : shl(-RelativeShift);
880 }
881
882 /// relative arithmetic shift left
883 APInt relativeAShl(int RelativeShift) const {
884 return relativeAShr(-RelativeShift);
885 }
886
887 /// Rotate left by rotateAmt.
888 APInt rotl(unsigned rotateAmt) const;
889
890 /// Rotate right by rotateAmt.
891 APInt rotr(unsigned rotateAmt) const;
892
893 /// Arithmetic right-shift function.
894 ///
895 /// Arithmetic right-shift this APInt by shiftAmt.
896 APInt ashr(const APInt &ShiftAmt) const {
897 APInt R(*this);
898 R.ashrInPlace(ShiftAmt);
899 return R;
900 }
901
902 /// Arithmetic right-shift this APInt by shiftAmt in place.
903 void ashrInPlace(const APInt &shiftAmt);
904
905 /// Logical right-shift function.
906 ///
907 /// Logical right-shift this APInt by shiftAmt.
908 APInt lshr(const APInt &ShiftAmt) const {
909 APInt R(*this);
910 R.lshrInPlace(ShiftAmt);
911 return R;
912 }
913
914 /// Logical right-shift this APInt by ShiftAmt in place.
915 void lshrInPlace(const APInt &ShiftAmt);
916
917 /// Left-shift function.
918 ///
919 /// Left-shift this APInt by shiftAmt.
920 APInt shl(const APInt &ShiftAmt) const {
921 APInt R(*this);
922 R <<= ShiftAmt;
923 return R;
924 }
925
926 /// Rotate left by rotateAmt.
927 APInt rotl(const APInt &rotateAmt) const;
928
929 /// Rotate right by rotateAmt.
930 APInt rotr(const APInt &rotateAmt) const;
931
932 /// Concatenate the bits from "NewLSB" onto the bottom of *this. This is
933 /// equivalent to:
934 /// (this->zext(NewWidth) << NewLSB.getBitWidth()) | NewLSB.zext(NewWidth)
935 APInt concat(const APInt &NewLSB) const {
936 /// If the result will be small, then both the merged values are small.
937 unsigned NewWidth = getBitWidth() + NewLSB.getBitWidth();
938 if (NewWidth <= APINT_BITS_PER_WORD)
939 return APInt(NewWidth, (U.VAL << NewLSB.getBitWidth()) | NewLSB.U.VAL);
940 return concatSlowCase(NewLSB);
941 }
942
943 /// Unsigned division operation.
944 ///
945 /// Perform an unsigned divide operation on this APInt by RHS. Both this and
946 /// RHS are treated as unsigned quantities for purposes of this division.
947 ///
948 /// \returns a new APInt value containing the division result, rounded towards
949 /// zero.
950 APInt udiv(const APInt &RHS) const;
951 APInt udiv(uint64_t RHS) const;
952
953 /// Signed division function for APInt.
954 ///
955 /// Signed divide this APInt by APInt RHS.
956 ///
957 /// The result is rounded towards zero.
958 APInt sdiv(const APInt &RHS) const;
959 APInt sdiv(int64_t RHS) const;
960
961 /// Unsigned remainder operation.
962 ///
963 /// Perform an unsigned remainder operation on this APInt with RHS being the
964 /// divisor. Both this and RHS are treated as unsigned quantities for purposes
965 /// of this operation.
966 ///
967 /// \returns a new APInt value containing the remainder result
968 APInt urem(const APInt &RHS) const;
969 uint64_t urem(uint64_t RHS) const;
970
971 /// Function for signed remainder operation.
972 ///
973 /// Signed remainder operation on APInt.
974 ///
975 /// Note that this is a true remainder operation and not a modulo operation
976 /// because the sign follows the sign of the dividend which is *this.
977 APInt srem(const APInt &RHS) const;
978 int64_t srem(int64_t RHS) const;
979
980 /// Dual division/remainder interface.
981 ///
982 /// Sometimes it is convenient to divide two APInt values and obtain both the
983 /// quotient and remainder. This function does both operations in the same
984 /// computation making it a little more efficient. The pair of input arguments
985 /// may overlap with the pair of output arguments. It is safe to call
986 /// udivrem(X, Y, X, Y), for example.
987 static void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient,
988 APInt &Remainder);
989 static void udivrem(const APInt &LHS, uint64_t RHS, APInt &Quotient,
990 uint64_t &Remainder);
991
992 static void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient,
993 APInt &Remainder);
994 static void sdivrem(const APInt &LHS, int64_t RHS, APInt &Quotient,
995 int64_t &Remainder);
996
997 // Operations that return overflow indicators.
998 APInt sadd_ov(const APInt &RHS, bool &Overflow) const;
999 APInt uadd_ov(const APInt &RHS, bool &Overflow) const;
1000 APInt ssub_ov(const APInt &RHS, bool &Overflow) const;
1001 APInt usub_ov(const APInt &RHS, bool &Overflow) const;
1002 APInt sdiv_ov(const APInt &RHS, bool &Overflow) const;
1003 APInt smul_ov(const APInt &RHS, bool &Overflow) const;
1004 APInt umul_ov(const APInt &RHS, bool &Overflow) const;
1005 APInt sshl_ov(const APInt &Amt, bool &Overflow) const;
1006 APInt ushl_ov(const APInt &Amt, bool &Overflow) const;
1007
1008 // Operations that saturate
1009 APInt sadd_sat(const APInt &RHS) const;
1010 APInt uadd_sat(const APInt &RHS) const;
1011 APInt ssub_sat(const APInt &RHS) const;
1012 APInt usub_sat(const APInt &RHS) const;
1013 APInt smul_sat(const APInt &RHS) const;
1014 APInt umul_sat(const APInt &RHS) const;
1015 APInt sshl_sat(const APInt &RHS) const;
1016 APInt ushl_sat(const APInt &RHS) const;
1017
1018 /// Array-indexing support.
1019 ///
1020 /// \returns the bit value at bitPosition
1021 bool operator[](unsigned bitPosition) const {
1022 assert(bitPosition < getBitWidth() && "Bit position out of bounds!")(static_cast <bool> (bitPosition < getBitWidth() &&
"Bit position out of bounds!") ? void (0) : __assert_fail ("bitPosition < getBitWidth() && \"Bit position out of bounds!\""
, "llvm/include/llvm/ADT/APInt.h", 1022, __extension__ __PRETTY_FUNCTION__
))
;
1023 return (maskBit(bitPosition) & getWord(bitPosition)) != 0;
1024 }
1025
1026 /// @}
1027 /// \name Comparison Operators
1028 /// @{
1029
1030 /// Equality operator.
1031 ///
1032 /// Compares this APInt with RHS for the validity of the equality
1033 /// relationship.
1034 bool operator==(const APInt &RHS) const {
1035 assert(BitWidth == RHS.BitWidth && "Comparison requires equal bit widths")(static_cast <bool> (BitWidth == RHS.BitWidth &&
"Comparison requires equal bit widths") ? void (0) : __assert_fail
("BitWidth == RHS.BitWidth && \"Comparison requires equal bit widths\""
, "llvm/include/llvm/ADT/APInt.h", 1035, __extension__ __PRETTY_FUNCTION__
))
;
1036 if (isSingleWord())
1037 return U.VAL == RHS.U.VAL;
1038 return equalSlowCase(RHS);
1039 }
1040
1041 /// Equality operator.
1042 ///
1043 /// Compares this APInt with a uint64_t for the validity of the equality
1044 /// relationship.
1045 ///
1046 /// \returns true if *this == Val
1047 bool operator==(uint64_t Val) const {
1048 return (isSingleWord() || getActiveBits() <= 64) && getZExtValue() == Val;
1049 }
1050
1051 /// Equality comparison.
1052 ///
1053 /// Compares this APInt with RHS for the validity of the equality
1054 /// relationship.
1055 ///
1056 /// \returns true if *this == Val
1057 bool eq(const APInt &RHS) const { return (*this) == RHS; }
1058
1059 /// Inequality operator.
1060 ///
1061 /// Compares this APInt with RHS for the validity of the inequality
1062 /// relationship.
1063 ///
1064 /// \returns true if *this != Val
1065 bool operator!=(const APInt &RHS) const { return !((*this) == RHS); }
1066
1067 /// Inequality operator.
1068 ///
1069 /// Compares this APInt with a uint64_t for the validity of the inequality
1070 /// relationship.
1071 ///
1072 /// \returns true if *this != Val
1073 bool operator!=(uint64_t Val) const { return !((*this) == Val); }
1074
1075 /// Inequality comparison
1076 ///
1077 /// Compares this APInt with RHS for the validity of the inequality
1078 /// relationship.
1079 ///
1080 /// \returns true if *this != Val
1081 bool ne(const APInt &RHS) const { return !((*this) == RHS); }
1082
1083 /// Unsigned less than comparison
1084 ///
1085 /// Regards both *this and RHS as unsigned quantities and compares them for
1086 /// the validity of the less-than relationship.
1087 ///
1088 /// \returns true if *this < RHS when both are considered unsigned.
1089 bool ult(const APInt &RHS) const { return compare(RHS) < 0; }
1090
1091 /// Unsigned less than comparison
1092 ///
1093 /// Regards both *this as an unsigned quantity and compares it with RHS for
1094 /// the validity of the less-than relationship.
1095 ///
1096 /// \returns true if *this < RHS when considered unsigned.
1097 bool ult(uint64_t RHS) const {
1098 // Only need to check active bits if not a single word.
1099 return (isSingleWord() || getActiveBits() <= 64) && getZExtValue() < RHS;
1100 }
1101
1102 /// Signed less than comparison
1103 ///
1104 /// Regards both *this and RHS as signed quantities and compares them for
1105 /// validity of the less-than relationship.
1106 ///
1107 /// \returns true if *this < RHS when both are considered signed.
1108 bool slt(const APInt &RHS) const { return compareSigned(RHS) < 0; }
1109
1110 /// Signed less than comparison
1111 ///
1112 /// Regards both *this as a signed quantity and compares it with RHS for
1113 /// the validity of the less-than relationship.
1114 ///
1115 /// \returns true if *this < RHS when considered signed.
1116 bool slt(int64_t RHS) const {
1117 return (!isSingleWord() && getSignificantBits() > 64)
1118 ? isNegative()
1119 : getSExtValue() < RHS;
1120 }
1121
1122 /// Unsigned less or equal comparison
1123 ///
1124 /// Regards both *this and RHS as unsigned quantities and compares them for
1125 /// validity of the less-or-equal relationship.
1126 ///
1127 /// \returns true if *this <= RHS when both are considered unsigned.
1128 bool ule(const APInt &RHS) const { return compare(RHS) <= 0; }
1129
1130 /// Unsigned less or equal comparison
1131 ///
1132 /// Regards both *this as an unsigned quantity and compares it with RHS for
1133 /// the validity of the less-or-equal relationship.
1134 ///
1135 /// \returns true if *this <= RHS when considered unsigned.
1136 bool ule(uint64_t RHS) const { return !ugt(RHS); }
1137
1138 /// Signed less or equal comparison
1139 ///
1140 /// Regards both *this and RHS as signed quantities and compares them for
1141 /// validity of the less-or-equal relationship.
1142 ///
1143 /// \returns true if *this <= RHS when both are considered signed.
1144 bool sle(const APInt &RHS) const { return compareSigned(RHS) <= 0; }
1145
1146 /// Signed less or equal comparison
1147 ///
1148 /// Regards both *this as a signed quantity and compares it with RHS for the
1149 /// validity of the less-or-equal relationship.
1150 ///
1151 /// \returns true if *this <= RHS when considered signed.
1152 bool sle(uint64_t RHS) const { return !sgt(RHS); }
1153
1154 /// Unsigned greater than comparison
1155 ///
1156 /// Regards both *this and RHS as unsigned quantities and compares them for
1157 /// the validity of the greater-than relationship.
1158 ///
1159 /// \returns true if *this > RHS when both are considered unsigned.
1160 bool ugt(const APInt &RHS) const { return !ule(RHS); }
1161
1162 /// Unsigned greater than comparison
1163 ///
1164 /// Regards both *this as an unsigned quantity and compares it with RHS for
1165 /// the validity of the greater-than relationship.
1166 ///
1167 /// \returns true if *this > RHS when considered unsigned.
1168 bool ugt(uint64_t RHS) const {
1169 // Only need to check active bits if not a single word.
1170 return (!isSingleWord() && getActiveBits() > 64) || getZExtValue() > RHS;
1171 }
1172
1173 /// Signed greater than comparison
1174 ///
1175 /// Regards both *this and RHS as signed quantities and compares them for the
1176 /// validity of the greater-than relationship.
1177 ///
1178 /// \returns true if *this > RHS when both are considered signed.
1179 bool sgt(const APInt &RHS) const { return !sle(RHS); }
1180
1181 /// Signed greater than comparison
1182 ///
1183 /// Regards both *this as a signed quantity and compares it with RHS for
1184 /// the validity of the greater-than relationship.
1185 ///
1186 /// \returns true if *this > RHS when considered signed.
1187 bool sgt(int64_t RHS) const {
1188 return (!isSingleWord() && getSignificantBits() > 64)
1189 ? !isNegative()
1190 : getSExtValue() > RHS;
1191 }
1192
1193 /// Unsigned greater or equal comparison
1194 ///
1195 /// Regards both *this and RHS as unsigned quantities and compares them for
1196 /// validity of the greater-or-equal relationship.
1197 ///
1198 /// \returns true if *this >= RHS when both are considered unsigned.
1199 bool uge(const APInt &RHS) const { return !ult(RHS); }
1200
1201 /// Unsigned greater or equal comparison
1202 ///
1203 /// Regards both *this as an unsigned quantity and compares it with RHS for
1204 /// the validity of the greater-or-equal relationship.
1205 ///
1206 /// \returns true if *this >= RHS when considered unsigned.
1207 bool uge(uint64_t RHS) const { return !ult(RHS); }
1208
1209 /// Signed greater or equal comparison
1210 ///
1211 /// Regards both *this and RHS as signed quantities and compares them for
1212 /// validity of the greater-or-equal relationship.
1213 ///
1214 /// \returns true if *this >= RHS when both are considered signed.
1215 bool sge(const APInt &RHS) const { return !slt(RHS); }
1216
1217 /// Signed greater or equal comparison
1218 ///
1219 /// Regards both *this as a signed quantity and compares it with RHS for
1220 /// the validity of the greater-or-equal relationship.
1221 ///
1222 /// \returns true if *this >= RHS when considered signed.
1223 bool sge(int64_t RHS) const { return !slt(RHS); }
1224
1225 /// This operation tests if there are any pairs of corresponding bits
1226 /// between this APInt and RHS that are both set.
1227 bool intersects(const APInt &RHS) const {
1228 assert(BitWidth == RHS.BitWidth && "Bit widths must be the same")(static_cast <bool> (BitWidth == RHS.BitWidth &&
"Bit widths must be the same") ? void (0) : __assert_fail ("BitWidth == RHS.BitWidth && \"Bit widths must be the same\""
, "llvm/include/llvm/ADT/APInt.h", 1228, __extension__ __PRETTY_FUNCTION__
))
;
1229 if (isSingleWord())
1230 return (U.VAL & RHS.U.VAL) != 0;
1231 return intersectsSlowCase(RHS);
1232 }
1233
1234 /// This operation checks that all bits set in this APInt are also set in RHS.
1235 bool isSubsetOf(const APInt &RHS) const {
1236 assert(BitWidth == RHS.BitWidth && "Bit widths must be the same")(static_cast <bool> (BitWidth == RHS.BitWidth &&
"Bit widths must be the same") ? void (0) : __assert_fail ("BitWidth == RHS.BitWidth && \"Bit widths must be the same\""
, "llvm/include/llvm/ADT/APInt.h", 1236, __extension__ __PRETTY_FUNCTION__
))
;
1237 if (isSingleWord())
1238 return (U.VAL & ~RHS.U.VAL) == 0;
1239 return isSubsetOfSlowCase(RHS);
1240 }
1241
1242 /// @}
1243 /// \name Resizing Operators
1244 /// @{
1245
1246 /// Truncate to new width.
1247 ///
1248 /// Truncate the APInt to a specified width. It is an error to specify a width
1249 /// that is greater than the current width.
1250 APInt trunc(unsigned width) const;
1251
1252 /// Truncate to new width with unsigned saturation.
1253 ///
1254 /// If the APInt, treated as unsigned integer, can be losslessly truncated to
1255 /// the new bitwidth, then return truncated APInt. Else, return max value.
1256 APInt truncUSat(unsigned width) const;
1257
1258 /// Truncate to new width with signed saturation.
1259 ///
1260 /// If this APInt, treated as signed integer, can be losslessly truncated to
1261 /// the new bitwidth, then return truncated APInt. Else, return either
1262 /// signed min value if the APInt was negative, or signed max value.
1263 APInt truncSSat(unsigned width) const;
1264
1265 /// Sign extend to a new width.
1266 ///
1267 /// This operation sign extends the APInt to a new width. If the high order
1268 /// bit is set, the fill on the left will be done with 1 bits, otherwise zero.
1269 /// It is an error to specify a width that is less than the
1270 /// current width.
1271 APInt sext(unsigned width) const;
1272
1273 /// Zero extend to a new width.
1274 ///
1275 /// This operation zero extends the APInt to a new width. The high order bits
1276 /// are filled with 0 bits. It is an error to specify a width that is less
1277 /// than the current width.
1278 APInt zext(unsigned width) const;
1279
1280 /// Sign extend or truncate to width
1281 ///
1282 /// Make this APInt have the bit width given by \p width. The value is sign
1283 /// extended, truncated, or left alone to make it that width.
1284 APInt sextOrTrunc(unsigned width) const;
1285
1286 /// Zero extend or truncate to width
1287 ///
1288 /// Make this APInt have the bit width given by \p width. The value is zero
1289 /// extended, truncated, or left alone to make it that width.
1290 APInt zextOrTrunc(unsigned width) const;
1291
1292 /// @}
1293 /// \name Bit Manipulation Operators
1294 /// @{
1295
1296 /// Set every bit to 1.
1297 void setAllBits() {
1298 if (isSingleWord())
1299 U.VAL = WORDTYPE_MAX;
1300 else
1301 // Set all the bits in all the words.
1302 memset(U.pVal, -1, getNumWords() * APINT_WORD_SIZE);
1303 // Clear the unused ones
1304 clearUnusedBits();
1305 }
1306
1307 /// Set the given bit to 1 whose position is given as "bitPosition".
1308 void setBit(unsigned BitPosition) {
1309 assert(BitPosition < BitWidth && "BitPosition out of range")(static_cast <bool> (BitPosition < BitWidth &&
"BitPosition out of range") ? void (0) : __assert_fail ("BitPosition < BitWidth && \"BitPosition out of range\""
, "llvm/include/llvm/ADT/APInt.h", 1309, __extension__ __PRETTY_FUNCTION__
))
;
1310 WordType Mask = maskBit(BitPosition);
1311 if (isSingleWord())
1312 U.VAL |= Mask;
1313 else
1314 U.pVal[whichWord(BitPosition)] |= Mask;
1315 }
1316
1317 /// Set the sign bit to 1.
1318 void setSignBit() { setBit(BitWidth - 1); }
1319
1320 /// Set a given bit to a given value.
1321 void setBitVal(unsigned BitPosition, bool BitValue) {
1322 if (BitValue)
1323 setBit(BitPosition);
1324 else
1325 clearBit(BitPosition);
1326 }
1327
1328 /// Set the bits from loBit (inclusive) to hiBit (exclusive) to 1.
1329 /// This function handles "wrap" case when \p loBit >= \p hiBit, and calls
1330 /// setBits when \p loBit < \p hiBit.
1331 /// For \p loBit == \p hiBit wrap case, set every bit to 1.
1332 void setBitsWithWrap(unsigned loBit, unsigned hiBit) {
1333 assert(hiBit <= BitWidth && "hiBit out of range")(static_cast <bool> (hiBit <= BitWidth && "hiBit out of range"
) ? void (0) : __assert_fail ("hiBit <= BitWidth && \"hiBit out of range\""
, "llvm/include/llvm/ADT/APInt.h", 1333, __extension__ __PRETTY_FUNCTION__
))
;
1334 assert(loBit <= BitWidth && "loBit out of range")(static_cast <bool> (loBit <= BitWidth && "loBit out of range"
) ? void (0) : __assert_fail ("loBit <= BitWidth && \"loBit out of range\""
, "llvm/include/llvm/ADT/APInt.h", 1334, __extension__ __PRETTY_FUNCTION__
))
;
1335 if (loBit < hiBit) {
1336 setBits(loBit, hiBit);
1337 return;
1338 }
1339 setLowBits(hiBit);
1340 setHighBits(BitWidth - loBit);
1341 }
1342
1343 /// Set the bits from loBit (inclusive) to hiBit (exclusive) to 1.
1344 /// This function handles case when \p loBit <= \p hiBit.
1345 void setBits(unsigned loBit, unsigned hiBit) {
1346 assert(hiBit <= BitWidth && "hiBit out of range")(static_cast <bool> (hiBit <= BitWidth && "hiBit out of range"
) ? void (0) : __assert_fail ("hiBit <= BitWidth && \"hiBit out of range\""
, "llvm/include/llvm/ADT/APInt.h", 1346, __extension__ __PRETTY_FUNCTION__
))
;
1347 assert(loBit <= BitWidth && "loBit out of range")(static_cast <bool> (loBit <= BitWidth && "loBit out of range"
) ? void (0) : __assert_fail ("loBit <= BitWidth && \"loBit out of range\""
, "llvm/include/llvm/ADT/APInt.h", 1347, __extension__ __PRETTY_FUNCTION__
))
;
1348 assert(loBit <= hiBit && "loBit greater than hiBit")(static_cast <bool> (loBit <= hiBit && "loBit greater than hiBit"
) ? void (0) : __assert_fail ("loBit <= hiBit && \"loBit greater than hiBit\""
, "llvm/include/llvm/ADT/APInt.h", 1348, __extension__ __PRETTY_FUNCTION__
))
;
1349 if (loBit == hiBit)
1350 return;
1351 if (loBit < APINT_BITS_PER_WORD && hiBit <= APINT_BITS_PER_WORD) {
1352 uint64_t mask = WORDTYPE_MAX >> (APINT_BITS_PER_WORD - (hiBit - loBit));
1353 mask <<= loBit;
1354 if (isSingleWord())
1355 U.VAL |= mask;
1356 else
1357 U.pVal[0] |= mask;
1358 } else {
1359 setBitsSlowCase(loBit, hiBit);
1360 }
1361 }
1362
1363 /// Set the top bits starting from loBit.
1364 void setBitsFrom(unsigned loBit) { return setBits(loBit, BitWidth); }
1365
1366 /// Set the bottom loBits bits.
1367 void setLowBits(unsigned loBits) { return setBits(0, loBits); }
1368
1369 /// Set the top hiBits bits.
1370 void setHighBits(unsigned hiBits) {
1371 return setBits(BitWidth - hiBits, BitWidth);
1372 }
1373
1374 /// Set every bit to 0.
1375 void clearAllBits() {
1376 if (isSingleWord())
1377 U.VAL = 0;
1378 else
1379 memset(U.pVal, 0, getNumWords() * APINT_WORD_SIZE);
1380 }
1381
1382 /// Set a given bit to 0.
1383 ///
1384 /// Set the given bit to 0 whose position is given as "bitPosition".
1385 void clearBit(unsigned BitPosition) {
1386 assert(BitPosition < BitWidth && "BitPosition out of range")(static_cast <bool> (BitPosition < BitWidth &&
"BitPosition out of range") ? void (0) : __assert_fail ("BitPosition < BitWidth && \"BitPosition out of range\""
, "llvm/include/llvm/ADT/APInt.h", 1386, __extension__ __PRETTY_FUNCTION__
))
;
1387 WordType Mask = ~maskBit(BitPosition);
1388 if (isSingleWord())
1389 U.VAL &= Mask;
1390 else
1391 U.pVal[whichWord(BitPosition)] &= Mask;
1392 }
1393
1394 /// Set bottom loBits bits to 0.
1395 void clearLowBits(unsigned loBits) {
1396 assert(loBits <= BitWidth && "More bits than bitwidth")(static_cast <bool> (loBits <= BitWidth && "More bits than bitwidth"
) ? void (0) : __assert_fail ("loBits <= BitWidth && \"More bits than bitwidth\""
, "llvm/include/llvm/ADT/APInt.h", 1396, __extension__ __PRETTY_FUNCTION__
))
;
1397 APInt Keep = getHighBitsSet(BitWidth, BitWidth - loBits);
1398 *this &= Keep;
1399 }
1400
1401 /// Set the sign bit to 0.
1402 void clearSignBit() { clearBit(BitWidth - 1); }
1403
1404 /// Toggle every bit to its opposite value.
1405 void flipAllBits() {
1406 if (isSingleWord()) {
1407 U.VAL ^= WORDTYPE_MAX;
1408 clearUnusedBits();
1409 } else {
1410 flipAllBitsSlowCase();
1411 }
1412 }
1413
1414 /// Toggles a given bit to its opposite value.
1415 ///
1416 /// Toggle a given bit to its opposite value whose position is given
1417 /// as "bitPosition".
1418 void flipBit(unsigned bitPosition);
1419
1420 /// Negate this APInt in place.
1421 void negate() {
1422 flipAllBits();
1423 ++(*this);
1424 }
1425
1426 /// Insert the bits from a smaller APInt starting at bitPosition.
1427 void insertBits(const APInt &SubBits, unsigned bitPosition);
1428 void insertBits(uint64_t SubBits, unsigned bitPosition, unsigned numBits);
1429
1430 /// Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
1431 APInt extractBits(unsigned numBits, unsigned bitPosition) const;
1432 uint64_t extractBitsAsZExtValue(unsigned numBits, unsigned bitPosition) const;
1433
1434 /// @}
1435 /// \name Value Characterization Functions
1436 /// @{
1437
1438 /// Return the number of bits in the APInt.
1439 unsigned getBitWidth() const { return BitWidth; }
1440
1441 /// Get the number of words.
1442 ///
1443 /// Here one word's bitwidth equals to that of uint64_t.
1444 ///
1445 /// \returns the number of words to hold the integer value of this APInt.
1446 unsigned getNumWords() const { return getNumWords(BitWidth); }
1447
1448 /// Get the number of words.
1449 ///
1450 /// *NOTE* Here one word's bitwidth equals to that of uint64_t.
1451 ///
1452 /// \returns the number of words to hold the integer value with a given bit
1453 /// width.
1454 static unsigned getNumWords(unsigned BitWidth) {
1455 return ((uint64_t)BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
1456 }
1457
1458 /// Compute the number of active bits in the value
1459 ///
1460 /// This function returns the number of active bits which is defined as the
1461 /// bit width minus the number of leading zeros. This is used in several
1462 /// computations to see how "wide" the value is.
1463 unsigned getActiveBits() const { return BitWidth - countl_zero(); }
1464
1465 /// Compute the number of active words in the value of this APInt.
1466 ///
1467 /// This is used in conjunction with getActiveData to extract the raw value of
1468 /// the APInt.
1469 unsigned getActiveWords() const {
1470 unsigned numActiveBits = getActiveBits();
1471 return numActiveBits ? whichWord(numActiveBits - 1) + 1 : 1;
1472 }
1473
1474 /// Get the minimum bit size for this signed APInt
1475 ///
1476 /// Computes the minimum bit width for this APInt while considering it to be a
1477 /// signed (and probably negative) value. If the value is not negative, this
1478 /// function returns the same value as getActiveBits()+1. Otherwise, it
1479 /// returns the smallest bit width that will retain the negative value. For
1480 /// example, -1 can be written as 0b1 or 0xFFFFFFFFFF. 0b1 is shorter and so
1481 /// for -1, this function will always return 1.
1482 unsigned getSignificantBits() const {
1483 return BitWidth - getNumSignBits() + 1;
1484 }
1485
1486 LLVM_DEPRECATED("use getSignificantBits instead", "getSignificantBits")__attribute__((deprecated("use getSignificantBits instead", "getSignificantBits"
)))
1487 unsigned getMinSignedBits() const { return getSignificantBits(); }
1488
1489 /// Get zero extended value
1490 ///
1491 /// This method attempts to return the value of this APInt as a zero extended
1492 /// uint64_t. The bitwidth must be <= 64 or the value must fit within a
1493 /// uint64_t. Otherwise an assertion will result.
1494 uint64_t getZExtValue() const {
1495 if (isSingleWord())
1496 return U.VAL;
1497 assert(getActiveBits() <= 64 && "Too many bits for uint64_t")(static_cast <bool> (getActiveBits() <= 64 &&
"Too many bits for uint64_t") ? void (0) : __assert_fail ("getActiveBits() <= 64 && \"Too many bits for uint64_t\""
, "llvm/include/llvm/ADT/APInt.h", 1497, __extension__ __PRETTY_FUNCTION__
))
;
1498 return U.pVal[0];
1499 }
1500
1501 /// Get zero extended value if possible
1502 ///
1503 /// This method attempts to return the value of this APInt as a zero extended
1504 /// uint64_t. The bitwidth must be <= 64 or the value must fit within a
1505 /// uint64_t. Otherwise no value is returned.
1506 std::optional<uint64_t> tryZExtValue() const {
1507 return (getActiveBits() <= 64) ? std::optional<uint64_t>(getZExtValue())
1508 : std::nullopt;
1509 };
1510
1511 /// Get sign extended value
1512 ///
1513 /// This method attempts to return the value of this APInt as a sign extended
1514 /// int64_t. The bit width must be <= 64 or the value must fit within an
1515 /// int64_t. Otherwise an assertion will result.
1516 int64_t getSExtValue() const {
1517 if (isSingleWord())
1518 return SignExtend64(U.VAL, BitWidth);
1519 assert(getSignificantBits() <= 64 && "Too many bits for int64_t")(static_cast <bool> (getSignificantBits() <= 64 &&
"Too many bits for int64_t") ? void (0) : __assert_fail ("getSignificantBits() <= 64 && \"Too many bits for int64_t\""
, "llvm/include/llvm/ADT/APInt.h", 1519, __extension__ __PRETTY_FUNCTION__
))
;
1520 return int64_t(U.pVal[0]);
1521 }
1522
1523 /// Get sign extended value if possible
1524 ///
1525 /// This method attempts to return the value of this APInt as a sign extended
1526 /// int64_t. The bitwidth must be <= 64 or the value must fit within an
1527 /// int64_t. Otherwise no value is returned.
1528 std::optional<int64_t> trySExtValue() const {
1529 return (getSignificantBits() <= 64) ? std::optional<int64_t>(getSExtValue())
1530 : std::nullopt;
1531 };
1532
1533 /// Get bits required for string value.
1534 ///
1535 /// This method determines how many bits are required to hold the APInt
1536 /// equivalent of the string given by \p str.
1537 static unsigned getBitsNeeded(StringRef str, uint8_t radix);
1538
1539 /// Get the bits that are sufficient to represent the string value. This may
1540 /// over estimate the amount of bits required, but it does not require
1541 /// parsing the value in the string.
1542 static unsigned getSufficientBitsNeeded(StringRef Str, uint8_t Radix);
1543
1544 /// The APInt version of std::countl_zero.
1545 ///
1546 /// It counts the number of zeros from the most significant bit to the first
1547 /// one bit.
1548 ///
1549 /// \returns BitWidth if the value is zero, otherwise returns the number of
1550 /// zeros from the most significant bit to the first one bits.
1551 unsigned countl_zero() const {
1552 if (isSingleWord()) {
1553 unsigned unusedBits = APINT_BITS_PER_WORD - BitWidth;
1554 return llvm::countl_zero(U.VAL) - unusedBits;
1555 }
1556 return countLeadingZerosSlowCase();
1557 }
1558
1559 unsigned countLeadingZeros() const { return countl_zero(); }
1560
1561 /// Count the number of leading one bits.
1562 ///
1563 /// This function is an APInt version of std::countl_one. It counts the number
1564 /// of ones from the most significant bit to the first zero bit.
1565 ///
1566 /// \returns 0 if the high order bit is not set, otherwise returns the number
1567 /// of 1 bits from the most significant to the least
1568 unsigned countl_one() const {
1569 if (isSingleWord()) {
1570 if (LLVM_UNLIKELY(BitWidth == 0)__builtin_expect((bool)(BitWidth == 0), false))
1571 return 0;
1572 return llvm::countl_one(U.VAL << (APINT_BITS_PER_WORD - BitWidth));
1573 }
1574 return countLeadingOnesSlowCase();
1575 }
1576
1577 unsigned countLeadingOnes() const { return countl_one(); }
1578
1579 /// Computes the number of leading bits of this APInt that are equal to its
1580 /// sign bit.
1581 unsigned getNumSignBits() const {
1582 return isNegative() ? countl_one() : countl_zero();
1583 }
1584
1585 /// Count the number of trailing zero bits.
1586 ///
1587 /// This function is an APInt version of std::countr_zero. It counts the number
1588 /// of zeros from the least significant bit to the first set bit.
1589 ///
1590 /// \returns BitWidth if the value is zero, otherwise returns the number of
1591 /// zeros from the least significant bit to the first one bit.
1592 unsigned countr_zero() const {
1593 if (isSingleWord()) {
1594 unsigned TrailingZeros = llvm::countr_zero(U.VAL);
1595 return (TrailingZeros > BitWidth ? BitWidth : TrailingZeros);
1596 }
1597 return countTrailingZerosSlowCase();
1598 }
1599
1600 unsigned countTrailingZeros() const { return countr_zero(); }
1601
1602 /// Count the number of trailing one bits.
1603 ///
1604 /// This function is an APInt version of std::countr_one. It counts the number
1605 /// of ones from the least significant bit to the first zero bit.
1606 ///
1607 /// \returns BitWidth if the value is all ones, otherwise returns the number
1608 /// of ones from the least significant bit to the first zero bit.
1609 unsigned countr_one() const {
1610 if (isSingleWord())
1611 return llvm::countr_one(U.VAL);
1612 return countTrailingOnesSlowCase();
1613 }
1614
1615 unsigned countTrailingOnes() const { return countr_one(); }
1616
1617 /// Count the number of bits set.
1618 ///
1619 /// This function is an APInt version of std::popcount. It counts the number
1620 /// of 1 bits in the APInt value.
1621 ///
1622 /// \returns 0 if the value is zero, otherwise returns the number of set bits.
1623 unsigned popcount() const {
1624 if (isSingleWord())
1625 return llvm::popcount(U.VAL);
1626 return countPopulationSlowCase();
1627 }
1628
1629 LLVM_DEPRECATED("use popcount instead", "popcount")__attribute__((deprecated("use popcount instead", "popcount")
))
1630 unsigned countPopulation() const { return popcount(); }
1631
1632 /// @}
1633 /// \name Conversion Functions
1634 /// @{
1635 void print(raw_ostream &OS, bool isSigned) const;
1636
1637 /// Converts an APInt to a string and append it to Str. Str is commonly a
1638 /// SmallString.
1639 void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
1640 bool formatAsCLiteral = false) const;
1641
1642 /// Considers the APInt to be unsigned and converts it into a string in the
1643 /// radix given. The radix can be 2, 8, 10 16, or 36.
1644 void toStringUnsigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
1645 toString(Str, Radix, false, false);
1646 }
1647
1648 /// Considers the APInt to be signed and converts it into a string in the
1649 /// radix given. The radix can be 2, 8, 10, 16, or 36.
1650 void toStringSigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
1651 toString(Str, Radix, true, false);
1652 }
1653
1654 /// \returns a byte-swapped representation of this APInt Value.
1655 APInt byteSwap() const;
1656
1657 /// \returns the value with the bit representation reversed of this APInt
1658 /// Value.
1659 APInt reverseBits() const;
1660
1661 /// Converts this APInt to a double value.
1662 double roundToDouble(bool isSigned) const;
1663
1664 /// Converts this unsigned APInt to a double value.
1665 double roundToDouble() const { return roundToDouble(false); }
1666
1667 /// Converts this signed APInt to a double value.
1668 double signedRoundToDouble() const { return roundToDouble(true); }
1669
1670 /// Converts APInt bits to a double
1671 ///
1672 /// The conversion does not do a translation from integer to double, it just
1673 /// re-interprets the bits as a double. Note that it is valid to do this on
1674 /// any bit width. Exactly 64 bits will be translated.
1675 double bitsToDouble() const { return llvm::bit_cast<double>(getWord(0)); }
1676
1677 /// Converts APInt bits to a float
1678 ///
1679 /// The conversion does not do a translation from integer to float, it just
1680 /// re-interprets the bits as a float. Note that it is valid to do this on
1681 /// any bit width. Exactly 32 bits will be translated.
1682 float bitsToFloat() const {
1683 return llvm::bit_cast<float>(static_cast<uint32_t>(getWord(0)));
1684 }
1685
1686 /// Converts a double to APInt bits.
1687 ///
1688 /// The conversion does not do a translation from double to integer, it just
1689 /// re-interprets the bits of the double.
1690 static APInt doubleToBits(double V) {
1691 return APInt(sizeof(double) * CHAR_BIT8, llvm::bit_cast<uint64_t>(V));
1692 }
1693
1694 /// Converts a float to APInt bits.
1695 ///
1696 /// The conversion does not do a translation from float to integer, it just
1697 /// re-interprets the bits of the float.
1698 static APInt floatToBits(float V) {
1699 return APInt(sizeof(float) * CHAR_BIT8, llvm::bit_cast<uint32_t>(V));
1700 }
1701
1702 /// @}
1703 /// \name Mathematics Operations
1704 /// @{
1705
1706 /// \returns the floor log base 2 of this APInt.
1707 unsigned logBase2() const { return getActiveBits() - 1; }
1708
1709 /// \returns the ceil log base 2 of this APInt.
1710 unsigned ceilLogBase2() const {
1711 APInt temp(*this);
1712 --temp;
1713 return temp.getActiveBits();
1714 }
1715
1716 /// \returns the nearest log base 2 of this APInt. Ties round up.
1717 ///
1718 /// NOTE: When we have a BitWidth of 1, we define:
1719 ///
1720 /// log2(0) = UINT32_MAX
1721 /// log2(1) = 0
1722 ///
1723 /// to get around any mathematical concerns resulting from
1724 /// referencing 2 in a space where 2 does no exist.
1725 unsigned nearestLogBase2() const;
1726
1727 /// \returns the log base 2 of this APInt if its an exact power of two, -1
1728 /// otherwise
1729 int32_t exactLogBase2() const {
1730 if (!isPowerOf2())
1731 return -1;
1732 return logBase2();
1733 }
1734
1735 /// Compute the square root.
1736 APInt sqrt() const;
1737
1738 /// Get the absolute value. If *this is < 0 then return -(*this), otherwise
1739 /// *this. Note that the "most negative" signed number (e.g. -128 for 8 bit
1740 /// wide APInt) is unchanged due to how negation works.
1741 APInt abs() const {
1742 if (isNegative())
1743 return -(*this);
1744 return *this;
1745 }
1746
1747 /// \returns the multiplicative inverse for a given modulo.
1748 APInt multiplicativeInverse(const APInt &modulo) const;
1749
1750 /// @}
1751 /// \name Building-block Operations for APInt and APFloat
1752 /// @{
1753
1754 // These building block operations operate on a representation of arbitrary
1755 // precision, two's-complement, bignum integer values. They should be
1756 // sufficient to implement APInt and APFloat bignum requirements. Inputs are
1757 // generally a pointer to the base of an array of integer parts, representing
1758 // an unsigned bignum, and a count of how many parts there are.
1759
1760 /// Sets the least significant part of a bignum to the input value, and zeroes
1761 /// out higher parts.
1762 static void tcSet(WordType *, WordType, unsigned);
1763
1764 /// Assign one bignum to another.
1765 static void tcAssign(WordType *, const WordType *, unsigned);
1766
1767 /// Returns true if a bignum is zero, false otherwise.
1768 static bool tcIsZero(const WordType *, unsigned);
1769
1770 /// Extract the given bit of a bignum; returns 0 or 1. Zero-based.
1771 static int tcExtractBit(const WordType *, unsigned bit);
1772
1773 /// Copy the bit vector of width srcBITS from SRC, starting at bit srcLSB, to
1774 /// DST, of dstCOUNT parts, such that the bit srcLSB becomes the least
1775 /// significant bit of DST. All high bits above srcBITS in DST are
1776 /// zero-filled.
1777 static void tcExtract(WordType *, unsigned dstCount, const WordType *,
1778 unsigned srcBits, unsigned srcLSB);
1779
1780 /// Set the given bit of a bignum. Zero-based.
1781 static void tcSetBit(WordType *, unsigned bit);
1782
1783 /// Clear the given bit of a bignum. Zero-based.
1784 static void tcClearBit(WordType *, unsigned bit);
1785
1786 /// Returns the bit number of the least or most significant set bit of a
1787 /// number. If the input number has no bits set -1U is returned.
1788 static unsigned tcLSB(const WordType *, unsigned n);
1789 static unsigned tcMSB(const WordType *parts, unsigned n);
1790
1791 /// Negate a bignum in-place.
1792 static void tcNegate(WordType *, unsigned);
1793
1794 /// DST += RHS + CARRY where CARRY is zero or one. Returns the carry flag.
1795 static WordType tcAdd(WordType *, const WordType *, WordType carry, unsigned);
1796 /// DST += RHS. Returns the carry flag.
1797 static WordType tcAddPart(WordType *, WordType, unsigned);
1798
1799 /// DST -= RHS + CARRY where CARRY is zero or one. Returns the carry flag.
1800 static WordType tcSubtract(WordType *, const WordType *, WordType carry,
1801 unsigned);
1802 /// DST -= RHS. Returns the carry flag.
1803 static WordType tcSubtractPart(WordType *, WordType, unsigned);
1804
1805 /// DST += SRC * MULTIPLIER + PART if add is true
1806 /// DST = SRC * MULTIPLIER + PART if add is false
1807 ///
1808 /// Requires 0 <= DSTPARTS <= SRCPARTS + 1. If DST overlaps SRC they must
1809 /// start at the same point, i.e. DST == SRC.
1810 ///
1811 /// If DSTPARTS == SRC_PARTS + 1 no overflow occurs and zero is returned.
1812 /// Otherwise DST is filled with the least significant DSTPARTS parts of the
1813 /// result, and if all of the omitted higher parts were zero return zero,
1814 /// otherwise overflow occurred and return one.
1815 static int tcMultiplyPart(WordType *dst, const WordType *src,
1816 WordType multiplier, WordType carry,
1817 unsigned srcParts, unsigned dstParts, bool add);
1818
1819 /// DST = LHS * RHS, where DST has the same width as the operands and is
1820 /// filled with the least significant parts of the result. Returns one if
1821 /// overflow occurred, otherwise zero. DST must be disjoint from both
1822 /// operands.
1823 static int tcMultiply(WordType *, const WordType *, const WordType *,
1824 unsigned);
1825
1826 /// DST = LHS * RHS, where DST has width the sum of the widths of the
1827 /// operands. No overflow occurs. DST must be disjoint from both operands.
1828 static void tcFullMultiply(WordType *, const WordType *, const WordType *,
1829 unsigned, unsigned);
1830
1831 /// If RHS is zero LHS and REMAINDER are left unchanged, return one.
1832 /// Otherwise set LHS to LHS / RHS with the fractional part discarded, set
1833 /// REMAINDER to the remainder, return zero. i.e.
1834 ///
1835 /// OLD_LHS = RHS * LHS + REMAINDER
1836 ///
1837 /// SCRATCH is a bignum of the same size as the operands and result for use by
1838 /// the routine; its contents need not be initialized and are destroyed. LHS,
1839 /// REMAINDER and SCRATCH must be distinct.
1840 static int tcDivide(WordType *lhs, const WordType *rhs, WordType *remainder,
1841 WordType *scratch, unsigned parts);
1842
1843 /// Shift a bignum left Count bits. Shifted in bits are zero. There are no
1844 /// restrictions on Count.
1845 static void tcShiftLeft(WordType *, unsigned Words, unsigned Count);
1846
1847 /// Shift a bignum right Count bits. Shifted in bits are zero. There are no
1848 /// restrictions on Count.
1849 static void tcShiftRight(WordType *, unsigned Words, unsigned Count);
1850
1851 /// Comparison (unsigned) of two bignums.
1852 static int tcCompare(const WordType *, const WordType *, unsigned);
1853
1854 /// Increment a bignum in-place. Return the carry flag.
1855 static WordType tcIncrement(WordType *dst, unsigned parts) {
1856 return tcAddPart(dst, 1, parts);
1857 }
1858
1859 /// Decrement a bignum in-place. Return the borrow flag.
1860 static WordType tcDecrement(WordType *dst, unsigned parts) {
1861 return tcSubtractPart(dst, 1, parts);
1862 }
1863
1864 /// Used to insert APInt objects, or objects that contain APInt objects, into
1865 /// FoldingSets.
1866 void Profile(FoldingSetNodeID &id) const;
1867
1868 /// debug method
1869 void dump() const;
1870
1871 /// Returns whether this instance allocated memory.
1872 bool needsCleanup() const { return !isSingleWord(); }
1873
1874private:
1875 /// This union is used to store the integer value. When the
1876 /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal.
1877 union {
1878 uint64_t VAL; ///< Used to store the <= 64 bits integer value.
1879 uint64_t *pVal; ///< Used to store the >64 bits integer value.
1880 } U;
1881
1882 unsigned BitWidth = 1; ///< The number of bits in this APInt.
1883
1884 friend struct DenseMapInfo<APInt, void>;
1885 friend class APSInt;
1886
1887 /// This constructor is used only internally for speed of construction of
1888 /// temporaries. It is unsafe since it takes ownership of the pointer, so it
1889 /// is not public.
1890 APInt(uint64_t *val, unsigned bits) : BitWidth(bits) { U.pVal = val; }
1891
1892 /// Determine which word a bit is in.
1893 ///
1894 /// \returns the word position for the specified bit position.
1895 static unsigned whichWord(unsigned bitPosition) {
1896 return bitPosition / APINT_BITS_PER_WORD;
1897 }
1898
1899 /// Determine which bit in a word the specified bit position is in.
1900 static unsigned whichBit(unsigned bitPosition) {
1901 return bitPosition % APINT_BITS_PER_WORD;
1902 }
1903
1904 /// Get a single bit mask.
1905 ///
1906 /// \returns a uint64_t with only bit at "whichBit(bitPosition)" set
1907 /// This method generates and returns a uint64_t (word) mask for a single
1908 /// bit at a specific bit position. This is used to mask the bit in the
1909 /// corresponding word.
1910 static uint64_t maskBit(unsigned bitPosition) {
1911 return 1ULL << whichBit(bitPosition);
1912 }
1913
1914 /// Clear unused high order bits
1915 ///
1916 /// This method is used internally to clear the top "N" bits in the high order
1917 /// word that are not used by the APInt. This is needed after the most
1918 /// significant word is assigned a value to ensure that those bits are
1919 /// zero'd out.
1920 APInt &clearUnusedBits() {
1921 // Compute how many bits are used in the final word.
1922 unsigned WordBits = ((BitWidth - 1) % APINT_BITS_PER_WORD) + 1;
1923
1924 // Mask out the high bits.
1925 uint64_t mask = WORDTYPE_MAX >> (APINT_BITS_PER_WORD - WordBits);
1926 if (LLVM_UNLIKELY(BitWidth == 0)__builtin_expect((bool)(BitWidth == 0), false))
1927 mask = 0;
1928
1929 if (isSingleWord())
1930 U.VAL &= mask;
1931 else
1932 U.pVal[getNumWords() - 1] &= mask;
1933 return *this;
1934 }
1935
1936 /// Get the word corresponding to a bit position
1937 /// \returns the corresponding word for the specified bit position.
1938 uint64_t getWord(unsigned bitPosition) const {
1939 return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)];
1940 }
1941
1942 /// Utility method to change the bit width of this APInt to new bit width,
1943 /// allocating and/or deallocating as necessary. There is no guarantee on the
1944 /// value of any bits upon return. Caller should populate the bits after.
1945 void reallocate(unsigned NewBitWidth);
1946
1947 /// Convert a char array into an APInt
1948 ///
1949 /// \param radix 2, 8, 10, 16, or 36
1950 /// Converts a string into a number. The string must be non-empty
1951 /// and well-formed as a number of the given base. The bit-width
1952 /// must be sufficient to hold the result.
1953 ///
1954 /// This is used by the constructors that take string arguments.
1955 ///
1956 /// StringRef::getAsInteger is superficially similar but (1) does
1957 /// not assume that the string is well-formed and (2) grows the
1958 /// result to hold the input.
1959 void fromString(unsigned numBits, StringRef str, uint8_t radix);
1960
1961 /// An internal division function for dividing APInts.
1962 ///
1963 /// This is used by the toString method to divide by the radix. It simply
1964 /// provides a more convenient form of divide for internal use since KnuthDiv
1965 /// has specific constraints on its inputs. If those constraints are not met
1966 /// then it provides a simpler form of divide.
1967 static void divide(const WordType *LHS, unsigned lhsWords,
1968 const WordType *RHS, unsigned rhsWords, WordType *Quotient,
1969 WordType *Remainder);
1970
1971 /// out-of-line slow case for inline constructor
1972 void initSlowCase(uint64_t val, bool isSigned);
1973
1974 /// shared code between two array constructors
1975 void initFromArray(ArrayRef<uint64_t> array);
1976
1977 /// out-of-line slow case for inline copy constructor
1978 void initSlowCase(const APInt &that);
1979
1980 /// out-of-line slow case for shl
1981 void shlSlowCase(unsigned ShiftAmt);
1982
1983 /// out-of-line slow case for lshr.
1984 void lshrSlowCase(unsigned ShiftAmt);
1985
1986 /// out-of-line slow case for ashr.
1987 void ashrSlowCase(unsigned ShiftAmt);
1988
1989 /// out-of-line slow case for operator=
1990 void assignSlowCase(const APInt &RHS);
1991
1992 /// out-of-line slow case for operator==
1993 bool equalSlowCase(const APInt &RHS) const LLVM_READONLY__attribute__((__pure__));
1994
1995 /// out-of-line slow case for countLeadingZeros
1996 unsigned countLeadingZerosSlowCase() const LLVM_READONLY__attribute__((__pure__));
1997
1998 /// out-of-line slow case for countLeadingOnes.
1999 unsigned countLeadingOnesSlowCase() const LLVM_READONLY__attribute__((__pure__));
2000
2001 /// out-of-line slow case for countTrailingZeros.
2002 unsigned countTrailingZerosSlowCase() const LLVM_READONLY__attribute__((__pure__));
2003
2004 /// out-of-line slow case for countTrailingOnes
2005 unsigned countTrailingOnesSlowCase() const LLVM_READONLY__attribute__((__pure__));
2006
2007 /// out-of-line slow case for countPopulation
2008 unsigned countPopulationSlowCase() const LLVM_READONLY__attribute__((__pure__));
2009
2010 /// out-of-line slow case for intersects.
2011 bool intersectsSlowCase(const APInt &RHS) const LLVM_READONLY__attribute__((__pure__));
2012
2013 /// out-of-line slow case for isSubsetOf.
2014 bool isSubsetOfSlowCase(const APInt &RHS) const LLVM_READONLY__attribute__((__pure__));
2015
2016 /// out-of-line slow case for setBits.
2017 void setBitsSlowCase(unsigned loBit, unsigned hiBit);
2018
2019 /// out-of-line slow case for flipAllBits.
2020 void flipAllBitsSlowCase();
2021
2022 /// out-of-line slow case for concat.
2023 APInt concatSlowCase(const APInt &NewLSB) const;
2024
2025 /// out-of-line slow case for operator&=.
2026 void andAssignSlowCase(const APInt &RHS);
2027
2028 /// out-of-line slow case for operator|=.
2029 void orAssignSlowCase(const APInt &RHS);
2030
2031 /// out-of-line slow case for operator^=.
2032 void xorAssignSlowCase(const APInt &RHS);
2033
2034 /// Unsigned comparison. Returns -1, 0, or 1 if this APInt is less than, equal
2035 /// to, or greater than RHS.
2036 int compare(const APInt &RHS) const LLVM_READONLY__attribute__((__pure__));
2037
2038 /// Signed comparison. Returns -1, 0, or 1 if this APInt is less than, equal
2039 /// to, or greater than RHS.
2040 int compareSigned(const APInt &RHS) const LLVM_READONLY__attribute__((__pure__));
2041
2042 /// @}
2043};
2044
2045inline bool operator==(uint64_t V1, const APInt &V2) { return V2 == V1; }
2046
2047inline bool operator!=(uint64_t V1, const APInt &V2) { return V2 != V1; }
2048
2049/// Unary bitwise complement operator.
2050///
2051/// \returns an APInt that is the bitwise complement of \p v.
2052inline APInt operator~(APInt v) {
2053 v.flipAllBits();
2054 return v;
2055}
2056
2057inline APInt operator&(APInt a, const APInt &b) {
2058 a &= b;
2059 return a;
2060}
2061
2062inline APInt operator&(const APInt &a, APInt &&b) {
2063 b &= a;
2064 return std::move(b);
2065}
2066
2067inline APInt operator&(APInt a, uint64_t RHS) {
2068 a &= RHS;
2069 return a;
2070}
2071
2072inline APInt operator&(uint64_t LHS, APInt b) {
2073 b &= LHS;
2074 return b;
2075}
2076
2077inline APInt operator|(APInt a, const APInt &b) {
2078 a |= b;
2079 return a;
2080}
2081
2082inline APInt operator|(const APInt &a, APInt &&b) {
2083 b |= a;
2084 return std::move(b);
2085}
2086
2087inline APInt operator|(APInt a, uint64_t RHS) {
2088 a |= RHS;
2089 return a;
2090}
2091
2092inline APInt operator|(uint64_t LHS, APInt b) {
2093 b |= LHS;
2094 return b;
2095}
2096
2097inline APInt operator^(APInt a, const APInt &b) {
2098 a ^= b;
2099 return a;
2100}
2101
2102inline APInt operator^(const APInt &a, APInt &&b) {
2103 b ^= a;
2104 return std::move(b);
2105}
2106
2107inline APInt operator^(APInt a, uint64_t RHS) {
2108 a ^= RHS;
2109 return a;
2110}
2111
2112inline APInt operator^(uint64_t LHS, APInt b) {
2113 b ^= LHS;
2114 return b;
2115}
2116
2117inline raw_ostream &operator<<(raw_ostream &OS, const APInt &I) {
2118 I.print(OS, true);
2119 return OS;
2120}
2121
2122inline APInt operator-(APInt v) {
2123 v.negate();
2124 return v;
2125}
2126
2127inline APInt operator+(APInt a, const APInt &b) {
2128 a += b;
2129 return a;
2130}
2131
2132inline APInt operator+(const APInt &a, APInt &&b) {
2133 b += a;
2134 return std::move(b);
2135}
2136
2137inline APInt operator+(APInt a, uint64_t RHS) {
2138 a += RHS;
2139 return a;
2140}
2141
2142inline APInt operator+(uint64_t LHS, APInt b) {
2143 b += LHS;
2144 return b;
2145}
2146
2147inline APInt operator-(APInt a, const APInt &b) {
2148 a -= b;
2149 return a;
2150}
2151
2152inline APInt operator-(const APInt &a, APInt &&b) {
2153 b.negate();
2154 b += a;
2155 return std::move(b);
2156}
2157
2158inline APInt operator-(APInt a, uint64_t RHS) {
2159 a -= RHS;
2160 return a;
2161}
2162
2163inline APInt operator-(uint64_t LHS, APInt b) {
2164 b.negate();
2165 b += LHS;
2166 return b;
2167}
2168
2169inline APInt operator*(APInt a, uint64_t RHS) {
2170 a *= RHS;
2171 return a;
2172}
2173
2174inline APInt operator*(uint64_t LHS, APInt b) {
2175 b *= LHS;
2176 return b;
2177}
2178
2179namespace APIntOps {
2180
2181/// Determine the smaller of two APInts considered to be signed.
2182inline const APInt &smin(const APInt &A, const APInt &B) {
2183 return A.slt(B) ? A : B;
2184}
2185
2186/// Determine the larger of two APInts considered to be signed.
2187inline const APInt &smax(const APInt &A, const APInt &B) {
2188 return A.sgt(B) ? A : B;
2189}
2190
2191/// Determine the smaller of two APInts considered to be unsigned.
2192inline const APInt &umin(const APInt &A, const APInt &B) {
2193 return A.ult(B) ? A : B;
2194}
2195
2196/// Determine the larger of two APInts considered to be unsigned.
2197inline const APInt &umax(const APInt &A, const APInt &B) {
2198 return A.ugt(B) ? A : B;
2199}
2200
2201/// Compute GCD of two unsigned APInt values.
2202///
2203/// This function returns the greatest common divisor of the two APInt values
2204/// using Stein's algorithm.
2205///
2206/// \returns the greatest common divisor of A and B.
2207APInt GreatestCommonDivisor(APInt A, APInt B);
2208
2209/// Converts the given APInt to a double value.
2210///
2211/// Treats the APInt as an unsigned value for conversion purposes.
2212inline double RoundAPIntToDouble(const APInt &APIVal) {
2213 return APIVal.roundToDouble();
2214}
2215
2216/// Converts the given APInt to a double value.
2217///
2218/// Treats the APInt as a signed value for conversion purposes.
2219inline double RoundSignedAPIntToDouble(const APInt &APIVal) {
2220 return APIVal.signedRoundToDouble();
2221}
2222
2223/// Converts the given APInt to a float value.
2224inline float RoundAPIntToFloat(const APInt &APIVal) {
2225 return float(RoundAPIntToDouble(APIVal));
2226}
2227
2228/// Converts the given APInt to a float value.
2229///
2230/// Treats the APInt as a signed value for conversion purposes.
2231inline float RoundSignedAPIntToFloat(const APInt &APIVal) {
2232 return float(APIVal.signedRoundToDouble());
2233}
2234
2235/// Converts the given double value into a APInt.
2236///
2237/// This function convert a double value to an APInt value.
2238APInt RoundDoubleToAPInt(double Double, unsigned width);
2239
2240/// Converts a float value into a APInt.
2241///
2242/// Converts a float value into an APInt value.
2243inline APInt RoundFloatToAPInt(float Float, unsigned width) {
2244 return RoundDoubleToAPInt(double(Float), width);
2245}
2246
2247/// Return A unsign-divided by B, rounded by the given rounding mode.
2248APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM);
2249
2250/// Return A sign-divided by B, rounded by the given rounding mode.
2251APInt RoundingSDiv(const APInt &A, const APInt &B, APInt::Rounding RM);
2252
2253/// Let q(n) = An^2 + Bn + C, and BW = bit width of the value range
2254/// (e.g. 32 for i32).
2255/// This function finds the smallest number n, such that
2256/// (a) n >= 0 and q(n) = 0, or
2257/// (b) n >= 1 and q(n-1) and q(n), when evaluated in the set of all
2258/// integers, belong to two different intervals [Rk, Rk+R),
2259/// where R = 2^BW, and k is an integer.
2260/// The idea here is to find when q(n) "overflows" 2^BW, while at the
2261/// same time "allowing" subtraction. In unsigned modulo arithmetic a
2262/// subtraction (treated as addition of negated numbers) would always
2263/// count as an overflow, but here we want to allow values to decrease
2264/// and increase as long as they are within the same interval.
2265/// Specifically, adding of two negative numbers should not cause an
2266/// overflow (as long as the magnitude does not exceed the bit width).
2267/// On the other hand, given a positive number, adding a negative
2268/// number to it can give a negative result, which would cause the
2269/// value to go from [-2^BW, 0) to [0, 2^BW). In that sense, zero is
2270/// treated as a special case of an overflow.
2271///
2272/// This function returns std::nullopt if after finding k that minimizes the
2273/// positive solution to q(n) = kR, both solutions are contained between
2274/// two consecutive integers.
2275///
2276/// There are cases where q(n) > T, and q(n+1) < T (assuming evaluation
2277/// in arithmetic modulo 2^BW, and treating the values as signed) by the
2278/// virtue of *signed* overflow. This function will *not* find such an n,
2279/// however it may find a value of n satisfying the inequalities due to
2280/// an *unsigned* overflow (if the values are treated as unsigned).
2281/// To find a solution for a signed overflow, treat it as a problem of
2282/// finding an unsigned overflow with a range with of BW-1.
2283///
2284/// The returned value may have a different bit width from the input
2285/// coefficients.
2286std::optional<APInt> SolveQuadraticEquationWrap(APInt A, APInt B, APInt C,
2287 unsigned RangeWidth);
2288
2289/// Compare two values, and if they are different, return the position of the
2290/// most significant bit that is different in the values.
2291std::optional<unsigned> GetMostSignificantDifferentBit(const APInt &A,
2292 const APInt &B);
2293
2294/// Splat/Merge neighboring bits to widen/narrow the bitmask represented
2295/// by \param A to \param NewBitWidth bits.
2296///
2297/// MatchAnyBits: (Default)
2298/// e.g. ScaleBitMask(0b0101, 8) -> 0b00110011
2299/// e.g. ScaleBitMask(0b00011011, 4) -> 0b0111
2300///
2301/// MatchAllBits:
2302/// e.g. ScaleBitMask(0b0101, 8) -> 0b00110011
2303/// e.g. ScaleBitMask(0b00011011, 4) -> 0b0001
2304/// A.getBitwidth() or NewBitWidth must be a whole multiples of the other.
2305APInt ScaleBitMask(const APInt &A, unsigned NewBitWidth,
2306 bool MatchAllBits = false);
2307} // namespace APIntOps
2308
2309// See friend declaration above. This additional declaration is required in
2310// order to compile LLVM with IBM xlC compiler.
2311hash_code hash_value(const APInt &Arg);
2312
2313/// StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst
2314/// with the integer held in IntVal.
2315void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, unsigned StoreBytes);
2316
2317/// LoadIntFromMemory - Loads the integer stored in the LoadBytes bytes starting
2318/// from Src into IntVal, which is assumed to be wide enough and to hold zero.
2319void LoadIntFromMemory(APInt &IntVal, const uint8_t *Src, unsigned LoadBytes);
2320
2321/// Provide DenseMapInfo for APInt.
2322template <> struct DenseMapInfo<APInt, void> {
2323 static inline APInt getEmptyKey() {
2324 APInt V(nullptr, 0);
2325 V.U.VAL = ~0ULL;
2326 return V;
2327 }
2328
2329 static inline APInt getTombstoneKey() {
2330 APInt V(nullptr, 0);
2331 V.U.VAL = ~1ULL;
2332 return V;
2333 }
2334
2335 static unsigned getHashValue(const APInt &Key);
2336
2337 static bool isEqual(const APInt &LHS, const APInt &RHS) {
2338 return LHS.getBitWidth() == RHS.getBitWidth() && LHS == RHS;
2339 }
2340};
2341
2342} // namespace llvm
2343
2344#endif