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