LLVM 23.0.0git
AMDGPUCodeGenPrepare.cpp
Go to the documentation of this file.
1//===-- AMDGPUCodeGenPrepare.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//
9/// \file
10/// This pass does misc. AMDGPU optimizations on IR before instruction
11/// selection.
12//
13//===----------------------------------------------------------------------===//
14
15#include "AMDGPU.h"
16#include "AMDGPUMemoryUtils.h"
17#include "AMDGPUTargetMachine.h"
19#include "llvm/ADT/SetVector.h"
27#include "llvm/IR/Dominators.h"
28#include "llvm/IR/IRBuilder.h"
29#include "llvm/IR/InstVisitor.h"
30#include "llvm/IR/IntrinsicsAMDGPU.h"
32#include "llvm/IR/ValueHandle.h"
34#include "llvm/Pass.h"
40
41#define DEBUG_TYPE "amdgpu-codegenprepare"
42
43using namespace llvm;
44using namespace llvm::PatternMatch;
45
46namespace {
47
49 "amdgpu-codegenprepare-widen-constant-loads",
50 cl::desc("Widen sub-dword constant address space loads in AMDGPUCodeGenPrepare"),
52 cl::init(false));
53
54static cl::opt<bool>
55 BreakLargePHIs("amdgpu-codegenprepare-break-large-phis",
56 cl::desc("Break large PHI nodes for DAGISel"),
58
59static cl::opt<bool>
60 ForceBreakLargePHIs("amdgpu-codegenprepare-force-break-large-phis",
61 cl::desc("For testing purposes, always break large "
62 "PHIs even if it isn't profitable."),
64
65static cl::opt<unsigned> BreakLargePHIsThreshold(
66 "amdgpu-codegenprepare-break-large-phis-threshold",
67 cl::desc("Minimum type size in bits for breaking large PHI nodes"),
69
70static cl::opt<bool> UseMul24Intrin(
71 "amdgpu-codegenprepare-mul24",
72 cl::desc("Introduce mul24 intrinsics in AMDGPUCodeGenPrepare"),
74 cl::init(true));
75
76// Legalize 64-bit division by using the generic IR expansion.
77static cl::opt<bool> ExpandDiv64InIR(
78 "amdgpu-codegenprepare-expand-div64",
79 cl::desc("Expand 64-bit division in AMDGPUCodeGenPrepare"),
81 cl::init(false));
82
83// Leave all division operations as they are. This supersedes ExpandDiv64InIR
84// and is used for testing the legalizer.
85static cl::opt<bool> DisableIDivExpand(
86 "amdgpu-codegenprepare-disable-idiv-expansion",
87 cl::desc("Prevent expanding integer division in AMDGPUCodeGenPrepare"),
89 cl::init(false));
90
91// Disable processing of fdiv so we can better test the backend implementations.
92static cl::opt<bool> DisableFDivExpand(
93 "amdgpu-codegenprepare-disable-fdiv-expansion",
94 cl::desc("Prevent expanding floating point division in AMDGPUCodeGenPrepare"),
96 cl::init(false));
97
98class AMDGPUCodeGenPrepareImpl
99 : public InstVisitor<AMDGPUCodeGenPrepareImpl, bool> {
100public:
101 Function &F;
102 const GCNSubtarget &ST;
103 const AMDGPUTargetMachine &TM;
104 const TargetLibraryInfo *TLI;
105 const UniformityInfo &UA;
106 const DataLayout &DL;
107 SimplifyQuery SQ;
108 const bool HasFP32DenormalFlush;
109 bool FlowChanged = false;
110 mutable Function *SqrtF32 = nullptr;
111 mutable Function *LdexpF32 = nullptr;
112 mutable SmallVector<WeakVH> DeadVals;
113
114 DenseMap<const PHINode *, bool> BreakPhiNodesCache;
115
116 AMDGPUCodeGenPrepareImpl(Function &F, const AMDGPUTargetMachine &TM,
117 const TargetLibraryInfo *TLI, AssumptionCache *AC,
118 const DominatorTree *DT, const UniformityInfo &UA)
119 : F(F), ST(TM.getSubtarget<GCNSubtarget>(F)), TM(TM), TLI(TLI), UA(UA),
120 DL(F.getDataLayout()), SQ(DL, TLI, DT, AC),
121 HasFP32DenormalFlush(SIModeRegisterDefaults(F, ST).FP32Denormals ==
123
124 Function *getSqrtF32() const {
125 if (SqrtF32)
126 return SqrtF32;
127
128 LLVMContext &Ctx = F.getContext();
130 F.getParent(), Intrinsic::amdgcn_sqrt, {Type::getFloatTy(Ctx)});
131 return SqrtF32;
132 }
133
134 Function *getLdexpF32() const {
135 if (LdexpF32)
136 return LdexpF32;
137
138 LLVMContext &Ctx = F.getContext();
140 F.getParent(), Intrinsic::ldexp,
141 {Type::getFloatTy(Ctx), Type::getInt32Ty(Ctx)});
142 return LdexpF32;
143 }
144
145 bool canBreakPHINode(const PHINode &I);
146
147 /// Return true if \p T is a legal scalar floating point type.
148 bool isLegalFloatingTy(const Type *T) const;
149
150 /// Wrapper to pass all the arguments to computeKnownFPClass
152 const Instruction *CtxI) const {
153 return llvm::computeKnownFPClass(V, Interested,
154 SQ.getWithInstruction(CtxI));
155 }
156
157 bool canIgnoreDenormalInput(const Value *V, const Instruction *CtxI) const {
158 return HasFP32DenormalFlush ||
160 }
161
162 /// \returns The minimum number of bits needed to store the value of \Op as an
163 /// unsigned integer. Truncating to this size and then zero-extending to
164 /// the original will not change the value.
165 unsigned numBitsUnsigned(Value *Op, const Instruction *CtxI) const;
166
167 /// \returns The minimum number of bits needed to store the value of \Op as a
168 /// signed integer. Truncating to this size and then sign-extending to
169 /// the original size will not change the value.
170 unsigned numBitsSigned(Value *Op, const Instruction *CtxI) const;
171
172 /// Replace mul instructions with llvm.amdgcn.mul.u24 or llvm.amdgcn.mul.s24.
173 /// SelectionDAG has an issue where an and asserting the bits are known
174 bool replaceMulWithMul24(BinaryOperator &I) const;
175
176 /// Perform same function as equivalently named function in DAGCombiner. Since
177 /// we expand some divisions here, we need to perform this before obscuring.
178 bool foldBinOpIntoSelect(BinaryOperator &I) const;
179
180 bool divHasSpecialOptimization(BinaryOperator &I,
181 Value *Num, Value *Den) const;
182 unsigned getDivNumBits(BinaryOperator &I, Value *Num, Value *Den,
183 unsigned MaxDivBits, bool Signed) const;
184
185 /// Expands div or rem by using floating-point operations.
186 /// Operands must be in the range [-0x400000,0x3FFFFF]
187 Value *expandDivRemToFloat(IRBuilder<> &Builder, BinaryOperator &I,
188 Value *Num, Value *Den, bool IsDiv,
189 bool IsSigned) const;
190
191 Value *expandDivRemToFloatImpl(IRBuilder<> &Builder, BinaryOperator &I,
192 Value *Num, Value *Den, unsigned NumBits,
193 bool IsDiv, bool IsSigned) const;
194
195 /// Expands 32 bit div or rem.
196 Value* expandDivRem32(IRBuilder<> &Builder, BinaryOperator &I,
197 Value *Num, Value *Den) const;
198
199 Value *shrinkDivRem64(IRBuilder<> &Builder, BinaryOperator &I,
200 Value *Num, Value *Den) const;
201 void expandDivRem64(BinaryOperator &I) const;
202
203 /// Widen a scalar load.
204 ///
205 /// \details \p Widen scalar load for uniform, small type loads from constant
206 // memory / to a full 32-bits and then truncate the input to allow a scalar
207 // load instead of a vector load.
208 //
209 /// \returns True.
210
211 bool canWidenScalarExtLoad(LoadInst &I) const;
212
213 Value *matchFractPatImpl(Value &V, const APFloat &C) const;
214 Value *matchFractPatNanAvoidant(Value &V);
215 Value *applyFractPat(IRBuilder<> &Builder, Value *FractArg);
216
217 bool canOptimizeWithRsq(FastMathFlags DivFMF, FastMathFlags SqrtFMF) const;
218
219 Value *optimizeWithRsq(IRBuilder<> &Builder, Value *Num, Value *Den,
220 FastMathFlags DivFMF, FastMathFlags SqrtFMF,
221 const Instruction *CtxI) const;
222
223 Value *optimizeWithRcp(IRBuilder<> &Builder, Value *Num, Value *Den,
224 FastMathFlags FMF, const Instruction *CtxI) const;
225 Value *optimizeWithFDivFast(IRBuilder<> &Builder, Value *Num, Value *Den,
226 float ReqdAccuracy) const;
227
228 Value *visitFDivElement(IRBuilder<> &Builder, Value *Num, Value *Den,
229 FastMathFlags DivFMF, FastMathFlags SqrtFMF,
230 Value *RsqOp, const Instruction *FDiv,
231 float ReqdAccuracy) const;
232
233 std::pair<Value *, Value *> getFrexpResults(IRBuilder<> &Builder,
234 Value *Src) const;
235
236 Value *emitRcpIEEE1ULP(IRBuilder<> &Builder, Value *Src,
237 bool IsNegative) const;
238 Value *emitFrexpDiv(IRBuilder<> &Builder, Value *LHS, Value *RHS,
239 FastMathFlags FMF) const;
240 Value *emitSqrtIEEE2ULP(IRBuilder<> &Builder, Value *Src,
241 FastMathFlags FMF) const;
242 Value *emitRsqF64(IRBuilder<> &Builder, Value *X, FastMathFlags SqrtFMF,
243 FastMathFlags DivFMF, const Instruction *CtxI,
244 bool IsNegative) const;
245
246 CallInst *createWorkitemIdX(IRBuilder<> &B) const;
247 void replaceWithWorkitemIdX(Instruction &I) const;
248 void replaceWithMaskedWorkitemIdX(Instruction &I, unsigned WaveSize) const;
249 bool tryReplaceWithWorkitemId(Instruction &I, unsigned Wave) const;
250
251 bool tryNarrowMathIfNoOverflow(Instruction *I);
252
253public:
254 bool visitFDiv(BinaryOperator &I);
255
256 bool visitInstruction(Instruction &I) { return false; }
257 bool visitBinaryOperator(BinaryOperator &I);
258 bool visitLoadInst(LoadInst &I);
259 bool visitSelectInst(SelectInst &I);
260 bool visitPHINode(PHINode &I);
261 bool visitAddrSpaceCastInst(AddrSpaceCastInst &I);
262
263 bool visitIntrinsicInst(IntrinsicInst &I);
264 bool visitFMinLike(IntrinsicInst &I);
265 bool visitSqrt(IntrinsicInst &I);
266 bool visitLog(FPMathOperator &Log, Intrinsic::ID IID);
267 bool visitMbcntLo(IntrinsicInst &I) const;
268 bool visitMbcntHi(IntrinsicInst &I) const;
269 bool visitVectorReduceAdd(IntrinsicInst &I);
270 bool visitSaturatingAdd(IntrinsicInst &I);
271 bool run();
272};
273
274class AMDGPUCodeGenPrepare : public FunctionPass {
275public:
276 static char ID;
277 AMDGPUCodeGenPrepare() : FunctionPass(ID) {}
278 void getAnalysisUsage(AnalysisUsage &AU) const override {
282
283 // FIXME: Division expansion needs to preserve the dominator tree.
284 if (!ExpandDiv64InIR)
285 AU.setPreservesAll();
286 }
287 bool runOnFunction(Function &F) override;
288 StringRef getPassName() const override { return "AMDGPU IR optimizations"; }
289};
290
291} // end anonymous namespace
292
293bool AMDGPUCodeGenPrepareImpl::run() {
294 BreakPhiNodesCache.clear();
295 bool MadeChange = false;
296
297 // Need to use make_early_inc_range because integer division expansion is
298 // handled by Transform/Utils, and it can delete instructions such as the
299 // terminator of the BB.
300 for (BasicBlock &BB : reverse(F)) {
301 for (Instruction &I : make_early_inc_range(reverse(BB))) {
302 if (!isInstructionTriviallyDead(&I, TLI))
303 MadeChange |= visit(I);
304 }
305 }
306
307 while (!DeadVals.empty()) {
308 if (auto *I = dyn_cast_or_null<Instruction>(DeadVals.pop_back_val()))
310 }
311
312 return MadeChange;
313}
314
315bool AMDGPUCodeGenPrepareImpl::isLegalFloatingTy(const Type *Ty) const {
316 return Ty->isFloatTy() || Ty->isDoubleTy() ||
317 (Ty->isHalfTy() && ST.has16BitInsts());
318}
319
320bool AMDGPUCodeGenPrepareImpl::canWidenScalarExtLoad(LoadInst &I) const {
321 Type *Ty = I.getType();
322 int TySize = DL.getTypeSizeInBits(Ty);
323 Align Alignment = DL.getValueOrABITypeAlignment(I.getAlign(), Ty);
324
325 return I.isSimple() && TySize < 32 && Alignment >= 4 && UA.isUniformAtDef(&I);
326}
327
328unsigned
329AMDGPUCodeGenPrepareImpl::numBitsUnsigned(Value *Op,
330 const Instruction *CtxI) const {
331 return computeKnownBits(Op, SQ.getWithInstruction(CtxI)).countMaxActiveBits();
332}
333
334unsigned
335AMDGPUCodeGenPrepareImpl::numBitsSigned(Value *Op,
336 const Instruction *CtxI) const {
337 return ComputeMaxSignificantBits(Op, SQ.DL, SQ.AC, CtxI, SQ.DT);
338}
339
340static void extractValues(IRBuilder<> &Builder,
342 auto *VT = dyn_cast<FixedVectorType>(V->getType());
343 if (!VT) {
344 Values.push_back(V);
345 return;
346 }
347
348 for (int I = 0, E = VT->getNumElements(); I != E; ++I)
349 Values.push_back(Builder.CreateExtractElement(V, I));
350}
351
353 Type *Ty,
355 if (!Ty->isVectorTy()) {
356 assert(Values.size() == 1);
357 return Values[0];
358 }
359
360 Value *NewVal = PoisonValue::get(Ty);
361 for (int I = 0, E = Values.size(); I != E; ++I)
362 NewVal = Builder.CreateInsertElement(NewVal, Values[I], I);
363
364 return NewVal;
365}
366
367bool AMDGPUCodeGenPrepareImpl::replaceMulWithMul24(BinaryOperator &I) const {
368 if (I.getOpcode() != Instruction::Mul)
369 return false;
370
371 Type *Ty = I.getType();
372 unsigned Size = Ty->getScalarSizeInBits();
373 if (Size <= 16 && ST.has16BitInsts())
374 return false;
375
376 // Prefer scalar if this could be s_mul_i32
377 if (UA.isUniformAtDef(&I))
378 return false;
379
380 Value *LHS = I.getOperand(0);
381 Value *RHS = I.getOperand(1);
382 IRBuilder<> Builder(&I);
383 Builder.SetCurrentDebugLocation(I.getDebugLoc());
384
385 unsigned LHSBits = 0, RHSBits = 0;
386 bool IsSigned = false;
387
388 if (ST.hasMulU24() && (LHSBits = numBitsUnsigned(LHS, &I)) <= 24 &&
389 (RHSBits = numBitsUnsigned(RHS, &I)) <= 24) {
390 IsSigned = false;
391
392 } else if (ST.hasMulI24() && (LHSBits = numBitsSigned(LHS, &I)) <= 24 &&
393 (RHSBits = numBitsSigned(RHS, &I)) <= 24) {
394 IsSigned = true;
395
396 } else
397 return false;
398
399 SmallVector<Value *, 4> LHSVals;
400 SmallVector<Value *, 4> RHSVals;
401 SmallVector<Value *, 4> ResultVals;
402 extractValues(Builder, LHSVals, LHS);
403 extractValues(Builder, RHSVals, RHS);
404
405 IntegerType *I32Ty = Builder.getInt32Ty();
406 IntegerType *IntrinTy = Size > 32 ? Builder.getInt64Ty() : I32Ty;
407 Type *DstTy = LHSVals[0]->getType();
408
409 for (int I = 0, E = LHSVals.size(); I != E; ++I) {
410 Value *LHS = IsSigned ? Builder.CreateSExtOrTrunc(LHSVals[I], I32Ty)
411 : Builder.CreateZExtOrTrunc(LHSVals[I], I32Ty);
412 Value *RHS = IsSigned ? Builder.CreateSExtOrTrunc(RHSVals[I], I32Ty)
413 : Builder.CreateZExtOrTrunc(RHSVals[I], I32Ty);
415 IsSigned ? Intrinsic::amdgcn_mul_i24 : Intrinsic::amdgcn_mul_u24;
416 Value *Result = Builder.CreateIntrinsic(ID, {IntrinTy}, {LHS, RHS});
417 Result = IsSigned ? Builder.CreateSExtOrTrunc(Result, DstTy)
418 : Builder.CreateZExtOrTrunc(Result, DstTy);
419 ResultVals.push_back(Result);
420 }
421
422 Value *NewVal = insertValues(Builder, Ty, ResultVals);
423 NewVal->takeName(&I);
424 I.replaceAllUsesWith(NewVal);
425 DeadVals.push_back(&I);
426
427 return true;
428}
429
430// Find a select instruction, which may have been casted. This is mostly to deal
431// with cases where i16 selects were promoted here to i32.
433 Cast = nullptr;
434 if (SelectInst *Sel = dyn_cast<SelectInst>(V))
435 return Sel;
436
437 if ((Cast = dyn_cast<CastInst>(V))) {
438 if (SelectInst *Sel = dyn_cast<SelectInst>(Cast->getOperand(0)))
439 return Sel;
440 }
441
442 return nullptr;
443}
444
445bool AMDGPUCodeGenPrepareImpl::foldBinOpIntoSelect(BinaryOperator &BO) const {
446 // Don't do this unless the old select is going away. We want to eliminate the
447 // binary operator, not replace a binop with a select.
448 int SelOpNo = 0;
449
450 CastInst *CastOp;
451
452 // TODO: Should probably try to handle some cases with multiple
453 // users. Duplicating the select may be profitable for division.
454 SelectInst *Sel = findSelectThroughCast(BO.getOperand(0), CastOp);
455 if (!Sel || !Sel->hasOneUse()) {
456 SelOpNo = 1;
457 Sel = findSelectThroughCast(BO.getOperand(1), CastOp);
458 }
459
460 if (!Sel || !Sel->hasOneUse())
461 return false;
462
465 Constant *CBO = dyn_cast<Constant>(BO.getOperand(SelOpNo ^ 1));
466 if (!CBO || !CT || !CF)
467 return false;
468
469 if (CastOp) {
470 if (!CastOp->hasOneUse())
471 return false;
472 CT = ConstantFoldCastOperand(CastOp->getOpcode(), CT, BO.getType(), DL);
473 CF = ConstantFoldCastOperand(CastOp->getOpcode(), CF, BO.getType(), DL);
474 }
475
476 // TODO: Handle special 0/-1 cases DAG combine does, although we only really
477 // need to handle divisions here.
478 Constant *FoldedT =
479 SelOpNo ? ConstantFoldBinaryOpOperands(BO.getOpcode(), CBO, CT, DL)
480 : ConstantFoldBinaryOpOperands(BO.getOpcode(), CT, CBO, DL);
481 if (!FoldedT || isa<ConstantExpr>(FoldedT))
482 return false;
483
484 Constant *FoldedF =
485 SelOpNo ? ConstantFoldBinaryOpOperands(BO.getOpcode(), CBO, CF, DL)
486 : ConstantFoldBinaryOpOperands(BO.getOpcode(), CF, CBO, DL);
487 if (!FoldedF || isa<ConstantExpr>(FoldedF))
488 return false;
489
490 IRBuilder<> Builder(&BO);
491 Builder.SetCurrentDebugLocation(BO.getDebugLoc());
492 if (const FPMathOperator *FPOp = dyn_cast<const FPMathOperator>(&BO))
493 Builder.setFastMathFlags(FPOp->getFastMathFlags());
494
495 Value *NewSelect = Builder.CreateSelect(Sel->getCondition(),
496 FoldedT, FoldedF);
497 NewSelect->takeName(&BO);
498 BO.replaceAllUsesWith(NewSelect);
499 DeadVals.push_back(&BO);
500 if (CastOp)
501 DeadVals.push_back(CastOp);
502 DeadVals.push_back(Sel);
503 return true;
504}
505
506std::pair<Value *, Value *>
507AMDGPUCodeGenPrepareImpl::getFrexpResults(IRBuilder<> &Builder,
508 Value *Src) const {
509 Type *Ty = Src->getType();
510 Value *Frexp = Builder.CreateIntrinsic(Intrinsic::frexp,
511 {Ty, Builder.getInt32Ty()}, Src);
512 Value *FrexpMant = Builder.CreateExtractValue(Frexp, {0});
513
514 // Bypass the bug workaround for the exponent result since it doesn't matter.
515 // TODO: Does the bug workaround even really need to consider the exponent
516 // result? It's unspecified by the spec.
517
518 Value *FrexpExp =
519 ST.hasFractBug()
520 ? Builder.CreateIntrinsic(Intrinsic::amdgcn_frexp_exp,
521 {Builder.getInt32Ty(), Ty}, Src)
522 : Builder.CreateExtractValue(Frexp, {1});
523 return {FrexpMant, FrexpExp};
524}
525
526/// Emit an expansion of 1.0 / Src good for 1ulp that supports denormals.
527Value *AMDGPUCodeGenPrepareImpl::emitRcpIEEE1ULP(IRBuilder<> &Builder,
528 Value *Src,
529 bool IsNegative) const {
530 // Same as for 1.0, but expand the sign out of the constant.
531 // -1.0 / x -> rcp (fneg x)
532 if (IsNegative)
533 Src = Builder.CreateFNeg(Src);
534
535 // The rcp instruction doesn't support denormals, so scale the input
536 // out of the denormal range and convert at the end.
537 //
538 // Expand as 2^-n * (1.0 / (x * 2^n))
539
540 // TODO: Skip scaling if input is known never denormal and the input
541 // range won't underflow to denormal. The hard part is knowing the
542 // result. We need a range check, the result could be denormal for
543 // 0x1p+126 < den <= 0x1p+127.
544 auto [FrexpMant, FrexpExp] = getFrexpResults(Builder, Src);
545 Value *ScaleFactor = Builder.CreateNeg(FrexpExp);
546 Value *Rcp = Builder.CreateUnaryIntrinsic(Intrinsic::amdgcn_rcp, FrexpMant);
547 return Builder.CreateCall(getLdexpF32(), {Rcp, ScaleFactor});
548}
549
550/// Emit a 2ulp expansion for fdiv by using frexp for input scaling.
551Value *AMDGPUCodeGenPrepareImpl::emitFrexpDiv(IRBuilder<> &Builder, Value *LHS,
552 Value *RHS,
553 FastMathFlags FMF) const {
554 // If we have have to work around the fract/frexp bug, we're worse off than
555 // using the fdiv.fast expansion. The full safe expansion is faster if we have
556 // fast FMA.
557 if (HasFP32DenormalFlush && ST.hasFractBug() && !ST.hasFastFMAF32() &&
558 (!FMF.noNaNs() || !FMF.noInfs()))
559 return nullptr;
560
561 // We're scaling the LHS to avoid a denormal input, and scale the denominator
562 // to avoid large values underflowing the result.
563 auto [FrexpMantRHS, FrexpExpRHS] = getFrexpResults(Builder, RHS);
564
565 Value *Rcp =
566 Builder.CreateUnaryIntrinsic(Intrinsic::amdgcn_rcp, FrexpMantRHS);
567
568 auto [FrexpMantLHS, FrexpExpLHS] = getFrexpResults(Builder, LHS);
569 Value *Mul = Builder.CreateFMul(FrexpMantLHS, Rcp);
570
571 // We multiplied by 2^N/2^M, so we need to multiply by 2^(N-M) to scale the
572 // result.
573 Value *ExpDiff = Builder.CreateSub(FrexpExpLHS, FrexpExpRHS);
574 return Builder.CreateCall(getLdexpF32(), {Mul, ExpDiff});
575}
576
577/// Emit a sqrt that handles denormals and is accurate to 2ulp.
578Value *AMDGPUCodeGenPrepareImpl::emitSqrtIEEE2ULP(IRBuilder<> &Builder,
579 Value *Src,
580 FastMathFlags FMF) const {
581 Type *Ty = Src->getType();
582 APFloat SmallestNormal =
584 Value *NeedScale =
585 Builder.CreateFCmpOLT(Src, ConstantFP::get(Ty, SmallestNormal));
586
587 ConstantInt *Zero = Builder.getInt32(0);
588 Value *InputScaleFactor =
589 Builder.CreateSelect(NeedScale, Builder.getInt32(32), Zero);
590
591 Value *Scaled = Builder.CreateCall(getLdexpF32(), {Src, InputScaleFactor});
592
593 Value *Sqrt = Builder.CreateCall(getSqrtF32(), Scaled);
594
595 Value *OutputScaleFactor =
596 Builder.CreateSelect(NeedScale, Builder.getInt32(-16), Zero);
597 return Builder.CreateCall(getLdexpF32(), {Sqrt, OutputScaleFactor});
598}
599
600/// Emit an expansion of 1.0 / sqrt(Src) good for 1ulp that supports denormals.
601static Value *emitRsqIEEE1ULP(IRBuilder<> &Builder, Value *Src,
602 bool IsNegative) {
603 // bool need_scale = x < 0x1p-126f;
604 // float input_scale = need_scale ? 0x1.0p+24f : 1.0f;
605 // float output_scale = need_scale ? 0x1.0p+12f : 1.0f;
606 // rsq(x * input_scale) * output_scale;
607
608 Type *Ty = Src->getType();
609 APFloat SmallestNormal =
610 APFloat::getSmallestNormalized(Ty->getFltSemantics());
611 Value *NeedScale =
612 Builder.CreateFCmpOLT(Src, ConstantFP::get(Ty, SmallestNormal));
613 Constant *One = ConstantFP::get(Ty, 1.0);
614 Constant *InputScale = ConstantFP::get(Ty, 0x1.0p+24);
615 Constant *OutputScale =
616 ConstantFP::get(Ty, IsNegative ? -0x1.0p+12 : 0x1.0p+12);
617
618 Value *InputScaleFactor = Builder.CreateSelect(NeedScale, InputScale, One);
619
620 Value *ScaledInput = Builder.CreateFMul(Src, InputScaleFactor);
621 Value *Rsq = Builder.CreateUnaryIntrinsic(Intrinsic::amdgcn_rsq, ScaledInput);
622 Value *OutputScaleFactor = Builder.CreateSelect(
623 NeedScale, OutputScale, IsNegative ? ConstantFP::get(Ty, -1.0) : One);
624
625 return Builder.CreateFMul(Rsq, OutputScaleFactor);
626}
627
628/// Emit inverse sqrt expansion for f64 with a correction sequence on top of
629/// v_rsq_f64. This should give a 1ulp result.
630Value *AMDGPUCodeGenPrepareImpl::emitRsqF64(IRBuilder<> &Builder, Value *X,
631 FastMathFlags SqrtFMF,
632 FastMathFlags DivFMF,
633 const Instruction *CtxI,
634 bool IsNegative) const {
635 // rsq(x):
636 // double y0 = BUILTIN_AMDGPU_RSQRT_F64(x);
637 // double e = MATH_MAD(-y0 * (x == PINF_F64 || x == 0.0 ? y0 : x), y0, 1.0);
638 // return MATH_MAD(y0*e, MATH_MAD(e, 0.375, 0.5), y0);
639 //
640 // -rsq(x):
641 // double y0 = BUILTIN_AMDGPU_RSQRT_F64(x);
642 // double e = MATH_MAD(-y0 * (x == PINF_F64 || x == 0.0 ? y0 : x), y0, 1.0);
643 // return MATH_MAD(-y0*e, MATH_MAD(e, 0.375, 0.5), -y0);
644 //
645 // The rsq instruction handles the special cases correctly. We need to check
646 // for the edge case conditions to ensure the special case propagates through
647 // the later instructions.
648
649 Value *Y0 = Builder.CreateUnaryIntrinsic(Intrinsic::amdgcn_rsq, X);
650
651 // Try to elide the edge case check.
652 //
653 // Fast math flags imply:
654 // sqrt ninf => !isinf(x)
655 // fdiv ninf => x != 0, !isinf(x)
656 bool MaybePosInf = !SqrtFMF.noInfs() && !DivFMF.noInfs();
657 bool MaybeZero = !DivFMF.noInfs();
658
659 DenormalMode DenormMode;
660 FPClassTest Interested = fcNone;
661 if (MaybePosInf)
662 Interested = fcPosInf;
663 if (MaybeZero)
664 Interested |= fcZero;
665
666 if (Interested != fcNone) {
667 KnownFPClass KnownSrc = computeKnownFPClass(X, Interested, CtxI);
668 if (KnownSrc.isKnownNeverPosInfinity())
669 MaybePosInf = false;
670
671 DenormMode = F.getDenormalMode(X->getType()->getFltSemantics());
672 if (KnownSrc.isKnownNeverLogicalZero(DenormMode))
673 MaybeZero = false;
674 }
675
676 Value *SpecialOrRsq = X;
677 if (MaybeZero || MaybePosInf) {
678 Value *Cond;
679 if (MaybePosInf && MaybeZero) {
680 if (DenormMode.Input != DenormalMode::DenormalModeKind::Dynamic) {
681 FPClassTest TestMask = fcPosInf | fcZero;
682 if (DenormMode.inputsAreZero())
683 TestMask |= fcSubnormal;
684
685 Cond = Builder.createIsFPClass(X, TestMask);
686 } else {
687 // Avoid using llvm.is.fpclass for dynamic denormal mode, since it
688 // doesn't respect the floating-point environment.
689 Value *IsZero =
690 Builder.CreateFCmpOEQ(X, ConstantFP::getZero(X->getType()));
691 Value *IsInf =
692 Builder.CreateFCmpOEQ(X, ConstantFP::getInfinity(X->getType()));
693 Cond = Builder.CreateOr(IsZero, IsInf);
694 }
695 } else if (MaybeZero) {
696 Cond = Builder.CreateFCmpOEQ(X, ConstantFP::getZero(X->getType()));
697 } else {
698 Cond = Builder.CreateFCmpOEQ(X, ConstantFP::getInfinity(X->getType()));
699 }
700
701 SpecialOrRsq = Builder.CreateSelect(Cond, Y0, X);
702 }
703
704 Value *NegY0 = Builder.CreateFNeg(Y0);
705 Value *NegXY0 = Builder.CreateFMul(SpecialOrRsq, NegY0);
706
707 // Could be fmuladd, but isFMAFasterThanFMulAndFAdd is always true for f64.
708 Value *E = Builder.CreateFMA(NegXY0, Y0, ConstantFP::get(X->getType(), 1.0));
709
710 Value *Y0E = Builder.CreateFMul(E, IsNegative ? NegY0 : Y0);
711
712 Value *EFMA = Builder.CreateFMA(E, ConstantFP::get(X->getType(), 0.375),
713 ConstantFP::get(X->getType(), 0.5));
714
715 return Builder.CreateFMA(Y0E, EFMA, IsNegative ? NegY0 : Y0);
716}
717
718bool AMDGPUCodeGenPrepareImpl::canOptimizeWithRsq(FastMathFlags DivFMF,
719 FastMathFlags SqrtFMF) const {
720 // The rsqrt contraction increases accuracy from ~2ulp to ~1ulp for f32 and
721 // f64.
722 return DivFMF.allowContract() && SqrtFMF.allowContract();
723}
724
725Value *AMDGPUCodeGenPrepareImpl::optimizeWithRsq(
726 IRBuilder<> &Builder, Value *Num, Value *Den, const FastMathFlags DivFMF,
727 const FastMathFlags SqrtFMF, const Instruction *CtxI) const {
728 // The rsqrt contraction increases accuracy from ~2ulp to ~1ulp.
729 assert(DivFMF.allowContract() && SqrtFMF.allowContract());
730
731 // rsq_f16 is accurate to 0.51 ulp.
732 // rsq_f32 is accurate for !fpmath >= 1.0ulp and denormals are flushed.
733 // rsq_f64 is never accurate.
734 const ConstantFP *CLHS = dyn_cast<ConstantFP>(Num);
735 if (!CLHS)
736 return nullptr;
737
738 bool IsNegative = false;
739
740 // TODO: Handle other numerator values with arcp.
741 if (CLHS->isOne() || (IsNegative = CLHS->isMinusOne())) {
742 // Add in the sqrt flags.
743 IRBuilder<>::FastMathFlagGuard Guard(Builder);
744 Builder.setFastMathFlags(DivFMF | SqrtFMF);
745
746 if (Den->getType()->isFloatTy()) {
747 if ((DivFMF.approxFunc() && SqrtFMF.approxFunc()) ||
748 canIgnoreDenormalInput(Den, CtxI)) {
749 Value *Result =
750 Builder.CreateUnaryIntrinsic(Intrinsic::amdgcn_rsq, Den);
751 // -1.0 / sqrt(x) -> fneg(rsq(x))
752 return IsNegative ? Builder.CreateFNeg(Result) : Result;
753 }
754
755 return emitRsqIEEE1ULP(Builder, Den, IsNegative);
756 }
757
758 if (Den->getType()->isDoubleTy())
759 return emitRsqF64(Builder, Den, SqrtFMF, DivFMF, CtxI, IsNegative);
760 }
761
762 return nullptr;
763}
764
765// Optimize fdiv with rcp:
766//
767// 1/x -> rcp(x) when rcp is sufficiently accurate or inaccurate rcp is
768// allowed with afn.
769//
770// a/b -> a*rcp(b) when arcp is allowed, and we only need provide ULP 1.0
771Value *
772AMDGPUCodeGenPrepareImpl::optimizeWithRcp(IRBuilder<> &Builder, Value *Num,
773 Value *Den, FastMathFlags FMF,
774 const Instruction *CtxI) const {
775 // rcp_f16 is accurate to 0.51 ulp.
776 // rcp_f32 is accurate for !fpmath >= 1.0ulp and denormals are flushed.
777 // rcp_f64 is never accurate.
778 assert(Den->getType()->isFloatTy());
779
780 if (const ConstantFP *CLHS = dyn_cast<ConstantFP>(Num)) {
781 bool IsNegative = false;
782 if (CLHS->isOne() || (IsNegative = CLHS->isMinusOne())) {
783 Value *Src = Den;
784
785 if (HasFP32DenormalFlush || FMF.approxFunc()) {
786 // -1.0 / x -> 1.0 / fneg(x)
787 if (IsNegative)
788 Src = Builder.CreateFNeg(Src);
789
790 // v_rcp_f32 and v_rsq_f32 do not support denormals, and according to
791 // the CI documentation has a worst case error of 1 ulp.
792 // OpenCL requires <= 2.5 ulp for 1.0 / x, so it should always be OK
793 // to use it as long as we aren't trying to use denormals.
794 //
795 // v_rcp_f16 and v_rsq_f16 DO support denormals.
796
797 // NOTE: v_sqrt and v_rcp will be combined to v_rsq later. So we don't
798 // insert rsq intrinsic here.
799
800 // 1.0 / x -> rcp(x)
801 return Builder.CreateUnaryIntrinsic(Intrinsic::amdgcn_rcp, Src);
802 }
803
804 // TODO: If the input isn't denormal, and we know the input exponent isn't
805 // big enough to introduce a denormal we can avoid the scaling.
806 return emitRcpIEEE1ULP(Builder, Src, IsNegative);
807 }
808 }
809
810 if (FMF.allowReciprocal()) {
811 // x / y -> x * (1.0 / y)
812
813 // TODO: Could avoid denormal scaling and use raw rcp if we knew the output
814 // will never underflow.
815 if (HasFP32DenormalFlush || FMF.approxFunc()) {
816 Value *Recip = Builder.CreateUnaryIntrinsic(Intrinsic::amdgcn_rcp, Den);
817 return Builder.CreateFMul(Num, Recip);
818 }
819
820 Value *Recip = emitRcpIEEE1ULP(Builder, Den, false);
821 return Builder.CreateFMul(Num, Recip);
822 }
823
824 return nullptr;
825}
826
827// optimize with fdiv.fast:
828//
829// a/b -> fdiv.fast(a, b) when !fpmath >= 2.5ulp with denormals flushed.
830//
831// 1/x -> fdiv.fast(1,x) when !fpmath >= 2.5ulp.
832//
833// NOTE: optimizeWithRcp should be tried first because rcp is the preference.
834Value *AMDGPUCodeGenPrepareImpl::optimizeWithFDivFast(
835 IRBuilder<> &Builder, Value *Num, Value *Den, float ReqdAccuracy) const {
836 // fdiv.fast can achieve 2.5 ULP accuracy.
837 if (ReqdAccuracy < 2.5f)
838 return nullptr;
839
840 // Only have fdiv.fast for f32.
841 assert(Den->getType()->isFloatTy());
842
843 bool NumIsOne = false;
844 if (const ConstantFP *CNum = dyn_cast<ConstantFP>(Num)) {
845 if (CNum->isOne() || CNum->isMinusOne())
846 NumIsOne = true;
847 }
848
849 // fdiv does not support denormals. But 1.0/x is always fine to use it.
850 //
851 // TODO: This works for any value with a specific known exponent range, don't
852 // just limit to constant 1.
853 if (!HasFP32DenormalFlush && !NumIsOne)
854 return nullptr;
855
856 return Builder.CreateIntrinsic(Intrinsic::amdgcn_fdiv_fast, {Num, Den});
857}
858
859Value *AMDGPUCodeGenPrepareImpl::visitFDivElement(
860 IRBuilder<> &Builder, Value *Num, Value *Den, FastMathFlags DivFMF,
861 FastMathFlags SqrtFMF, Value *RsqOp, const Instruction *FDivInst,
862 float ReqdDivAccuracy) const {
863 if (RsqOp) {
864 Value *Rsq =
865 optimizeWithRsq(Builder, Num, RsqOp, DivFMF, SqrtFMF, FDivInst);
866 if (Rsq)
867 return Rsq;
868 }
869
870 if (!Num->getType()->isFloatTy())
871 return nullptr;
872
873 Value *Rcp = optimizeWithRcp(Builder, Num, Den, DivFMF, FDivInst);
874 if (Rcp)
875 return Rcp;
876
877 // In the basic case fdiv_fast has the same instruction count as the frexp div
878 // expansion. Slightly prefer fdiv_fast since it ends in an fmul that can
879 // potentially be fused into a user. Also, materialization of the constants
880 // can be reused for multiple instances.
881 Value *FDivFast = optimizeWithFDivFast(Builder, Num, Den, ReqdDivAccuracy);
882 if (FDivFast)
883 return FDivFast;
884
885 return emitFrexpDiv(Builder, Num, Den, DivFMF);
886}
887
888// Optimizations is performed based on fpmath, fast math flags as well as
889// denormals to optimize fdiv with either rcp or fdiv.fast.
890//
891// With rcp:
892// 1/x -> rcp(x) when rcp is sufficiently accurate or inaccurate rcp is
893// allowed with afn.
894//
895// a/b -> a*rcp(b) when inaccurate rcp is allowed with afn.
896//
897// With fdiv.fast:
898// a/b -> fdiv.fast(a, b) when !fpmath >= 2.5ulp with denormals flushed.
899//
900// 1/x -> fdiv.fast(1,x) when !fpmath >= 2.5ulp.
901//
902// NOTE: rcp is the preference in cases that both are legal.
903bool AMDGPUCodeGenPrepareImpl::visitFDiv(BinaryOperator &FDiv) {
904 if (DisableFDivExpand)
905 return false;
906
907 Type *Ty = FDiv.getType()->getScalarType();
908 const bool IsFloat = Ty->isFloatTy();
909 if (!IsFloat && !Ty->isDoubleTy())
910 return false;
911
912 // The f64 rcp/rsq approximations are pretty inaccurate. We can do an
913 // expansion around them in codegen. f16 is good enough to always use.
914
915 const FPMathOperator *FPOp = cast<const FPMathOperator>(&FDiv);
916 const FastMathFlags DivFMF = FPOp->getFastMathFlags();
917 const float ReqdAccuracy = FPOp->getFPAccuracy();
918
919 FastMathFlags SqrtFMF;
920
921 Value *Num = FDiv.getOperand(0);
922 Value *Den = FDiv.getOperand(1);
923
924 Value *RsqOp = nullptr;
925 auto *DenII = dyn_cast<IntrinsicInst>(Den);
926 if (DenII && DenII->getIntrinsicID() == Intrinsic::sqrt &&
927 DenII->hasOneUse()) {
928 const auto *SqrtOp = cast<FPMathOperator>(DenII);
929 SqrtFMF = SqrtOp->getFastMathFlags();
930 if (canOptimizeWithRsq(DivFMF, SqrtFMF))
931 RsqOp = SqrtOp->getOperand(0);
932 }
933
934 // rcp path not yet implemented for f64.
935 if (!IsFloat && !RsqOp)
936 return false;
937
938 // Inaccurate rcp is allowed with afn.
939 //
940 // Defer to codegen to handle this.
941 //
942 // TODO: Decide on an interpretation for interactions between afn + arcp +
943 // !fpmath, and make it consistent between here and codegen. For now, defer
944 // expansion of afn to codegen. The current interpretation is so aggressive we
945 // don't need any pre-consideration here when we have better information. A
946 // more conservative interpretation could use handling here.
947 const bool AllowInaccurateRcp = DivFMF.approxFunc();
948 if (!RsqOp && AllowInaccurateRcp)
949 return false;
950
951 // Defer the correct implementations to codegen.
952 if (IsFloat && ReqdAccuracy < 1.0f)
953 return false;
954
955 IRBuilder<> Builder(FDiv.getParent(), std::next(FDiv.getIterator()));
956 Builder.setFastMathFlags(DivFMF);
957 Builder.SetCurrentDebugLocation(FDiv.getDebugLoc());
958
959 SmallVector<Value *, 4> NumVals;
960 SmallVector<Value *, 4> DenVals;
961 SmallVector<Value *, 4> RsqDenVals;
962 extractValues(Builder, NumVals, Num);
963 extractValues(Builder, DenVals, Den);
964
965 if (RsqOp)
966 extractValues(Builder, RsqDenVals, RsqOp);
967
968 SmallVector<Value *, 4> ResultVals(NumVals.size());
969 for (int I = 0, E = NumVals.size(); I != E; ++I) {
970 Value *NumElt = NumVals[I];
971 Value *DenElt = DenVals[I];
972 Value *RsqDenElt = RsqOp ? RsqDenVals[I] : nullptr;
973
974 Value *NewElt =
975 visitFDivElement(Builder, NumElt, DenElt, DivFMF, SqrtFMF, RsqDenElt,
976 cast<Instruction>(FPOp), ReqdAccuracy);
977 if (!NewElt) {
978 // Keep the original, but scalarized.
979
980 // This has the unfortunate side effect of sometimes scalarizing when
981 // we're not going to do anything.
982 NewElt = Builder.CreateFDiv(NumElt, DenElt);
983 if (auto *NewEltInst = dyn_cast<Instruction>(NewElt))
984 NewEltInst->copyMetadata(FDiv);
985 }
986
987 ResultVals[I] = NewElt;
988 }
989
990 Value *NewVal = insertValues(Builder, FDiv.getType(), ResultVals);
991
992 if (NewVal) {
993 FDiv.replaceAllUsesWith(NewVal);
994 NewVal->takeName(&FDiv);
995 DeadVals.push_back(&FDiv);
996 }
997
998 return true;
999}
1000
1001static std::pair<Value*, Value*> getMul64(IRBuilder<> &Builder,
1002 Value *LHS, Value *RHS) {
1003 Type *I32Ty = Builder.getInt32Ty();
1004 Type *I64Ty = Builder.getInt64Ty();
1005
1006 Value *LHS_EXT64 = Builder.CreateZExt(LHS, I64Ty);
1007 Value *RHS_EXT64 = Builder.CreateZExt(RHS, I64Ty);
1008 Value *MUL64 = Builder.CreateMul(LHS_EXT64, RHS_EXT64);
1009 Value *Lo = Builder.CreateTrunc(MUL64, I32Ty);
1010 Value *Hi = Builder.CreateLShr(MUL64, Builder.getInt64(32));
1011 Hi = Builder.CreateTrunc(Hi, I32Ty);
1012 return std::pair(Lo, Hi);
1013}
1014
1015static Value* getMulHu(IRBuilder<> &Builder, Value *LHS, Value *RHS) {
1016 return getMul64(Builder, LHS, RHS).second;
1017}
1018
1019/// Figure out how many bits are really needed for this division.
1020/// \p MaxDivBits is an optimization hint to bypass the second
1021/// ComputeNumSignBits/computeKnownBits call if the first one is
1022/// insufficient.
1023unsigned AMDGPUCodeGenPrepareImpl::getDivNumBits(BinaryOperator &I, Value *Num,
1024 Value *Den,
1025 unsigned MaxDivBits,
1026 bool IsSigned) const {
1028 Den->getType()->getScalarSizeInBits());
1029 unsigned SSBits = Num->getType()->getScalarSizeInBits();
1030 if (IsSigned) {
1031 unsigned RHSSignBits = ComputeNumSignBits(Den, SQ.DL, SQ.AC, &I, SQ.DT);
1032 // A sign bit needs to be reserved for shrinking.
1033 unsigned DivBits = SSBits - RHSSignBits + 1;
1034 if (DivBits > MaxDivBits)
1035 return SSBits;
1036
1037 unsigned LHSSignBits = ComputeNumSignBits(Num, SQ.DL, SQ.AC, &I);
1038
1039 unsigned SignBits = std::min(LHSSignBits, RHSSignBits);
1040 DivBits = SSBits - SignBits + 1;
1041 return DivBits;
1042 }
1043
1044 // All bits are used for unsigned division for Num or Den in range
1045 // (SignedMax, UnsignedMax].
1046 KnownBits Known = computeKnownBits(Den, SQ.getWithInstruction(&I));
1047 unsigned RHSBits = Known.countMaxActiveBits();
1048 if (RHSBits > MaxDivBits)
1049 return SSBits;
1050
1052 unsigned LHSBits = Known.countMaxActiveBits();
1053
1054 unsigned DivBits = std::max(LHSBits, RHSBits);
1055 return DivBits;
1056}
1057
1058Value *AMDGPUCodeGenPrepareImpl::expandDivRemToFloat(IRBuilder<> &Builder,
1059 BinaryOperator &I,
1060 Value *Num, Value *Den,
1061 bool IsDiv,
1062 bool IsSigned) const {
1063 unsigned DivBits = getDivNumBits(I, Num, Den, 23, IsSigned);
1064
1065 if (DivBits > (IsSigned ? 23 : 22))
1066 return nullptr;
1067 return expandDivRemToFloatImpl(Builder, I, Num, Den, DivBits, IsDiv,
1068 IsSigned);
1069}
1070
1071Value *AMDGPUCodeGenPrepareImpl::expandDivRemToFloatImpl(
1072 IRBuilder<> &Builder, BinaryOperator &I, Value *Num, Value *Den,
1073 unsigned DivBits, bool IsDiv, bool IsSigned) const {
1074
1075 // v_rcp_f32(float(X)) can have an error of 1 ulp.
1076 // This would cause incorrect calculation of Y/X if:
1077 // Y = (0x7FFFFF/X)*(X-0)-1
1078 // were allowed.
1079 //
1080 // For example,
1081 // (0x7FF6D3/0x000FE7) would erroneously produce 2060 instead of 2059.
1082 // (0x7FF8F5/0x007EFB) would erroneously produce 258 instead of 257.
1083 //
1084 // Thus, we conservatively restrict expandDivRemToFloatImpl to
1085 // [-0x400000,0x3FFFFF] for IsSigned
1086 // [ 0x000000,0x3FFFFF] for !IsSigned.
1087 assert(0 < DivBits && DivBits <= (IsSigned ? 23 : 22) &&
1088 "abs(Num) must be <= 0x400000 for expandDivRemToFloatImpl to work "
1089 "correctly");
1090
1091 Type *I32Ty = Builder.getInt32Ty();
1092 Num = Builder.CreateTrunc(Num, I32Ty);
1093 Den = Builder.CreateTrunc(Den, I32Ty);
1094
1095 Type *F32Ty = Builder.getFloatTy();
1096 ConstantInt *One = Builder.getInt32(1);
1097
1098 // int ia = (int)LHS;
1099 Value *IA = Num;
1100
1101 // int ib, (int)RHS;
1102 Value *IB = Den;
1103
1104 // float fa = (float)ia;
1105 Value *FA = IsSigned ? Builder.CreateSIToFP(IA, F32Ty)
1106 : Builder.CreateUIToFP(IA, F32Ty);
1107
1108 // float fb = (float)ib;
1109 Value *FB = IsSigned ? Builder.CreateSIToFP(IB, F32Ty)
1110 : Builder.CreateUIToFP(IB, F32Ty);
1111
1112 Value *RCP = Builder.CreateIntrinsic(Intrinsic::amdgcn_rcp,
1113 Builder.getFloatTy(), {FB});
1114
1115 // The calculation:
1116 // fq = fa*recip(fb)
1117 // may be too small due to the 1ulp accuracy in the recip
1118 // operation and rounding issues. Since fq is truncated to produce
1119 // an integer value it may be too small by one. This is
1120 // dealt with by incrementing fa by 1ulp:
1121 // fq = (fa+1ulp)*recip(fb)
1122 // This will increase fa's magnitude by at most 0.5
1123 // (i.e. when fabs(fa)==0x400000 the LSB of the mantissa represents 0.5).
1124 // Thus, this method is safe since fa must be incremented by at least 1.0
1125 // for the quotient to increase by one.
1126
1127 Value *FABits = Builder.CreateBitCast(FA, I32Ty);
1128 Value *FABitsInc = Builder.CreateAdd(FABits, One);
1129 FA = Builder.CreateBitCast(FABitsInc, F32Ty);
1130
1131 Value *FQM = Builder.CreateFMul(FA, RCP);
1132
1133 // fq = trunc(fqm);
1134 Value *FQ = Builder.CreateUnaryIntrinsic(Intrinsic::trunc, FQM);
1135
1136 // int iq = (int)fq;
1137 Value *IQ = IsSigned ? Builder.CreateFPToSI(FQ, I32Ty)
1138 : Builder.CreateFPToUI(FQ, I32Ty);
1139
1140 Value *Res = IQ;
1141 if (!IsDiv) {
1142 // Rem needs compensation, it's easier to recompute it
1143 Value *Rem = Builder.CreateMul(IQ, Den);
1144 Res = Builder.CreateSub(Num, Rem);
1145 }
1146
1147 return Res;
1148}
1149
1150// Try to recognize special cases the DAG will emit special, better expansions
1151// than the general expansion we do here.
1152
1153// TODO: It would be better to just directly handle those optimizations here.
1154bool AMDGPUCodeGenPrepareImpl::divHasSpecialOptimization(BinaryOperator &I,
1155 Value *Num,
1156 Value *Den) const {
1157 if (Constant *C = dyn_cast<Constant>(Den)) {
1158 // Arbitrary constants get a better expansion as long as a wider mulhi is
1159 // legal.
1160 if (C->getType()->getScalarSizeInBits() <= 32)
1161 return true;
1162
1163 // TODO: Sdiv check for not exact for some reason.
1164
1165 // If there's no wider mulhi, there's only a better expansion for powers of
1166 // two.
1167 // TODO: Should really know for each vector element.
1169 return true;
1170
1171 return false;
1172 }
1173
1174 if (BinaryOperator *BinOpDen = dyn_cast<BinaryOperator>(Den)) {
1175 // fold (udiv x, (shl c, y)) -> x >>u (log2(c)+y) iff c is power of 2
1176 if (BinOpDen->getOpcode() == Instruction::Shl &&
1177 isa<Constant>(BinOpDen->getOperand(0)) &&
1178 isKnownToBeAPowerOfTwo(BinOpDen->getOperand(0), true,
1179 SQ.getWithInstruction(&I))) {
1180 return true;
1181 }
1182 }
1183
1184 return false;
1185}
1186
1187static Value *getSign32(Value *V, IRBuilder<> &Builder, const DataLayout DL) {
1188 // Check whether the sign can be determined statically.
1190 if (Known.isNegative())
1191 return Constant::getAllOnesValue(V->getType());
1192 if (Known.isNonNegative())
1193 return Constant::getNullValue(V->getType());
1194 return Builder.CreateAShr(V, Builder.getInt32(31));
1195}
1196
1197Value *AMDGPUCodeGenPrepareImpl::expandDivRem32(IRBuilder<> &Builder,
1198 BinaryOperator &I, Value *X,
1199 Value *Y) const {
1200 Instruction::BinaryOps Opc = I.getOpcode();
1201 assert(Opc == Instruction::URem || Opc == Instruction::UDiv ||
1202 Opc == Instruction::SRem || Opc == Instruction::SDiv);
1203
1204 FastMathFlags FMF;
1205 FMF.setFast();
1206 Builder.setFastMathFlags(FMF);
1207
1208 if (divHasSpecialOptimization(I, X, Y))
1209 return nullptr; // Keep it for later optimization.
1210
1211 bool IsDiv = Opc == Instruction::UDiv || Opc == Instruction::SDiv;
1212 bool IsSigned = Opc == Instruction::SRem || Opc == Instruction::SDiv;
1213
1214 Type *Ty = X->getType();
1215 Type *I32Ty = Builder.getInt32Ty();
1216 Type *F32Ty = Builder.getFloatTy();
1217
1218 if (Ty->getScalarSizeInBits() != 32) {
1219 if (IsSigned) {
1220 X = Builder.CreateSExtOrTrunc(X, I32Ty);
1221 Y = Builder.CreateSExtOrTrunc(Y, I32Ty);
1222 } else {
1223 X = Builder.CreateZExtOrTrunc(X, I32Ty);
1224 Y = Builder.CreateZExtOrTrunc(Y, I32Ty);
1225 }
1226 }
1227
1228 if (Value *Res = expandDivRemToFloat(Builder, I, X, Y, IsDiv, IsSigned)) {
1229 return IsSigned ? Builder.CreateSExtOrTrunc(Res, Ty) :
1230 Builder.CreateZExtOrTrunc(Res, Ty);
1231 }
1232
1233 ConstantInt *Zero = Builder.getInt32(0);
1234 ConstantInt *One = Builder.getInt32(1);
1235
1236 Value *Sign = nullptr;
1237 if (IsSigned) {
1238 Value *SignX = getSign32(X, Builder, DL);
1239 Value *SignY = getSign32(Y, Builder, DL);
1240 // Remainder sign is the same as LHS
1241 Sign = IsDiv ? Builder.CreateXor(SignX, SignY) : SignX;
1242
1243 X = Builder.CreateAdd(X, SignX);
1244 Y = Builder.CreateAdd(Y, SignY);
1245
1246 X = Builder.CreateXor(X, SignX);
1247 Y = Builder.CreateXor(Y, SignY);
1248 }
1249
1250 // The algorithm here is based on ideas from "Software Integer Division", Tom
1251 // Rodeheffer, August 2008.
1252 //
1253 // unsigned udiv(unsigned x, unsigned y) {
1254 // // Initial estimate of inv(y). The constant is less than 2^32 to ensure
1255 // // that this is a lower bound on inv(y), even if some of the calculations
1256 // // round up.
1257 // unsigned z = (unsigned)((4294967296.0 - 512.0) * v_rcp_f32((float)y));
1258 //
1259 // // One round of UNR (Unsigned integer Newton-Raphson) to improve z.
1260 // // Empirically this is guaranteed to give a "two-y" lower bound on
1261 // // inv(y).
1262 // z += umulh(z, -y * z);
1263 //
1264 // // Quotient/remainder estimate.
1265 // unsigned q = umulh(x, z);
1266 // unsigned r = x - q * y;
1267 //
1268 // // Two rounds of quotient/remainder refinement.
1269 // if (r >= y) {
1270 // ++q;
1271 // r -= y;
1272 // }
1273 // if (r >= y) {
1274 // ++q;
1275 // r -= y;
1276 // }
1277 //
1278 // return q;
1279 // }
1280
1281 // Initial estimate of inv(y).
1282 Value *FloatY = Builder.CreateUIToFP(Y, F32Ty);
1283 Value *RcpY = Builder.CreateIntrinsic(Intrinsic::amdgcn_rcp, F32Ty, {FloatY});
1284 Constant *Scale = ConstantFP::get(F32Ty, llvm::bit_cast<float>(0x4F7FFFFE));
1285 Value *ScaledY = Builder.CreateFMul(RcpY, Scale);
1286 Value *Z = Builder.CreateFPToUI(ScaledY, I32Ty);
1287
1288 // One round of UNR.
1289 Value *NegY = Builder.CreateSub(Zero, Y);
1290 Value *NegYZ = Builder.CreateMul(NegY, Z);
1291 Z = Builder.CreateAdd(Z, getMulHu(Builder, Z, NegYZ));
1292
1293 // Quotient/remainder estimate.
1294 Value *Q = getMulHu(Builder, X, Z);
1295 Value *R = Builder.CreateSub(X, Builder.CreateMul(Q, Y));
1296
1297 // First quotient/remainder refinement.
1298 Value *Cond = Builder.CreateICmpUGE(R, Y);
1299 if (IsDiv)
1300 Q = Builder.CreateSelect(Cond, Builder.CreateAdd(Q, One), Q);
1301 R = Builder.CreateSelect(Cond, Builder.CreateSub(R, Y), R);
1302
1303 // Second quotient/remainder refinement.
1304 Cond = Builder.CreateICmpUGE(R, Y);
1305 Value *Res;
1306 if (IsDiv)
1307 Res = Builder.CreateSelect(Cond, Builder.CreateAdd(Q, One), Q);
1308 else
1309 Res = Builder.CreateSelect(Cond, Builder.CreateSub(R, Y), R);
1310
1311 if (IsSigned) {
1312 Res = Builder.CreateXor(Res, Sign);
1313 Res = Builder.CreateSub(Res, Sign);
1314 Res = Builder.CreateSExtOrTrunc(Res, Ty);
1315 } else {
1316 Res = Builder.CreateZExtOrTrunc(Res, Ty);
1317 }
1318 return Res;
1319}
1320
1321Value *AMDGPUCodeGenPrepareImpl::shrinkDivRem64(IRBuilder<> &Builder,
1322 BinaryOperator &I, Value *Num,
1323 Value *Den) const {
1324 if (!ExpandDiv64InIR && divHasSpecialOptimization(I, Num, Den))
1325 return nullptr; // Keep it for later optimization.
1326
1327 Instruction::BinaryOps Opc = I.getOpcode();
1328
1329 bool IsDiv = Opc == Instruction::SDiv || Opc == Instruction::UDiv;
1330 bool IsSigned = Opc == Instruction::SDiv || Opc == Instruction::SRem;
1331
1332 unsigned NumDivBits = getDivNumBits(I, Num, Den, 32, IsSigned);
1333 if (NumDivBits > 32)
1334 return nullptr;
1335
1336 Value *Narrowed = nullptr;
1337 if (NumDivBits <= (IsSigned ? 23 : 22)) {
1338 Narrowed = expandDivRemToFloatImpl(Builder, I, Num, Den, NumDivBits, IsDiv,
1339 IsSigned);
1340 } else if (NumDivBits <= (IsSigned ? 31 : 32)) {
1341 // Do not use 32-bit division if dividend may be -2147483648.
1342 // Otherwise 32-bit division cannot be used safely.
1343 // -2147483648/1 and -2147483648/-1 are not equal,
1344 // but they produce the same lower 32-bit result.
1345 Narrowed = expandDivRem32(Builder, I, Num, Den);
1346 }
1347
1348 if (Narrowed) {
1349 return IsSigned ? Builder.CreateSExt(Narrowed, Num->getType()) :
1350 Builder.CreateZExt(Narrowed, Num->getType());
1351 }
1352
1353 return nullptr;
1354}
1355
1356void AMDGPUCodeGenPrepareImpl::expandDivRem64(BinaryOperator &I) const {
1357 Instruction::BinaryOps Opc = I.getOpcode();
1358 // Do the general expansion.
1359 if (Opc == Instruction::UDiv || Opc == Instruction::SDiv) {
1361 return;
1362 }
1363
1364 if (Opc == Instruction::URem || Opc == Instruction::SRem) {
1366 return;
1367 }
1368
1369 llvm_unreachable("not a division");
1370}
1371
1372/*
1373This will cause non-byte load in consistency, for example:
1374```
1375 %load = load i1, ptr addrspace(4) %arg, align 4
1376 %zext = zext i1 %load to
1377 i64 %add = add i64 %zext
1378```
1379Instead of creating `s_and_b32 s0, s0, 1`,
1380it will create `s_and_b32 s0, s0, 0xff`.
1381We accept this change since the non-byte load assumes the upper bits
1382within the byte are all 0.
1383*/
1384bool AMDGPUCodeGenPrepareImpl::tryNarrowMathIfNoOverflow(Instruction *I) {
1385 unsigned Opc = I->getOpcode();
1386 Type *OldType = I->getType();
1387
1388 if (Opc != Instruction::Add && Opc != Instruction::Mul)
1389 return false;
1390
1391 unsigned OrigBit = OldType->getScalarSizeInBits();
1392
1393 if (Opc != Instruction::Add && Opc != Instruction::Mul)
1394 llvm_unreachable("Unexpected opcode, only valid for Instruction::Add and "
1395 "Instruction::Mul.");
1396
1397 unsigned MaxBitsNeeded = computeKnownBits(I, DL).countMaxActiveBits();
1398
1399 MaxBitsNeeded = std::max<unsigned>(bit_ceil(MaxBitsNeeded), 8);
1400 Type *NewType = DL.getSmallestLegalIntType(I->getContext(), MaxBitsNeeded);
1401 if (!NewType)
1402 return false;
1403 unsigned NewBit = NewType->getIntegerBitWidth();
1404 if (NewBit >= OrigBit)
1405 return false;
1406 NewType = I->getType()->getWithNewBitWidth(NewBit);
1407
1408 // Old cost
1409 const TargetTransformInfo &TTI = TM.getTargetTransformInfo(F);
1410 InstructionCost OldCost =
1412 // New cost of new op
1413 InstructionCost NewCost =
1415 // New cost of narrowing 2 operands (use trunc)
1416 int NumOfNonConstOps = 2;
1417 if (isa<Constant>(I->getOperand(0)) || isa<Constant>(I->getOperand(1))) {
1418 // Cannot be both constant, should be propagated
1419 NumOfNonConstOps = 1;
1420 }
1421 NewCost += NumOfNonConstOps * TTI.getCastInstrCost(Instruction::Trunc,
1422 NewType, OldType,
1425 // New cost of zext narrowed result to original type
1426 NewCost +=
1427 TTI.getCastInstrCost(Instruction::ZExt, OldType, NewType,
1429 if (NewCost >= OldCost)
1430 return false;
1431
1432 IRBuilder<> Builder(I);
1433 Value *Trunc0 = Builder.CreateTrunc(I->getOperand(0), NewType);
1434 Value *Trunc1 = Builder.CreateTrunc(I->getOperand(1), NewType);
1435 Value *Arith =
1436 Builder.CreateBinOp((Instruction::BinaryOps)Opc, Trunc0, Trunc1);
1437
1438 Value *Zext = Builder.CreateZExt(Arith, OldType);
1439 I->replaceAllUsesWith(Zext);
1440 DeadVals.push_back(I);
1441 return true;
1442}
1443
1444bool AMDGPUCodeGenPrepareImpl::visitBinaryOperator(BinaryOperator &I) {
1445 if (foldBinOpIntoSelect(I))
1446 return true;
1447
1448 if (UseMul24Intrin && replaceMulWithMul24(I))
1449 return true;
1450 if (tryNarrowMathIfNoOverflow(&I))
1451 return true;
1452
1453 bool Changed = false;
1454 Instruction::BinaryOps Opc = I.getOpcode();
1455 Type *Ty = I.getType();
1456 Value *NewDiv = nullptr;
1457 unsigned ScalarSize = Ty->getScalarSizeInBits();
1458
1460
1461 if ((Opc == Instruction::URem || Opc == Instruction::UDiv ||
1462 Opc == Instruction::SRem || Opc == Instruction::SDiv) &&
1463 ScalarSize <= 64 &&
1464 !DisableIDivExpand) {
1465 Value *Num = I.getOperand(0);
1466 Value *Den = I.getOperand(1);
1467 IRBuilder<> Builder(&I);
1468 Builder.SetCurrentDebugLocation(I.getDebugLoc());
1469
1470 if (auto *VT = dyn_cast<FixedVectorType>(Ty)) {
1471 NewDiv = PoisonValue::get(VT);
1472
1473 for (unsigned N = 0, E = VT->getNumElements(); N != E; ++N) {
1474 Value *NumEltN = Builder.CreateExtractElement(Num, N);
1475 Value *DenEltN = Builder.CreateExtractElement(Den, N);
1476
1477 Value *NewElt;
1478 if (ScalarSize <= 32) {
1479 NewElt = expandDivRem32(Builder, I, NumEltN, DenEltN);
1480 if (!NewElt)
1481 NewElt = Builder.CreateBinOp(Opc, NumEltN, DenEltN);
1482 } else {
1483 // See if this 64-bit division can be shrunk to 32/24-bits before
1484 // producing the general expansion.
1485 NewElt = shrinkDivRem64(Builder, I, NumEltN, DenEltN);
1486 if (!NewElt) {
1487 // The general 64-bit expansion introduces control flow and doesn't
1488 // return the new value. Just insert a scalar copy and defer
1489 // expanding it.
1490 NewElt = Builder.CreateBinOp(Opc, NumEltN, DenEltN);
1491 // CreateBinOp does constant folding. If the operands are constant,
1492 // it will return a Constant instead of a BinaryOperator.
1493 if (auto *NewEltBO = dyn_cast<BinaryOperator>(NewElt))
1494 Div64ToExpand.push_back(NewEltBO);
1495 }
1496 }
1497
1498 if (auto *NewEltI = dyn_cast<Instruction>(NewElt))
1499 NewEltI->copyIRFlags(&I);
1500
1501 NewDiv = Builder.CreateInsertElement(NewDiv, NewElt, N);
1502 }
1503 } else {
1504 if (ScalarSize <= 32)
1505 NewDiv = expandDivRem32(Builder, I, Num, Den);
1506 else {
1507 NewDiv = shrinkDivRem64(Builder, I, Num, Den);
1508 if (!NewDiv)
1509 Div64ToExpand.push_back(&I);
1510 }
1511 }
1512
1513 if (NewDiv) {
1514 I.replaceAllUsesWith(NewDiv);
1515 DeadVals.push_back(&I);
1516 Changed = true;
1517 }
1518 }
1519
1520 if (ExpandDiv64InIR) {
1521 // TODO: We get much worse code in specially handled constant cases.
1522 for (BinaryOperator *Div : Div64ToExpand) {
1523 expandDivRem64(*Div);
1524 FlowChanged = true;
1525 Changed = true;
1526 }
1527 }
1528
1529 return Changed;
1530}
1531
1532bool AMDGPUCodeGenPrepareImpl::visitLoadInst(LoadInst &I) {
1533 if (!WidenLoads)
1534 return false;
1535
1536 if ((I.getPointerAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS ||
1537 I.getPointerAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS_32BIT) &&
1538 canWidenScalarExtLoad(I)) {
1539 IRBuilder<> Builder(&I);
1540 Builder.SetCurrentDebugLocation(I.getDebugLoc());
1541
1542 Type *I32Ty = Builder.getInt32Ty();
1543 LoadInst *WidenLoad = Builder.CreateLoad(I32Ty, I.getPointerOperand());
1545
1546 // The widened load reads the original bytes in the low bits, so a !range
1547 // lower bound still holds. Convert it to the new type and don't make
1548 // assumptions about the high bits.
1549 if (auto *Range = I.getMetadata(LLVMContext::MD_range)) {
1550 ConstantInt *Lower = mdconst::extract<ConstantInt>(Range->getOperand(0));
1551
1552 if (!Lower->isNullValue()) {
1553 Metadata *LowAndHigh[] = {
1554 ConstantAsMetadata::get(ConstantInt::get(I32Ty, Lower->getValue().zext(32))),
1555 // Don't make assumptions about the high bits.
1556 ConstantAsMetadata::get(ConstantInt::get(I32Ty, 0))
1557 };
1558
1559 WidenLoad->setMetadata(LLVMContext::MD_range,
1560 MDNode::get(F.getContext(), LowAndHigh));
1561 }
1562 }
1563
1564 int TySize = DL.getTypeSizeInBits(I.getType());
1565 Type *IntNTy = Builder.getIntNTy(TySize);
1566 Value *ValTrunc = Builder.CreateTrunc(WidenLoad, IntNTy);
1567 Value *ValOrig = Builder.CreateBitCast(ValTrunc, I.getType());
1568 I.replaceAllUsesWith(ValOrig);
1569 DeadVals.push_back(&I);
1570 return true;
1571 }
1572
1573 return false;
1574}
1575
1576bool AMDGPUCodeGenPrepareImpl::visitSelectInst(SelectInst &I) {
1577 FPMathOperator *FPOp = dyn_cast<FPMathOperator>(&I);
1578 if (!FPOp)
1579 return false;
1580
1581 Value *X;
1582 Value *Fract = nullptr;
1583
1584 // Match:
1585 // (x - floor(x)) >= MIN_CONSTANT ? MIN_CONSTANT : (x - floor(x))
1586 //
1587 // This is the preferred way to implement fract.
1588 // TODO: Could also match with compare against 1.0
1589 const APFloat *C;
1591 Value *FractSrc = matchFractPatImpl(*X, *C);
1592 if (!FractSrc)
1593 return false;
1594 IRBuilder<> Builder(&I);
1595 Builder.setFastMathFlags(FPOp->getFastMathFlags());
1596 Fract = applyFractPat(Builder, FractSrc);
1597 } else {
1598 // Match patterns which may appear in legacy implementations of the fract()
1599 // function, built around the nan-avoidant minnum intrinsic. These are the
1600 // core pattern plus additional clamping of inf and nan values on the
1601 // result.
1602 Value *Cond = I.getCondition();
1603 Value *TrueVal = I.getTrueValue();
1604 Value *FalseVal = I.getFalseValue();
1605 Value *CmpVal;
1606 CmpPredicate IsNanPred;
1607
1608 // Match fract pattern with nan check.
1609 if (!match(Cond, m_FCmp(IsNanPred, m_Value(CmpVal), m_NonNaN())))
1610 return false;
1611
1612 IRBuilder<> Builder(&I);
1613 Builder.setFastMathFlags(FPOp->getFastMathFlags());
1614
1615 if (IsNanPred == FCmpInst::FCMP_UNO && TrueVal == CmpVal &&
1616 CmpVal == matchFractPatNanAvoidant(*FalseVal)) {
1617 // isnan(x) ? x : fract(x)
1618 Fract = applyFractPat(Builder, CmpVal);
1619 } else if (IsNanPred == FCmpInst::FCMP_ORD && FalseVal == CmpVal) {
1620 if (CmpVal == matchFractPatNanAvoidant(*TrueVal)) {
1621 // !isnan(x) ? fract(x) : x
1622 Fract = applyFractPat(Builder, CmpVal);
1623 } else {
1624 // Match an intermediate clamp infinity to 0 pattern. i.e.
1625 // !isnan(x) ? (!isinf(x) ? fract(x) : 0.0) : x
1626 CmpPredicate PredInf;
1627 Value *IfNotInf;
1628
1629 if (!match(TrueVal, m_Select(m_FCmp(PredInf, m_FAbs(m_Specific(CmpVal)),
1630 m_PosInf()),
1631 m_Value(IfNotInf), m_PosZeroFP())) ||
1632 PredInf != FCmpInst::FCMP_UNE ||
1633 CmpVal != matchFractPatNanAvoidant(*IfNotInf))
1634 return false;
1635
1636 SelectInst *ClampInfSelect = cast<SelectInst>(TrueVal);
1637
1638 // Insert before the fabs
1639 Value *InsertPt =
1640 cast<Instruction>(ClampInfSelect->getCondition())->getOperand(0);
1641
1642 Builder.SetInsertPoint(cast<Instruction>(InsertPt));
1643 Value *NewFract = applyFractPat(Builder, CmpVal);
1644 NewFract->takeName(TrueVal);
1645
1646 // Thread the new fract into the inf clamping sequence.
1647 DeadVals.push_back(ClampInfSelect->getOperand(1));
1648 ClampInfSelect->setOperand(1, NewFract);
1649
1650 // The outer select nan handling is also absorbed into the fract.
1651 Fract = ClampInfSelect;
1652 }
1653 } else
1654 return false;
1655 }
1656
1657 Fract->takeName(&I);
1658 I.replaceAllUsesWith(Fract);
1659 DeadVals.push_back(&I);
1660 return true;
1661}
1662
1663static bool areInSameBB(const Value *A, const Value *B) {
1664 const auto *IA = dyn_cast<Instruction>(A);
1665 const auto *IB = dyn_cast<Instruction>(B);
1666 return IA && IB && IA->getParent() == IB->getParent();
1667}
1668
1669// Helper for breaking large PHIs that returns true when an extractelement on V
1670// is likely to be folded away by the DAG combiner.
1672 const auto *FVT = dyn_cast<FixedVectorType>(V->getType());
1673 if (!FVT)
1674 return false;
1675
1676 const Value *CurVal = V;
1677
1678 // Check for insertelements, keeping track of the elements covered.
1679 BitVector EltsCovered(FVT->getNumElements());
1680 while (const auto *IE = dyn_cast<InsertElementInst>(CurVal)) {
1681 const auto *Idx = dyn_cast<ConstantInt>(IE->getOperand(2));
1682
1683 // Non constant index/out of bounds index -> folding is unlikely.
1684 // The latter is more of a sanity check because canonical IR should just
1685 // have replaced those with poison.
1686 if (!Idx || Idx->getZExtValue() >= FVT->getNumElements())
1687 return false;
1688
1689 const auto *VecSrc = IE->getOperand(0);
1690
1691 // If the vector source is another instruction, it must be in the same basic
1692 // block. Otherwise, the DAGCombiner won't see the whole thing and is
1693 // unlikely to be able to do anything interesting here.
1694 if (isa<Instruction>(VecSrc) && !areInSameBB(VecSrc, IE))
1695 return false;
1696
1697 CurVal = VecSrc;
1698 EltsCovered.set(Idx->getZExtValue());
1699
1700 // All elements covered.
1701 if (EltsCovered.all())
1702 return true;
1703 }
1704
1705 // We either didn't find a single insertelement, or the insertelement chain
1706 // ended before all elements were covered. Check for other interesting values.
1707
1708 // Constants are always interesting because we can just constant fold the
1709 // extractelements.
1710 if (isa<Constant>(CurVal))
1711 return true;
1712
1713 // shufflevector is likely to be profitable if either operand is a constant,
1714 // or if either source is in the same block.
1715 // This is because shufflevector is most often lowered as a series of
1716 // insert/extract elements anyway.
1717 if (const auto *SV = dyn_cast<ShuffleVectorInst>(CurVal)) {
1718 return isa<Constant>(SV->getOperand(1)) ||
1719 areInSameBB(SV, SV->getOperand(0)) ||
1720 areInSameBB(SV, SV->getOperand(1));
1721 }
1722
1723 return false;
1724}
1725
1726static void collectPHINodes(const PHINode &I,
1728 const auto [It, Inserted] = SeenPHIs.insert(&I);
1729 if (!Inserted)
1730 return;
1731
1732 for (const Value *Inc : I.incoming_values()) {
1733 if (const auto *PhiInc = dyn_cast<PHINode>(Inc))
1734 collectPHINodes(*PhiInc, SeenPHIs);
1735 }
1736
1737 for (const User *U : I.users()) {
1738 if (const auto *PhiU = dyn_cast<PHINode>(U))
1739 collectPHINodes(*PhiU, SeenPHIs);
1740 }
1741}
1742
1743bool AMDGPUCodeGenPrepareImpl::canBreakPHINode(const PHINode &I) {
1744 // Check in the cache first.
1745 if (const auto It = BreakPhiNodesCache.find(&I);
1746 It != BreakPhiNodesCache.end())
1747 return It->second;
1748
1749 // We consider PHI nodes as part of "chains", so given a PHI node I, we
1750 // recursively consider all its users and incoming values that are also PHI
1751 // nodes. We then make a decision about all of those PHIs at once. Either they
1752 // all get broken up, or none of them do. That way, we avoid cases where a
1753 // single PHI is/is not broken and we end up reforming/exploding a vector
1754 // multiple times, or even worse, doing it in a loop.
1755 SmallPtrSet<const PHINode *, 8> WorkList;
1756 collectPHINodes(I, WorkList);
1757
1758#ifndef NDEBUG
1759 // Check that none of the PHI nodes in the worklist are in the map. If some of
1760 // them are, it means we're not good enough at collecting related PHIs.
1761 for (const PHINode *WLP : WorkList) {
1762 assert(BreakPhiNodesCache.count(WLP) == 0);
1763 }
1764#endif
1765
1766 // To consider a PHI profitable to break, we need to see some interesting
1767 // incoming values. At least 2/3rd (rounded up) of all PHIs in the worklist
1768 // must have one to consider all PHIs breakable.
1769 //
1770 // This threshold has been determined through performance testing.
1771 //
1772 // Note that the computation below is equivalent to
1773 //
1774 // (unsigned)ceil((K / 3.0) * 2)
1775 //
1776 // It's simply written this way to avoid mixing integral/FP arithmetic.
1777 const auto Threshold = (alignTo(WorkList.size() * 2, 3) / 3);
1778 unsigned NumBreakablePHIs = 0;
1779 bool CanBreak = false;
1780 for (const PHINode *Cur : WorkList) {
1781 // Don't break PHIs that have no interesting incoming values. That is, where
1782 // there is no clear opportunity to fold the "extractelement" instructions
1783 // we would add.
1784 //
1785 // Note: IC does not run after this pass, so we're only interested in the
1786 // foldings that the DAG combiner can do.
1787 if (any_of(Cur->incoming_values(), isInterestingPHIIncomingValue)) {
1788 if (++NumBreakablePHIs >= Threshold) {
1789 CanBreak = true;
1790 break;
1791 }
1792 }
1793 }
1794
1795 for (const PHINode *Cur : WorkList)
1796 BreakPhiNodesCache[Cur] = CanBreak;
1797
1798 return CanBreak;
1799}
1800
1801/// Helper class for "break large PHIs" (visitPHINode).
1802///
1803/// This represents a slice of a PHI's incoming value, which is made up of:
1804/// - The type of the slice (Ty)
1805/// - The index in the incoming value's vector where the slice starts (Idx)
1806/// - The number of elements in the slice (NumElts).
1807/// It also keeps track of the NewPHI node inserted for this particular slice.
1808///
1809/// Slice examples:
1810/// <4 x i64> -> Split into four i64 slices.
1811/// -> [i64, 0, 1], [i64, 1, 1], [i64, 2, 1], [i64, 3, 1]
1812/// <5 x i16> -> Split into 2 <2 x i16> slices + a i16 tail.
1813/// -> [<2 x i16>, 0, 2], [<2 x i16>, 2, 2], [i16, 4, 1]
1815public:
1816 VectorSlice(Type *Ty, unsigned Idx, unsigned NumElts)
1817 : Ty(Ty), Idx(Idx), NumElts(NumElts) {}
1818
1819 Type *Ty = nullptr;
1820 unsigned Idx = 0;
1821 unsigned NumElts = 0;
1822 PHINode *NewPHI = nullptr;
1823
1824 /// Slice \p Inc according to the information contained within this slice.
1825 /// This is cached, so if called multiple times for the same \p BB & \p Inc
1826 /// pair, it returns the same Sliced value as well.
1827 ///
1828 /// Note this *intentionally* does not return the same value for, say,
1829 /// [%bb.0, %0] & [%bb.1, %0] as:
1830 /// - It could cause issues with dominance (e.g. if bb.1 is seen first, then
1831 /// the value in bb.1 may not be reachable from bb.0 if it's its
1832 /// predecessor.)
1833 /// - We also want to make our extract instructions as local as possible so
1834 /// the DAG has better chances of folding them out. Duplicating them like
1835 /// that is beneficial in that regard.
1836 ///
1837 /// This is both a minor optimization to avoid creating duplicate
1838 /// instructions, but also a requirement for correctness. It is not forbidden
1839 /// for a PHI node to have the same [BB, Val] pair multiple times. If we
1840 /// returned a new value each time, those previously identical pairs would all
1841 /// have different incoming values (from the same block) and it'd cause a "PHI
1842 /// node has multiple entries for the same basic block with different incoming
1843 /// values!" verifier error.
1844 Value *getSlicedVal(BasicBlock *BB, Value *Inc, StringRef NewValName) {
1845 Value *&Res = SlicedVals[{BB, Inc}];
1846 if (Res)
1847 return Res;
1848
1850 if (Instruction *IncInst = dyn_cast<Instruction>(Inc))
1851 B.SetCurrentDebugLocation(IncInst->getDebugLoc());
1852
1853 if (NumElts > 1) {
1855 for (unsigned K = Idx; K < (Idx + NumElts); ++K)
1856 Mask.push_back(K);
1857 Res = B.CreateShuffleVector(Inc, Mask, NewValName);
1858 } else
1859 Res = B.CreateExtractElement(Inc, Idx, NewValName);
1860
1861 return Res;
1862 }
1863
1864private:
1866};
1867
1868bool AMDGPUCodeGenPrepareImpl::visitPHINode(PHINode &I) {
1869 // Break-up fixed-vector PHIs into smaller pieces.
1870 // Default threshold is 32, so it breaks up any vector that's >32 bits into
1871 // its elements, or into 32-bit pieces (for 8/16 bit elts).
1872 //
1873 // This is only helpful for DAGISel because it doesn't handle large PHIs as
1874 // well as GlobalISel. DAGISel lowers PHIs by using CopyToReg/CopyFromReg.
1875 // With large, odd-sized PHIs we may end up needing many `build_vector`
1876 // operations with most elements being "undef". This inhibits a lot of
1877 // optimization opportunities and can result in unreasonably high register
1878 // pressure and the inevitable stack spilling.
1879 if (!BreakLargePHIs || getCGPassBuilderOption().EnableGlobalISelOption ==
1880 cl::boolOrDefault::BOU_TRUE)
1881 return false;
1882
1883 FixedVectorType *FVT = dyn_cast<FixedVectorType>(I.getType());
1884 if (!FVT || FVT->getNumElements() == 1 ||
1885 DL.getTypeSizeInBits(FVT) <= BreakLargePHIsThreshold)
1886 return false;
1887
1888 if (!ForceBreakLargePHIs && !canBreakPHINode(I))
1889 return false;
1890
1891 std::vector<VectorSlice> Slices;
1892
1893 Type *EltTy = FVT->getElementType();
1894 {
1895 unsigned Idx = 0;
1896 // For 8/16 bits type, don't scalarize fully but break it up into as many
1897 // 32-bit slices as we can, and scalarize the tail.
1898 const unsigned EltSize = DL.getTypeSizeInBits(EltTy);
1899 const unsigned NumElts = FVT->getNumElements();
1900 if (EltSize == 8 || EltSize == 16) {
1901 const unsigned SubVecSize = (32 / EltSize);
1902 Type *SubVecTy = FixedVectorType::get(EltTy, SubVecSize);
1903 for (unsigned End = alignDown(NumElts, SubVecSize); Idx < End;
1904 Idx += SubVecSize)
1905 Slices.emplace_back(SubVecTy, Idx, SubVecSize);
1906 }
1907
1908 // Scalarize all remaining elements.
1909 for (; Idx < NumElts; ++Idx)
1910 Slices.emplace_back(EltTy, Idx, 1);
1911 }
1912
1913 assert(Slices.size() > 1);
1914
1915 // Create one PHI per vector piece. The "VectorSlice" class takes care of
1916 // creating the necessary instruction to extract the relevant slices of each
1917 // incoming value.
1918 IRBuilder<> B(I.getParent());
1919 B.SetCurrentDebugLocation(I.getDebugLoc());
1920
1921 unsigned IncNameSuffix = 0;
1922 for (VectorSlice &S : Slices) {
1923 // We need to reset the build on each iteration, because getSlicedVal may
1924 // have inserted something into I's BB.
1925 B.SetInsertPoint(I.getParent()->getFirstNonPHIIt());
1926 S.NewPHI = B.CreatePHI(S.Ty, I.getNumIncomingValues());
1927
1928 for (const auto &[Idx, BB] : enumerate(I.blocks())) {
1929 S.NewPHI->addIncoming(S.getSlicedVal(BB, I.getIncomingValue(Idx),
1930 "largephi.extractslice" +
1931 std::to_string(IncNameSuffix++)),
1932 BB);
1933 }
1934 }
1935
1936 // And replace this PHI with a vector of all the previous PHI values.
1937 Value *Vec = PoisonValue::get(FVT);
1938 unsigned NameSuffix = 0;
1939 for (VectorSlice &S : Slices) {
1940 const auto ValName = "largephi.insertslice" + std::to_string(NameSuffix++);
1941 if (S.NumElts > 1)
1942 Vec = B.CreateInsertVector(FVT, Vec, S.NewPHI, S.Idx, ValName);
1943 else
1944 Vec = B.CreateInsertElement(Vec, S.NewPHI, S.Idx, ValName);
1945 }
1946
1947 I.replaceAllUsesWith(Vec);
1948 DeadVals.push_back(&I);
1949 return true;
1950}
1951
1952/// \param V Value to check
1953/// \param DL DataLayout
1954/// \param TM TargetMachine (TODO: remove once DL contains nullptr values)
1955/// \param AS Target Address Space
1956/// \return true if \p V cannot be the null value of \p AS, false otherwise.
1957static bool isPtrKnownNeverNull(const Value *V, const DataLayout &DL,
1958 const AMDGPUTargetMachine &TM, unsigned AS) {
1959 // Pointer cannot be null if it's a block address, GV or alloca.
1960 // NOTE: We don't support extern_weak, but if we did, we'd need to check for
1961 // it as the symbol could be null in such cases.
1963 return true;
1964
1965 // Check nonnull arguments.
1966 if (const auto *Arg = dyn_cast<Argument>(V); Arg && Arg->hasNonNullAttr())
1967 return true;
1968
1969 // Check nonnull loads.
1970 if (const auto *Load = dyn_cast<LoadInst>(V);
1971 Load && Load->hasMetadata(LLVMContext::MD_nonnull))
1972 return true;
1973
1974 // getUnderlyingObject may have looked through another addrspacecast, although
1975 // the optimizable situations most likely folded out by now.
1976 if (AS != cast<PointerType>(V->getType())->getAddressSpace())
1977 return false;
1978
1979 // TODO: Calls that return nonnull?
1980
1981 // For all other things, use KnownBits.
1982 // We either use 0 or all bits set to indicate null, so check whether the
1983 // value can be zero or all ones.
1984 //
1985 // TODO: Use ValueTracking's isKnownNeverNull if it becomes aware that some
1986 // address spaces have non-zero null values.
1987 auto SrcPtrKB = computeKnownBits(V, DL);
1988 const auto NullVal = AMDGPU::getNullPointerValue(AS);
1989
1990 assert(SrcPtrKB.getBitWidth() == DL.getPointerSizeInBits(AS));
1991 assert((NullVal == 0 || NullVal == -1) &&
1992 "don't know how to check for this null value!");
1993 return NullVal ? !SrcPtrKB.getMaxValue().isAllOnes() : SrcPtrKB.isNonZero();
1994}
1995
1996bool AMDGPUCodeGenPrepareImpl::visitAddrSpaceCastInst(AddrSpaceCastInst &I) {
1997 // Intrinsic doesn't support vectors, also it seems that it's often difficult
1998 // to prove that a vector cannot have any nulls in it so it's unclear if it's
1999 // worth supporting.
2000 if (I.getType()->isVectorTy())
2001 return false;
2002
2003 // Check if this can be lowered to a amdgcn.addrspacecast.nonnull.
2004 // This is only worthwhile for casts from/to priv/local to flat.
2005 const unsigned SrcAS = I.getSrcAddressSpace();
2006 const unsigned DstAS = I.getDestAddressSpace();
2007
2008 bool CanLower = false;
2009 if (SrcAS == AMDGPUAS::FLAT_ADDRESS)
2010 CanLower = (DstAS == AMDGPUAS::LOCAL_ADDRESS ||
2011 DstAS == AMDGPUAS::PRIVATE_ADDRESS);
2012 else if (DstAS == AMDGPUAS::FLAT_ADDRESS)
2013 CanLower = (SrcAS == AMDGPUAS::LOCAL_ADDRESS ||
2014 SrcAS == AMDGPUAS::PRIVATE_ADDRESS);
2015 if (!CanLower)
2016 return false;
2017
2019 getUnderlyingObjects(I.getOperand(0), WorkList);
2020 if (!all_of(WorkList, [&](const Value *V) {
2021 return isPtrKnownNeverNull(V, DL, TM, SrcAS);
2022 }))
2023 return false;
2024
2025 IRBuilder<> B(&I);
2026 auto *Intrin = B.CreateIntrinsic(
2027 I.getType(), Intrinsic::amdgcn_addrspacecast_nonnull, {I.getOperand(0)});
2028 I.replaceAllUsesWith(Intrin);
2029 DeadVals.push_back(&I);
2030 return true;
2031}
2032
2033bool AMDGPUCodeGenPrepareImpl::visitIntrinsicInst(IntrinsicInst &I) {
2034 Intrinsic::ID IID = I.getIntrinsicID();
2035 switch (IID) {
2036 case Intrinsic::minnum:
2037 case Intrinsic::minimumnum:
2038 case Intrinsic::minimum:
2039 return visitFMinLike(I);
2040 case Intrinsic::sqrt:
2041 return visitSqrt(I);
2042 case Intrinsic::log:
2043 case Intrinsic::log10:
2044 return visitLog(cast<FPMathOperator>(I), IID);
2045 case Intrinsic::log2:
2046 // No reason to handle log2.
2047 return false;
2048 case Intrinsic::amdgcn_mbcnt_lo:
2049 return visitMbcntLo(I);
2050 case Intrinsic::amdgcn_mbcnt_hi:
2051 return visitMbcntHi(I);
2052 case Intrinsic::vector_reduce_add:
2053 return visitVectorReduceAdd(I);
2054 case Intrinsic::uadd_sat:
2055 case Intrinsic::sadd_sat:
2056 return visitSaturatingAdd(I);
2057 default:
2058 return false;
2059 }
2060}
2061
2062/// Match the core sequence in the fract pattern (x - floor(x), which doesn't
2063/// need to consider edge case handling.
2064Value *AMDGPUCodeGenPrepareImpl::matchFractPatImpl(Value &FractSrc,
2065 const APFloat &C) const {
2066 if (ST.hasFractBug())
2067 return nullptr;
2068
2069 Type *Ty = FractSrc.getType();
2070 if (!isLegalFloatingTy(Ty->getScalarType()))
2071 return nullptr;
2072
2073 APFloat OneNextDown = APFloat::getOne(C.getSemantics());
2074 OneNextDown.next(true);
2075
2076 // Match nextafter(1.0, -1)
2077 if (OneNextDown != C)
2078 return nullptr;
2079
2080 Value *FloorSrc;
2081 if (match(&FractSrc, m_FSub(m_Value(FloorSrc), m_Intrinsic<Intrinsic::floor>(
2082 m_Deferred(FloorSrc)))))
2083 return FloorSrc;
2084 return nullptr;
2085}
2086
2087/// Match non-nan fract pattern.
2088// MIN_CONSTANT = nextafter(1.0, -1.0)
2089/// minnum(fsub(x, floor(x)), MIN_CONSTANT)
2090/// minimumnum(fsub(x, floor(x)), MIN_CONSTANT)
2091/// minimum(fsub(x, floor(x)), MIN_CONSTANT)
2092
2093// x_sub_floor >= MIN_CONSTANT ? MIN_CONSTANT : x_sub_floor;
2094///
2095/// If fract is a useful instruction for the subtarget. Does not account for the
2096/// nan handling; the instruction has a nan check on the input value.
2097Value *AMDGPUCodeGenPrepareImpl::matchFractPatNanAvoidant(Value &V) {
2098 Value *Arg0;
2099 const APFloat *C;
2100
2101 // The value is only used in contexts where we know the input isn't a nan, so
2102 // any of the fmin variants are fine.
2103 if (!match(&V,
2107 return nullptr;
2108
2109 return matchFractPatImpl(*Arg0, *C);
2110}
2111
2112Value *AMDGPUCodeGenPrepareImpl::applyFractPat(IRBuilder<> &Builder,
2113 Value *FractArg) {
2114 SmallVector<Value *, 4> FractVals;
2115 extractValues(Builder, FractVals, FractArg);
2116
2117 SmallVector<Value *, 4> ResultVals(FractVals.size());
2118
2119 Type *Ty = FractArg->getType()->getScalarType();
2120 for (unsigned I = 0, E = FractVals.size(); I != E; ++I) {
2121 ResultVals[I] =
2122 Builder.CreateIntrinsic(Intrinsic::amdgcn_fract, {Ty}, {FractVals[I]});
2123 }
2124
2125 return insertValues(Builder, FractArg->getType(), ResultVals);
2126}
2127
2128bool AMDGPUCodeGenPrepareImpl::visitFMinLike(IntrinsicInst &I) {
2129 const APFloat *C;
2130 Value *FractArg;
2131
2132 // minimum(x - floor(x), MIN_CONSTANT)
2133 Value *X;
2134 if (!ST.hasFractBug() &&
2136 FractArg = matchFractPatImpl(*X, *C);
2137 if (!FractArg)
2138 return false;
2139 } else {
2140 // minnum(x - floor(x), MIN_CONSTANT)
2141 FractArg = matchFractPatNanAvoidant(I);
2142 if (!FractArg)
2143 return false;
2144
2145 // Match pattern for fract intrinsic in contexts where the nan check has
2146 // been optimized out (and hope the knowledge the source can't be nan wasn't
2147 // lost).
2148 if (!I.hasNoNaNs() && !isKnownNeverNaN(FractArg, SQ.getWithInstruction(&I)))
2149 return false;
2150 }
2151
2152 IRBuilder<> Builder(&I);
2153 FastMathFlags FMF = I.getFastMathFlags();
2154 FMF.setNoNaNs();
2155 Builder.setFastMathFlags(FMF);
2156
2157 Value *Fract = applyFractPat(Builder, FractArg);
2158 Fract->takeName(&I);
2159 I.replaceAllUsesWith(Fract);
2160 DeadVals.push_back(&I);
2161 return true;
2162}
2163
2164// Expand llvm.sqrt.f32 calls with !fpmath metadata in a semi-fast way.
2165bool AMDGPUCodeGenPrepareImpl::visitSqrt(IntrinsicInst &Sqrt) {
2166 Type *Ty = Sqrt.getType()->getScalarType();
2167 if (!Ty->isFloatTy() && (!Ty->isHalfTy() || ST.has16BitInsts()))
2168 return false;
2169
2170 const FPMathOperator *FPOp = cast<const FPMathOperator>(&Sqrt);
2171 FastMathFlags SqrtFMF = FPOp->getFastMathFlags();
2172
2173 // We're trying to handle the fast-but-not-that-fast case only. The lowering
2174 // of fast llvm.sqrt will give the raw instruction anyway.
2175 if (SqrtFMF.approxFunc())
2176 return false;
2177
2178 const float ReqdAccuracy = FPOp->getFPAccuracy();
2179
2180 // Defer correctly rounded expansion to codegen.
2181 if (ReqdAccuracy < 1.0f)
2182 return false;
2183
2184 Value *SrcVal = Sqrt.getOperand(0);
2185 bool CanTreatAsDAZ = canIgnoreDenormalInput(SrcVal, &Sqrt);
2186
2187 // The raw instruction is 1 ulp, but the correction for denormal handling
2188 // brings it to 2.
2189 if (!CanTreatAsDAZ && ReqdAccuracy < 2.0f)
2190 return false;
2191
2192 IRBuilder<> Builder(&Sqrt);
2193 SmallVector<Value *, 4> SrcVals;
2194 extractValues(Builder, SrcVals, SrcVal);
2195
2196 SmallVector<Value *, 4> ResultVals(SrcVals.size());
2197 for (int I = 0, E = SrcVals.size(); I != E; ++I) {
2198 if (CanTreatAsDAZ)
2199 ResultVals[I] = Builder.CreateCall(getSqrtF32(), SrcVals[I]);
2200 else
2201 ResultVals[I] = emitSqrtIEEE2ULP(Builder, SrcVals[I], SqrtFMF);
2202 }
2203
2204 Value *NewSqrt = insertValues(Builder, Sqrt.getType(), ResultVals);
2205 NewSqrt->takeName(&Sqrt);
2206 Sqrt.replaceAllUsesWith(NewSqrt);
2207 DeadVals.push_back(&Sqrt);
2208 return true;
2209}
2210
2211/// Replace log and log10 intrinsic calls based on fpmath metadata.
2212bool AMDGPUCodeGenPrepareImpl::visitLog(FPMathOperator &Log,
2213 Intrinsic::ID IID) {
2214 Type *Ty = Log.getType();
2215 if (!Ty->getScalarType()->isHalfTy() || !ST.has16BitInsts())
2216 return false;
2217
2218 FastMathFlags FMF = Log.getFastMathFlags();
2219
2220 // Defer fast math cases to codegen.
2221 if (FMF.approxFunc())
2222 return false;
2223
2224 // Limit experimentally determined from OpenCL conformance test (1.79)
2225 if (Log.getFPAccuracy() < 1.80f)
2226 return false;
2227
2228 IRBuilder<> Builder(&cast<CallInst>(Log));
2229
2230 // Use the generic intrinsic for convenience in the vector case. Codegen will
2231 // recognize the denormal handling is not necessary from the fpext.
2232 // TODO: Move to generic code
2233 Value *Log2 =
2234 Builder.CreateUnaryIntrinsic(Intrinsic::log2, Log.getOperand(0), FMF);
2235
2236 double Log2BaseInverted =
2237 IID == Intrinsic::log10 ? numbers::ln2 / numbers::ln10 : numbers::ln2;
2238 Value *Mul =
2239 Builder.CreateFMulFMF(Log2, ConstantFP::get(Ty, Log2BaseInverted), FMF);
2240
2241 Mul->takeName(&Log);
2242
2243 Log.replaceAllUsesWith(Mul);
2244 DeadVals.push_back(&Log);
2245 return true;
2246}
2247
2248bool AMDGPUCodeGenPrepare::runOnFunction(Function &F) {
2249 if (skipFunction(F))
2250 return false;
2251
2252 auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
2253 if (!TPC)
2254 return false;
2255
2256 const AMDGPUTargetMachine &TM = TPC->getTM<AMDGPUTargetMachine>();
2257 const TargetLibraryInfo *TLI =
2258 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
2259 AssumptionCache *AC =
2260 &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
2261 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
2262 const DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr;
2263 const UniformityInfo &UA =
2264 getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
2265 return AMDGPUCodeGenPrepareImpl(F, TM, TLI, AC, DT, UA).run();
2266}
2267
2270 const AMDGPUTargetMachine &ATM = static_cast<const AMDGPUTargetMachine &>(TM);
2271 const TargetLibraryInfo *TLI = &FAM.getResult<TargetLibraryAnalysis>(F);
2272 AssumptionCache *AC = &FAM.getResult<AssumptionAnalysis>(F);
2273 const DominatorTree *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
2274 const UniformityInfo &UA = FAM.getResult<UniformityInfoAnalysis>(F);
2275 AMDGPUCodeGenPrepareImpl Impl(F, ATM, TLI, AC, DT, UA);
2276 if (!Impl.run())
2277 return PreservedAnalyses::all();
2279 if (!Impl.FlowChanged)
2281 return PA;
2282}
2283
2284INITIALIZE_PASS_BEGIN(AMDGPUCodeGenPrepare, DEBUG_TYPE,
2285 "AMDGPU IR optimizations", false, false)
2289INITIALIZE_PASS_END(AMDGPUCodeGenPrepare, DEBUG_TYPE, "AMDGPU IR optimizations",
2291
2292/// Create a workitem.id.x intrinsic call with range metadata.
2293CallInst *AMDGPUCodeGenPrepareImpl::createWorkitemIdX(IRBuilder<> &B) const {
2294 CallInst *Tid =
2295 B.CreateIntrinsicWithoutFolding(Intrinsic::amdgcn_workitem_id_x, {});
2296 ST.makeLIDRangeMetadata(Tid);
2297 return Tid;
2298}
2299
2300/// Replace the instruction with a direct workitem.id.x call.
2301void AMDGPUCodeGenPrepareImpl::replaceWithWorkitemIdX(Instruction &I) const {
2302 IRBuilder<> B(&I);
2303 CallInst *Tid = createWorkitemIdX(B);
2305 ReplaceInstWithValue(BI, Tid);
2306}
2307
2308/// Replace the instruction with (workitem.id.x & mask).
2309void AMDGPUCodeGenPrepareImpl::replaceWithMaskedWorkitemIdX(
2310 Instruction &I, unsigned WaveSize) const {
2311 IRBuilder<> B(&I);
2312 CallInst *Tid = createWorkitemIdX(B);
2313 Constant *Mask = ConstantInt::get(Tid->getType(), WaveSize - 1);
2314 Value *AndInst = B.CreateAnd(Tid, Mask);
2316 ReplaceInstWithValue(BI, AndInst);
2317}
2318
2319/// Try to optimize mbcnt instruction by replacing with workitem.id.x when
2320/// work group size allows direct computation of lane ID.
2321/// Returns true if optimization was applied, false otherwise.
2322bool AMDGPUCodeGenPrepareImpl::tryReplaceWithWorkitemId(Instruction &I,
2323 unsigned Wave) const {
2324 std::optional<unsigned> MaybeX = ST.getReqdWorkGroupSize(F, 0);
2325 if (!MaybeX)
2326 return false;
2327
2328 // When work group size == wave_size, each work group contains exactly one
2329 // wave, so the instruction can be replaced with workitem.id.x directly.
2330 if (*MaybeX == Wave) {
2331 replaceWithWorkitemIdX(I);
2332 return true;
2333 }
2334
2335 // When work group evenly splits into waves, compute lane ID within wave
2336 // using bit masking: lane_id = workitem.id.x & (wave_size - 1).
2337 if (ST.hasWavefrontsEvenlySplittingXDim(F, /*RequiresUniformYZ=*/true)) {
2338 replaceWithMaskedWorkitemIdX(I, Wave);
2339 return true;
2340 }
2341
2342 return false;
2343}
2344
2345/// Optimize mbcnt.lo calls on wave32 architectures for lane ID computation.
2346bool AMDGPUCodeGenPrepareImpl::visitMbcntLo(IntrinsicInst &I) const {
2347 // This optimization only applies to wave32 targets where mbcnt.lo operates on
2348 // the full execution mask.
2349 if (!ST.isWave32())
2350 return false;
2351
2352 // Only optimize the pattern mbcnt.lo(~0, 0) which counts active lanes with
2353 // lower IDs.
2354 if (!match(&I,
2356 return false;
2357
2358 return tryReplaceWithWorkitemId(I, ST.getWavefrontSize());
2359}
2360
2361/// Optimize mbcnt.hi calls for lane ID computation.
2362bool AMDGPUCodeGenPrepareImpl::visitMbcntHi(IntrinsicInst &I) const {
2363 // Abort if wave size is not known at compile time.
2364 if (!ST.isWaveSizeKnown())
2365 return false;
2366
2367 unsigned Wave = ST.getWavefrontSize();
2368
2369 // On wave32, the upper 32 bits of execution mask are always 0, so
2370 // mbcnt.hi(mask, val) always returns val unchanged.
2371 if (ST.isWave32()) {
2372 if (auto MaybeX = ST.getReqdWorkGroupSize(F, 0)) {
2373 // Replace mbcnt.hi(mask, val) with val only when work group size matches
2374 // wave size (single wave per work group).
2375 if (*MaybeX == Wave) {
2377 ReplaceInstWithValue(BI, I.getArgOperand(1));
2378 return true;
2379 }
2380 }
2381 }
2382
2383 // Optimize the complete lane ID computation pattern:
2384 // mbcnt.hi(~0, mbcnt.lo(~0, 0)) which counts all active lanes with lower IDs
2385 // across the full execution mask.
2386 using namespace PatternMatch;
2387
2388 // Check for pattern: mbcnt.hi(~0, mbcnt.lo(~0, 0))
2391 m_AllOnes(), m_Zero()))))
2392 return false;
2393
2394 return tryReplaceWithWorkitemId(I, Wave);
2395}
2396
2397/// Check if type is <4 x i8>.
2398static bool isV4I8(Type *Ty) {
2400 return VTy && VTy->getNumElements() == 4 &&
2401 VTy->getElementType()->isIntegerTy(8);
2402}
2403
2404/// Helper to match the dot4 pattern: mul(zext/sext <4 x i8>, zext/sext <4 x
2405/// i8>) Returns true if pattern matches and signedness matches IsSigned.
2406/// Sets A, B to the <4 x i8> sources.
2407static bool matchDot4Pattern(Value *MulOp, Value *&A, Value *&B,
2408 bool IsSigned) {
2409 Value *Src0, *Src1;
2410 if (!match(MulOp, m_Mul(m_Value(Src0), m_Value(Src1))))
2411 return false;
2412
2413 // Check that result type is <4 x i32>
2415 if (!MulTy || MulTy->getNumElements() != 4 ||
2416 !MulTy->getElementType()->isIntegerTy(32))
2417 return false;
2418
2419 // Match zext or sext based on IsSigned
2420 Value *ExtSrc0, *ExtSrc1;
2421 if (IsSigned) {
2422 if (!match(Src0, m_SExt(m_Value(ExtSrc0))) || !isV4I8(ExtSrc0->getType()))
2423 return false;
2424 if (!match(Src1, m_SExt(m_Value(ExtSrc1))) || !isV4I8(ExtSrc1->getType()))
2425 return false;
2426 } else {
2427 if (!match(Src0, m_ZExt(m_Value(ExtSrc0))) || !isV4I8(ExtSrc0->getType()))
2428 return false;
2429 if (!match(Src1, m_ZExt(m_Value(ExtSrc1))) || !isV4I8(ExtSrc1->getType()))
2430 return false;
2431 }
2432
2433 A = ExtSrc0;
2434 B = ExtSrc1;
2435 return true;
2436}
2437
2438/// Try to convert vector.reduce.add(mul(zext/sext <4 x i8>, zext/sext <4 x
2439/// i8>)) to a dot4 intrinsic call (non-saturating case only).
2440bool AMDGPUCodeGenPrepareImpl::visitVectorReduceAdd(IntrinsicInst &I) {
2441 // Check if we have dot4 instructions available
2442 if (!ST.hasDot7Insts() || (!ST.hasDot1Insts() && !ST.hasDot8Insts()))
2443 return false;
2444
2445 Value *A = nullptr, *B = nullptr;
2446
2447 // Try unsigned first, then signed
2448 bool IsSigned = false;
2449 if (!matchDot4Pattern(I.getArgOperand(0), A, B, /*IsSigned=*/false)) {
2450 if (!matchDot4Pattern(I.getArgOperand(0), A, B, /*IsSigned=*/true))
2451 return false;
2452 IsSigned = true;
2453 }
2454
2455 LLVMContext &Ctx = I.getContext();
2456 Type *I32Ty = Type::getInt32Ty(Ctx);
2457 IRBuilder<> Builder(&I);
2458
2459 // Bitcast <4 x i8> to i32
2460 Value *ASrc = Builder.CreateBitCast(A, I32Ty);
2461 Value *BSrc = Builder.CreateBitCast(B, I32Ty);
2462
2463 // Non-saturating case: accumulator is 0, clamp is false
2464 Value *Acc = ConstantInt::get(I32Ty, 0);
2465 Value *Clamp = ConstantInt::getFalse(Ctx);
2466
2467 Intrinsic::ID DotIID =
2468 IsSigned ? Intrinsic::amdgcn_sdot4 : Intrinsic::amdgcn_udot4;
2469
2470 Value *Dot = Builder.CreateIntrinsic(DotIID, {}, {ASrc, BSrc, Acc, Clamp});
2471 Dot->takeName(&I);
2472
2473 I.replaceAllUsesWith(Dot);
2474 DeadVals.push_back(&I);
2475
2476 return true;
2477}
2478
2479/// Try to convert uadd.sat/sadd.sat(vector.reduce.add(mul(...)), c) to a
2480/// saturating dot4 intrinsic. This combine starts at the root (saturating add)
2481/// and looks at its operands.
2482bool AMDGPUCodeGenPrepareImpl::visitSaturatingAdd(IntrinsicInst &I) {
2483 // Check if we have dot4 instructions available
2484 if (!ST.hasDot7Insts() || (!ST.hasDot1Insts() && !ST.hasDot8Insts()))
2485 return false;
2486
2487 Intrinsic::ID IID = I.getIntrinsicID();
2488 bool IsSigned = (IID == Intrinsic::sadd_sat);
2489
2490 // Look for vector.reduce.add as one of the operands (commutative match)
2491 Value *Op0 = I.getArgOperand(0);
2492 Value *Op1 = I.getArgOperand(1);
2493 Value *MulOp = nullptr;
2494 Value *Accum = nullptr;
2495 IntrinsicInst *ReduceInst = nullptr;
2496
2498 ReduceInst = cast<IntrinsicInst>(Op0);
2499 Accum = Op1;
2500 } else if (match(Op1,
2502 ReduceInst = cast<IntrinsicInst>(Op1);
2503 Accum = Op0;
2504 } else {
2505 return false;
2506 }
2507
2508 Value *A = nullptr, *B = nullptr;
2509
2510 if (!matchDot4Pattern(MulOp, A, B, IsSigned))
2511 return false;
2512
2513 LLVMContext &Ctx = I.getContext();
2514 Type *I32Ty = Type::getInt32Ty(Ctx);
2515 IRBuilder<> Builder(&I);
2516
2517 // Bitcast <4 x i8> to i32
2518 Value *ASrc = Builder.CreateBitCast(A, I32Ty);
2519 Value *BSrc = Builder.CreateBitCast(B, I32Ty);
2520
2521 // Saturating case: use the accumulator and set clamp to true
2522 Value *Clamp = ConstantInt::getTrue(Ctx);
2523
2524 Intrinsic::ID DotIID =
2525 IsSigned ? Intrinsic::amdgcn_sdot4 : Intrinsic::amdgcn_udot4;
2526
2527 Value *Dot = Builder.CreateIntrinsic(DotIID, {}, {ASrc, BSrc, Accum, Clamp});
2528 Dot->takeName(&I);
2529
2530 I.replaceAllUsesWith(Dot);
2531 DeadVals.push_back(&I);
2532 // The reduce.add will be dead after this and cleaned up later
2533 if (ReduceInst->use_empty())
2534 DeadVals.push_back(ReduceInst);
2535
2536 return true;
2537}
2538
2539char AMDGPUCodeGenPrepare::ID = 0;
2540
2542 return new AMDGPUCodeGenPrepare();
2543}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static Value * insertValues(IRBuilder<> &Builder, Type *Ty, SmallVectorImpl< Value * > &Values)
static void extractValues(IRBuilder<> &Builder, SmallVectorImpl< Value * > &Values, Value *V)
static Value * getMulHu(IRBuilder<> &Builder, Value *LHS, Value *RHS)
static bool isInterestingPHIIncomingValue(const Value *V)
static SelectInst * findSelectThroughCast(Value *V, CastInst *&Cast)
static bool matchDot4Pattern(Value *MulOp, Value *&A, Value *&B, bool IsSigned)
Helper to match the dot4 pattern: mul(zext/sext <4 x i8>, zext/sext <4 x i8>) Returns true if pattern...
static bool isV4I8(Type *Ty)
Check if type is <4 x i8>.
static std::pair< Value *, Value * > getMul64(IRBuilder<> &Builder, Value *LHS, Value *RHS)
static Value * emitRsqIEEE1ULP(IRBuilder<> &Builder, Value *Src, bool IsNegative)
Emit an expansion of 1.0 / sqrt(Src) good for 1ulp that supports denormals.
static Value * getSign32(Value *V, IRBuilder<> &Builder, const DataLayout DL)
static void collectPHINodes(const PHINode &I, SmallPtrSet< const PHINode *, 8 > &SeenPHIs)
static bool isPtrKnownNeverNull(const Value *V, const DataLayout &DL, const AMDGPUTargetMachine &TM, unsigned AS)
static bool areInSameBB(const Value *A, const Value *B)
static cl::opt< bool > WidenLoads("amdgpu-late-codegenprepare-widen-constant-loads", cl::desc("Widen sub-dword constant address space loads in " "AMDGPULateCodeGenPrepare"), cl::ReallyHidden, cl::init(true))
The AMDGPU TargetMachine interface definition for hw codegen targets.
@ Scaled
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
dxil translate DXIL Translate Metadata
static bool runOnFunction(Function &F, bool PostInlining)
#define DEBUG_TYPE
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
const SmallVectorImpl< MachineOperand > & Cond
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
This file implements a set that has insertion order iteration characteristics.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static cl::opt< cl::boolOrDefault > EnableGlobalISelOption("global-isel", cl::Hidden, cl::desc("Enable the \"global\" instruction selector"))
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
LLVM IR instance of the generic uniformity analysis.
Value * RHS
Value * LHS
BinaryOperator * Mul
VectorSlice(Type *Ty, unsigned Idx, unsigned NumElts)
Value * getSlicedVal(BasicBlock *BB, Value *Inc, StringRef NewValName)
Slice Inc according to the information contained within this slice.
PreservedAnalyses run(Function &, FunctionAnalysisManager &)
std::optional< unsigned > getReqdWorkGroupSize(const Function &F, unsigned Dim) const
bool hasWavefrontsEvenlySplittingXDim(const Function &F, bool REquiresUniformYZ=false) const
unsigned getWavefrontSize() const
static APFloat getOne(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative One.
Definition APFloat.h:1174
static APFloat getSmallestNormalized(const fltSemantics &Sem, bool Negative=false)
Returns the smallest (by magnitude) normalized finite number in the given semantics.
Definition APFloat.h:1244
opStatus next(bool nextDown)
Definition APFloat.h:1340
This class represents a conversion between pointers from one address space to another.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
BinaryOps getOpcode() const
Definition InstrTypes.h:409
BitVector & set()
Set all bits in the bitvector.
Definition BitVector.h:366
bool all() const
Returns true if all bits are set.
Definition BitVector.h:194
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
Definition InstrTypes.h:512
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition InstrTypes.h:674
TargetTransformInfo getTargetTransformInfo(const Function &F) const override
Get a TargetTransformInfo implementation for the target.
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:537
bool isMinusOne() const
Returns true if this value is exactly -1.0.
Definition Constants.h:488
static LLVM_ABI ConstantFP * getZero(Type *Ty, bool Negative=false)
bool isOne() const
Returns true if this value is exactly +1.0.
Definition Constants.h:485
static LLVM_ABI ConstantFP * getInfinity(Type *Ty, bool Negative=false)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
This is an important base class in LLVM.
Definition Constant.h:43
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
Analysis pass which computes a DominatorTree.
Definition Dominators.h:270
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:151
Utility class for floating point operations which can have information about relaxed accuracy require...
Definition Operator.h:202
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags.
Definition Operator.h:291
LLVM_ABI float getFPAccuracy() const
Get the maximum error permitted by this operation in ULPs.
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
void setFast(bool B=true)
Definition FMF.h:96
bool noInfs() const
Definition FMF.h:66
bool allowReciprocal() const
Definition FMF.h:68
bool approxFunc() const
Definition FMF.h:70
void setNoNaNs(bool B=true)
Definition FMF.h:78
bool noNaNs() const
Definition FMF.h:65
bool allowContract() const
Definition FMF.h:69
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:867
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
bool isWave32() const
bool isWaveSizeKnown() const
Returns if the wavesize of this subtarget is known reliable.
bool hasFractBug() const
bool isUniformAtDef(ConstValueRefT V) const
Whether V is uniform/non-divergent at its definition.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2662
Value * CreateFDiv(Value *L, Value *R, const Twine &Name="", MDNode *FPMD=nullptr)
Definition IRBuilder.h:1693
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2650
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Definition IRBuilder.h:547
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
Definition IRBuilder.h:2139
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition IRBuilder.h:2709
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateFPToUI(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2167
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2133
void SetCurrentDebugLocation(const DebugLoc &L)
Set location information used by debugging information.
Definition IRBuilder.h:221
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition IRBuilder.h:534
Value * CreateUIToFP(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false, MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2181
void setFastMathFlags(FastMathFlags NewFMF)
Set the fast-math flags to be used with generated fp-math operators.
Definition IRBuilder.h:300
Value * CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2430
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
Definition IRBuilder.h:1830
LLVM_ABI Value * createIsFPClass(Value *FPNum, unsigned Test)
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition IRBuilder.h:477
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1439
Value * CreateFMA(Value *Factor1, Value *Factor2, Value *Summand, FMFSource FMFSource={}, const Twine &Name="")
Create call to the fma intrinsic.
Definition IRBuilder.h:1092
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2243
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Definition IRBuilder.h:1906
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Definition IRBuilder.h:2121
Value * CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2415
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1422
Type * getFloatTy()
Fetch the type representing a 32-bit floating point value.
Definition IRBuilder.h:562
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2554
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition IRBuilder.h:2107
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1731
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2387
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:181
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1622
Value * CreateSIToFP(Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2193
Value * CreateFMul(Value *L, Value *R, const Twine &Name="", MDNode *FPMD=nullptr)
Definition IRBuilder.h:1674
Value * CreateFNeg(Value *V, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1839
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1592
Value * CreateSExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a SExt or Trunc from the integer value V to DestTy.
Definition IRBuilder.h:2154
Value * CreateFMulFMF(Value *L, Value *R, FMFSource FMFSource, const Twine &Name="", MDNode *FPMD=nullptr)
Definition IRBuilder.h:1679
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1456
LLVM_ABI Value * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *Op, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
Value * CreateFPToSI(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2174
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2893
Base class for instruction visitors.
Definition InstVisitor.h:78
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
An instruction for reading from memory.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1565
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
This class represents the LLVM 'select' instruction.
const Value * getFalseValue() const
const Value * getCondition() const
const Value * getTrueValue() const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
static LLVM_ABI CastContextHint getCastContextHint(const Instruction *I)
Calculates a CastContextHint from I.
LLVM_ABI InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind=TTI::TCK_SizeAndLatency, const Instruction *I=nullptr) const
@ TCK_RecipThroughput
Reciprocal throughput.
LLVM_ABI InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind=TTI::TCK_RecipThroughput, TTI::OperandValueInfo Opd1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Opd2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr, const TargetLibraryInfo *TLibInfo=nullptr) const
This is an approximation of reciprocal throughput of a math/logic op.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:310
LLVM_ABI unsigned getIntegerBitWidth() const
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:309
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition Type.h:155
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:368
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
Definition Type.h:144
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:232
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition Type.h:158
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
LLVM_ABI const fltSemantics & getFltSemantics() const
Definition Type.cpp:106
Analysis pass which computes UniformityInfo.
Legacy analysis pass which computes a CycleInfo.
void setOperand(unsigned i, Value *Val)
Definition User.h:212
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:439
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
bool use_empty() const
Definition Value.h:346
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition Value.cpp:400
Type * getElementType() const
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CONSTANT_ADDRESS_32BIT
Address space for 32-bit constant memory.
@ LOCAL_ADDRESS
Address space for local memory.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
@ FLAT_ADDRESS
Address space for flat memory.
@ PRIVATE_ADDRESS
Address space for private memory.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr int64_t getNullPointerValue(unsigned AS)
Get the null pointer value for the given address space.
void copyMetadataForWidenedLoad(LoadInst &Dest, const LoadInst &Source)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
CmpClass_match< LHS, RHS, FCmpInst > m_FCmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
match_deferred< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
ap_match< APFloat > m_APFloatAllowPoison(const APFloat *&Res)
Match APFloat while allowing poison in splat vector constants.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
FMaxMin_match< LHS, RHS, ufmin_pred_ty > m_UnordFMin(const LHS &L, const RHS &R)
Match an 'unordered' floating point minimum function.
auto m_FMinimum(const Opnd0 &Op0, const Opnd1 &Op1)
auto m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
cstfp_pred_ty< is_nonnan > m_NonNaN()
Match a non-NaN FP constant.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
auto m_FMinNum_or_FMinimumNum(const Opnd0 &Op0, const Opnd1 &Op1)
cstfp_pred_ty< is_signed_inf< false > > m_PosInf()
Match a positive infinity FP constant.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
auto m_FAbs(const Opnd0 &Op0)
cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()
Match a floating-point positive zero.
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
initializer< Ty > init(const Ty &Val)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:668
constexpr double ln2
constexpr double ln10
This is an optimization pass for GlobalISel generic memory operations.
GenericUniformityInfo< SSAContext > UniformityInfo
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
Definition Local.cpp:535
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
@ Known
Known to have no common set bits.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2554
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI bool expandRemainderUpTo64Bits(BinaryOperator *Rem)
Generate code to calculate the remainder of two integers, replacing Rem with the generated code.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:633
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
Definition MathExtras.h:546
LLVM_ABI void ReplaceInstWithValue(BasicBlock::iterator &BI, Value *V)
Replace all uses of an instruction (specified by BI) with a value, then remove and delete the origina...
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Definition bit.h:362
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
Definition Local.cpp:403
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
LLVM_ABI bool expandDivisionUpTo64Bits(BinaryOperator *Div)
Generate code to divide two integers, replacing Div with the generated code.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
TargetTransformInfo TTI
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
FunctionPass * createAMDGPUCodeGenPreparePass()
To bit_cast(const From &from) noexcept
Definition bit.h:90
DWARFExpression::Operation Op
LLVM_ABI unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return the number of times the sign bit of the register is replicated into the other bits.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI bool isKnownNeverNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
LLVM_ABI unsigned ComputeMaxSignificantBits(const Value *Op, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Get the upper bound on bit size for this Value Op as a signed integer.
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition Alignment.h:197
LLVM_ABI bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return true if the given value is known to have exactly one bit set when defined.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, const LoopInfo *LI=nullptr, unsigned MaxLookup=MaxLookupSearchDepth)
This method is similar to getUnderlyingObject except that it can look through phi and select instruct...
LLVM_ABI CGPassBuilderOption getCGPassBuilderOption()
#define N
DenormalModeKind Input
Denormal treatment kind for floating point instruction inputs in the default floating-point environme...
constexpr bool inputsAreZero() const
Return true if input denormals must be implicitly treated as 0.
static constexpr DenormalMode getPreserveSign()
bool isKnownNeverSubnormal() const
Return true if it's known this can never be a subnormal.
LLVM_ABI bool isKnownNeverLogicalZero(DenormalMode Mode) const
Return true if it's known this can never be interpreted as a zero.
bool isKnownNeverPosInfinity() const
Return true if it's known this can never be +infinity.
const DataLayout & DL
const DominatorTree * DT
SimplifyQuery getWithInstruction(const Instruction *I) const
AssumptionCache * AC