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 FastMathFlags ValueFMF = FastMathFlags::intersectValue(DivFMF, SqrtFMF);
748 NewFMF.setNoInfs(ValueFMF.noInfs());
749 NewFMF.setNoSignedZeros(ValueFMF.noSignedZeros());
750 Builder.setFastMathFlags(NewFMF);
751
752 if (Den->getType()->isFloatTy()) {
753 if ((DivFMF.approxFunc() && SqrtFMF.approxFunc()) ||
754 canIgnoreDenormalInput(Den, CtxI)) {
755 Value *Result =
756 Builder.CreateUnaryIntrinsic(Intrinsic::amdgcn_rsq, Den);
757 // -1.0 / sqrt(x) -> fneg(rsq(x))
758 return IsNegative ? Builder.CreateFNeg(Result) : Result;
759 }
760
761 return emitRsqIEEE1ULP(Builder, Den, IsNegative);
762 }
763
764 if (Den->getType()->isDoubleTy())
765 return emitRsqF64(Builder, Den, SqrtFMF, DivFMF, CtxI, IsNegative);
766 }
767
768 return nullptr;
769}
770
771// Optimize fdiv with rcp:
772//
773// 1/x -> rcp(x) when rcp is sufficiently accurate or inaccurate rcp is
774// allowed with afn.
775//
776// a/b -> a*rcp(b) when arcp is allowed, and we only need provide ULP 1.0
777Value *
778AMDGPUCodeGenPrepareImpl::optimizeWithRcp(IRBuilder<> &Builder, Value *Num,
779 Value *Den, FastMathFlags FMF,
780 const Instruction *CtxI) const {
781 // rcp_f16 is accurate to 0.51 ulp.
782 // rcp_f32 is accurate for !fpmath >= 1.0ulp and denormals are flushed.
783 // rcp_f64 is never accurate.
784 assert(Den->getType()->isFloatTy());
785
786 if (const ConstantFP *CLHS = dyn_cast<ConstantFP>(Num)) {
787 bool IsNegative = false;
788 if (CLHS->isOne() || (IsNegative = CLHS->isMinusOne())) {
789 Value *Src = Den;
790
791 if (HasFP32DenormalFlush || FMF.approxFunc()) {
792 // -1.0 / x -> 1.0 / fneg(x)
793 if (IsNegative)
794 Src = Builder.CreateFNeg(Src);
795
796 // v_rcp_f32 and v_rsq_f32 do not support denormals, and according to
797 // the CI documentation has a worst case error of 1 ulp.
798 // OpenCL requires <= 2.5 ulp for 1.0 / x, so it should always be OK
799 // to use it as long as we aren't trying to use denormals.
800 //
801 // v_rcp_f16 and v_rsq_f16 DO support denormals.
802
803 // NOTE: v_sqrt and v_rcp will be combined to v_rsq later. So we don't
804 // insert rsq intrinsic here.
805
806 // 1.0 / x -> rcp(x)
807 return Builder.CreateUnaryIntrinsic(Intrinsic::amdgcn_rcp, Src);
808 }
809
810 // TODO: If the input isn't denormal, and we know the input exponent isn't
811 // big enough to introduce a denormal we can avoid the scaling.
812 return emitRcpIEEE1ULP(Builder, Src, IsNegative);
813 }
814 }
815
816 if (FMF.allowReciprocal()) {
817 // x / y -> x * (1.0 / y)
818
819 // TODO: Could avoid denormal scaling and use raw rcp if we knew the output
820 // will never underflow.
821 if (HasFP32DenormalFlush || FMF.approxFunc()) {
822 Value *Recip = Builder.CreateUnaryIntrinsic(Intrinsic::amdgcn_rcp, Den);
823 return Builder.CreateFMul(Num, Recip);
824 }
825
826 Value *Recip = emitRcpIEEE1ULP(Builder, Den, false);
827 return Builder.CreateFMul(Num, Recip);
828 }
829
830 return nullptr;
831}
832
833// optimize with fdiv.fast:
834//
835// a/b -> fdiv.fast(a, b) when !fpmath >= 2.5ulp with denormals flushed.
836//
837// 1/x -> fdiv.fast(1,x) when !fpmath >= 2.5ulp.
838//
839// NOTE: optimizeWithRcp should be tried first because rcp is the preference.
840Value *AMDGPUCodeGenPrepareImpl::optimizeWithFDivFast(
841 IRBuilder<> &Builder, Value *Num, Value *Den, float ReqdAccuracy) const {
842 // fdiv.fast can achieve 2.5 ULP accuracy.
843 if (ReqdAccuracy < 2.5f)
844 return nullptr;
845
846 // Only have fdiv.fast for f32.
847 assert(Den->getType()->isFloatTy());
848
849 bool NumIsOne = false;
850 if (const ConstantFP *CNum = dyn_cast<ConstantFP>(Num)) {
851 if (CNum->isOne() || CNum->isMinusOne())
852 NumIsOne = true;
853 }
854
855 // fdiv does not support denormals. But 1.0/x is always fine to use it.
856 //
857 // TODO: This works for any value with a specific known exponent range, don't
858 // just limit to constant 1.
859 if (!HasFP32DenormalFlush && !NumIsOne)
860 return nullptr;
861
862 return Builder.CreateIntrinsic(Intrinsic::amdgcn_fdiv_fast, {Num, Den});
863}
864
865Value *AMDGPUCodeGenPrepareImpl::visitFDivElement(
866 IRBuilder<> &Builder, Value *Num, Value *Den, FastMathFlags DivFMF,
867 FastMathFlags SqrtFMF, Value *RsqOp, const Instruction *FDivInst,
868 float ReqdDivAccuracy) const {
869 if (RsqOp) {
870 Value *Rsq =
871 optimizeWithRsq(Builder, Num, RsqOp, DivFMF, SqrtFMF, FDivInst);
872 if (Rsq)
873 return Rsq;
874 }
875
876 if (!Num->getType()->isFloatTy())
877 return nullptr;
878
879 Value *Rcp = optimizeWithRcp(Builder, Num, Den, DivFMF, FDivInst);
880 if (Rcp)
881 return Rcp;
882
883 // In the basic case fdiv_fast has the same instruction count as the frexp div
884 // expansion. Slightly prefer fdiv_fast since it ends in an fmul that can
885 // potentially be fused into a user. Also, materialization of the constants
886 // can be reused for multiple instances.
887 Value *FDivFast = optimizeWithFDivFast(Builder, Num, Den, ReqdDivAccuracy);
888 if (FDivFast)
889 return FDivFast;
890
891 return emitFrexpDiv(Builder, Num, Den, DivFMF);
892}
893
894// Optimizations is performed based on fpmath, fast math flags as well as
895// denormals to optimize fdiv with either rcp or fdiv.fast.
896//
897// With rcp:
898// 1/x -> rcp(x) when rcp is sufficiently accurate or inaccurate rcp is
899// allowed with afn.
900//
901// a/b -> a*rcp(b) when inaccurate rcp is allowed with afn.
902//
903// With fdiv.fast:
904// a/b -> fdiv.fast(a, b) when !fpmath >= 2.5ulp with denormals flushed.
905//
906// 1/x -> fdiv.fast(1,x) when !fpmath >= 2.5ulp.
907//
908// NOTE: rcp is the preference in cases that both are legal.
909bool AMDGPUCodeGenPrepareImpl::visitFDiv(BinaryOperator &FDiv) {
910 if (DisableFDivExpand)
911 return false;
912
913 Type *Ty = FDiv.getType()->getScalarType();
914 const bool IsFloat = Ty->isFloatTy();
915 if (!IsFloat && !Ty->isDoubleTy())
916 return false;
917
918 // The f64 rcp/rsq approximations are pretty inaccurate. We can do an
919 // expansion around them in codegen. f16 is good enough to always use.
920
921 const FPMathOperator *FPOp = cast<const FPMathOperator>(&FDiv);
922 const FastMathFlags DivFMF = FPOp->getFastMathFlags();
923 const float ReqdAccuracy = FPOp->getFPAccuracy();
924
925 FastMathFlags SqrtFMF;
926
927 Value *Num = FDiv.getOperand(0);
928 Value *Den = FDiv.getOperand(1);
929
930 Value *RsqOp = nullptr;
931 auto *DenII = dyn_cast<IntrinsicInst>(Den);
932 if (DenII && DenII->getIntrinsicID() == Intrinsic::sqrt &&
933 DenII->hasOneUse()) {
934 const auto *SqrtOp = cast<FPMathOperator>(DenII);
935 SqrtFMF = SqrtOp->getFastMathFlags();
936 if (canOptimizeWithRsq(DivFMF, SqrtFMF))
937 RsqOp = SqrtOp->getOperand(0);
938 }
939
940 // rcp path not yet implemented for f64.
941 if (!IsFloat && !RsqOp)
942 return false;
943
944 // Inaccurate rcp is allowed with afn.
945 //
946 // Defer to codegen to handle this.
947 //
948 // TODO: Decide on an interpretation for interactions between afn + arcp +
949 // !fpmath, and make it consistent between here and codegen. For now, defer
950 // expansion of afn to codegen. The current interpretation is so aggressive we
951 // don't need any pre-consideration here when we have better information. A
952 // more conservative interpretation could use handling here.
953 const bool AllowInaccurateRcp = DivFMF.approxFunc();
954 if (!RsqOp && AllowInaccurateRcp)
955 return false;
956
957 // Defer the correct implementations to codegen.
958 if (IsFloat && ReqdAccuracy < 1.0f)
959 return false;
960
961 IRBuilder<> Builder(std::next(FDiv.getIterator()));
962 Builder.setFastMathFlags(DivFMF);
963 Builder.SetCurrentDebugLocation(FDiv.getDebugLoc());
964
965 SmallVector<Value *, 4> NumVals;
966 SmallVector<Value *, 4> DenVals;
967 SmallVector<Value *, 4> RsqDenVals;
968 extractValues(Builder, NumVals, Num);
969 extractValues(Builder, DenVals, Den);
970
971 if (RsqOp)
972 extractValues(Builder, RsqDenVals, RsqOp);
973
974 SmallVector<Value *, 4> ResultVals(NumVals.size());
975 for (int I = 0, E = NumVals.size(); I != E; ++I) {
976 Value *NumElt = NumVals[I];
977 Value *DenElt = DenVals[I];
978 Value *RsqDenElt = RsqOp ? RsqDenVals[I] : nullptr;
979
980 Value *NewElt =
981 visitFDivElement(Builder, NumElt, DenElt, DivFMF, SqrtFMF, RsqDenElt,
982 cast<Instruction>(FPOp), ReqdAccuracy);
983 if (!NewElt) {
984 // Keep the original, but scalarized.
985
986 // This has the unfortunate side effect of sometimes scalarizing when
987 // we're not going to do anything.
988 NewElt = Builder.CreateFDiv(NumElt, DenElt);
989 if (auto *NewEltInst = dyn_cast<Instruction>(NewElt))
990 NewEltInst->copyMetadata(FDiv);
991 }
992
993 ResultVals[I] = NewElt;
994 }
995
996 Value *NewVal = insertValues(Builder, FDiv.getType(), ResultVals);
997
998 if (NewVal) {
999 FDiv.replaceAllUsesWith(NewVal);
1000 NewVal->takeName(&FDiv);
1001 DeadVals.push_back(&FDiv);
1002 }
1003
1004 return true;
1005}
1006
1007static std::pair<Value*, Value*> getMul64(IRBuilder<> &Builder,
1008 Value *LHS, Value *RHS) {
1009 Type *I32Ty = Builder.getInt32Ty();
1010 Type *I64Ty = Builder.getInt64Ty();
1011
1012 Value *LHS_EXT64 = Builder.CreateZExt(LHS, I64Ty);
1013 Value *RHS_EXT64 = Builder.CreateZExt(RHS, I64Ty);
1014 Value *MUL64 = Builder.CreateMul(LHS_EXT64, RHS_EXT64);
1015 Value *Lo = Builder.CreateTrunc(MUL64, I32Ty);
1016 Value *Hi = Builder.CreateLShr(MUL64, Builder.getInt64(32));
1017 Hi = Builder.CreateTrunc(Hi, I32Ty);
1018 return std::pair(Lo, Hi);
1019}
1020
1021static Value* getMulHu(IRBuilder<> &Builder, Value *LHS, Value *RHS) {
1022 return getMul64(Builder, LHS, RHS).second;
1023}
1024
1025/// Figure out how many bits are really needed for this division.
1026/// \p MaxDivBits is an optimization hint to bypass the second
1027/// ComputeNumSignBits/computeKnownBits call if the first one is
1028/// insufficient.
1029unsigned AMDGPUCodeGenPrepareImpl::getDivNumBits(BinaryOperator &I, Value *Num,
1030 Value *Den,
1031 unsigned MaxDivBits,
1032 bool IsSigned) const {
1034 Den->getType()->getScalarSizeInBits());
1035 unsigned SSBits = Num->getType()->getScalarSizeInBits();
1036 if (IsSigned) {
1037 unsigned RHSSignBits = ComputeNumSignBits(Den, SQ.DL, SQ.AC, &I, SQ.DT);
1038 // A sign bit needs to be reserved for shrinking.
1039 unsigned DivBits = SSBits - RHSSignBits + 1;
1040 if (DivBits > MaxDivBits)
1041 return SSBits;
1042
1043 unsigned LHSSignBits = ComputeNumSignBits(Num, SQ.DL, SQ.AC, &I);
1044
1045 unsigned SignBits = std::min(LHSSignBits, RHSSignBits);
1046 DivBits = SSBits - SignBits + 1;
1047 return DivBits;
1048 }
1049
1050 // All bits are used for unsigned division for Num or Den in range
1051 // (SignedMax, UnsignedMax].
1052 KnownBits Known = computeKnownBits(Den, SQ.getWithInstruction(&I));
1053 unsigned RHSBits = Known.countMaxActiveBits();
1054 if (RHSBits > MaxDivBits)
1055 return SSBits;
1056
1058 unsigned LHSBits = Known.countMaxActiveBits();
1059
1060 unsigned DivBits = std::max(LHSBits, RHSBits);
1061 return DivBits;
1062}
1063
1064Value *AMDGPUCodeGenPrepareImpl::expandDivRemToFloat(IRBuilder<> &Builder,
1065 BinaryOperator &I,
1066 Value *Num, Value *Den,
1067 bool IsDiv,
1068 bool IsSigned) const {
1069 unsigned DivBits = getDivNumBits(I, Num, Den, 23, IsSigned);
1070
1071 if (DivBits > (IsSigned ? 23 : 22))
1072 return nullptr;
1073 return expandDivRemToFloatImpl(Builder, I, Num, Den, DivBits, IsDiv,
1074 IsSigned);
1075}
1076
1077Value *AMDGPUCodeGenPrepareImpl::expandDivRemToFloatImpl(
1078 IRBuilder<> &Builder, BinaryOperator &I, Value *Num, Value *Den,
1079 unsigned DivBits, bool IsDiv, bool IsSigned) const {
1080
1081 // v_rcp_f32(float(X)) can have an error of 1 ulp.
1082 // This would cause incorrect calculation of Y/X if:
1083 // Y = (0x7FFFFF/X)*(X-0)-1
1084 // were allowed.
1085 //
1086 // For example,
1087 // (0x7FF6D3/0x000FE7) would erroneously produce 2060 instead of 2059.
1088 // (0x7FF8F5/0x007EFB) would erroneously produce 258 instead of 257.
1089 //
1090 // Thus, we conservatively restrict expandDivRemToFloatImpl to
1091 // [-0x400000,0x3FFFFF] for IsSigned
1092 // [ 0x000000,0x3FFFFF] for !IsSigned.
1093 assert(0 < DivBits && DivBits <= (IsSigned ? 23 : 22) &&
1094 "abs(Num) must be <= 0x400000 for expandDivRemToFloatImpl to work "
1095 "correctly");
1096
1097 Type *I32Ty = Builder.getInt32Ty();
1098 Num = Builder.CreateTrunc(Num, I32Ty);
1099 Den = Builder.CreateTrunc(Den, I32Ty);
1100
1101 Type *F32Ty = Builder.getFloatTy();
1102 ConstantInt *One = Builder.getInt32(1);
1103
1104 // int ia = (int)LHS;
1105 Value *IA = Num;
1106
1107 // int ib, (int)RHS;
1108 Value *IB = Den;
1109
1110 // float fa = (float)ia;
1111 Value *FA = IsSigned ? Builder.CreateSIToFP(IA, F32Ty)
1112 : Builder.CreateUIToFP(IA, F32Ty);
1113
1114 // float fb = (float)ib;
1115 Value *FB = IsSigned ? Builder.CreateSIToFP(IB, F32Ty)
1116 : Builder.CreateUIToFP(IB, F32Ty);
1117
1118 Value *RCP = Builder.CreateIntrinsic(Intrinsic::amdgcn_rcp,
1119 Builder.getFloatTy(), {FB});
1120
1121 // The calculation:
1122 // fq = fa*recip(fb)
1123 // may be too small due to the 1ulp accuracy in the recip
1124 // operation and rounding issues. Since fq is truncated to produce
1125 // an integer value it may be too small by one. This is
1126 // dealt with by incrementing fa by 1ulp:
1127 // fq = (fa+1ulp)*recip(fb)
1128 // This will increase fa's magnitude by at most 0.5
1129 // (i.e. when fabs(fa)==0x400000 the LSB of the mantissa represents 0.5).
1130 // Thus, this method is safe since fa must be incremented by at least 1.0
1131 // for the quotient to increase by one.
1132
1133 Value *FABits = Builder.CreateBitCast(FA, I32Ty);
1134 Value *FABitsInc = Builder.CreateAdd(FABits, One);
1135 FA = Builder.CreateBitCast(FABitsInc, F32Ty);
1136
1137 Value *FQM = Builder.CreateFMul(FA, RCP);
1138
1139 // fq = trunc(fqm);
1140 Value *FQ = Builder.CreateUnaryIntrinsic(Intrinsic::trunc, FQM);
1141
1142 // int iq = (int)fq;
1143 Value *IQ = IsSigned ? Builder.CreateFPToSI(FQ, I32Ty)
1144 : Builder.CreateFPToUI(FQ, I32Ty);
1145
1146 Value *Res = IQ;
1147 if (!IsDiv) {
1148 // Rem needs compensation, it's easier to recompute it
1149 Value *Rem = Builder.CreateMul(IQ, Den);
1150 Res = Builder.CreateSub(Num, Rem);
1151 }
1152
1153 return Res;
1154}
1155
1156// Try to recognize special cases the DAG will emit special, better expansions
1157// than the general expansion we do here.
1158
1159// TODO: It would be better to just directly handle those optimizations here.
1160bool AMDGPUCodeGenPrepareImpl::divHasSpecialOptimization(BinaryOperator &I,
1161 Value *Num,
1162 Value *Den) const {
1163 if (Constant *C = dyn_cast<Constant>(Den)) {
1164 // Arbitrary constants get a better expansion as long as a wider mulhi is
1165 // legal.
1166 if (C->getType()->getScalarSizeInBits() <= 32)
1167 return true;
1168
1169 // TODO: Sdiv check for not exact for some reason.
1170
1171 // If there's no wider mulhi, there's only a better expansion for powers of
1172 // two.
1173 // TODO: Should really know for each vector element.
1175 return true;
1176
1177 return false;
1178 }
1179
1180 if (BinaryOperator *BinOpDen = dyn_cast<BinaryOperator>(Den)) {
1181 // fold (udiv x, (shl c, y)) -> x >>u (log2(c)+y) iff c is power of 2
1182 if (BinOpDen->getOpcode() == Instruction::Shl &&
1183 isa<Constant>(BinOpDen->getOperand(0)) &&
1184 isKnownToBeAPowerOfTwo(BinOpDen->getOperand(0), true,
1185 SQ.getWithInstruction(&I))) {
1186 return true;
1187 }
1188 }
1189
1190 return false;
1191}
1192
1193static Value *getSign32(Value *V, IRBuilder<> &Builder, const DataLayout DL) {
1194 // Check whether the sign can be determined statically.
1196 if (Known.isNegative())
1197 return Constant::getAllOnesValue(V->getType());
1198 if (Known.isNonNegative())
1199 return Constant::getNullValue(V->getType());
1200 return Builder.CreateAShr(V, Builder.getInt32(31));
1201}
1202
1203Value *AMDGPUCodeGenPrepareImpl::expandDivRem32(IRBuilder<> &Builder,
1204 BinaryOperator &I, Value *X,
1205 Value *Y) const {
1206 Instruction::BinaryOps Opc = I.getOpcode();
1207 assert(Opc == Instruction::URem || Opc == Instruction::UDiv ||
1208 Opc == Instruction::SRem || Opc == Instruction::SDiv);
1209
1210 FastMathFlags FMF;
1211 FMF.setFast();
1212 Builder.setFastMathFlags(FMF);
1213
1214 if (divHasSpecialOptimization(I, X, Y))
1215 return nullptr; // Keep it for later optimization.
1216
1217 bool IsDiv = Opc == Instruction::UDiv || Opc == Instruction::SDiv;
1218 bool IsSigned = Opc == Instruction::SRem || Opc == Instruction::SDiv;
1219
1220 Type *Ty = X->getType();
1221 Type *I32Ty = Builder.getInt32Ty();
1222 Type *F32Ty = Builder.getFloatTy();
1223
1224 if (Ty->getScalarSizeInBits() != 32) {
1225 if (IsSigned) {
1226 X = Builder.CreateSExtOrTrunc(X, I32Ty);
1227 Y = Builder.CreateSExtOrTrunc(Y, I32Ty);
1228 } else {
1229 X = Builder.CreateZExtOrTrunc(X, I32Ty);
1230 Y = Builder.CreateZExtOrTrunc(Y, I32Ty);
1231 }
1232 }
1233
1234 if (Value *Res = expandDivRemToFloat(Builder, I, X, Y, IsDiv, IsSigned)) {
1235 return IsSigned ? Builder.CreateSExtOrTrunc(Res, Ty) :
1236 Builder.CreateZExtOrTrunc(Res, Ty);
1237 }
1238
1239 ConstantInt *Zero = Builder.getInt32(0);
1240 ConstantInt *One = Builder.getInt32(1);
1241
1242 Value *Sign = nullptr;
1243 if (IsSigned) {
1244 Value *SignX = getSign32(X, Builder, DL);
1245 Value *SignY = getSign32(Y, Builder, DL);
1246 // Remainder sign is the same as LHS
1247 Sign = IsDiv ? Builder.CreateXor(SignX, SignY) : SignX;
1248
1249 X = Builder.CreateAdd(X, SignX);
1250 Y = Builder.CreateAdd(Y, SignY);
1251
1252 X = Builder.CreateXor(X, SignX);
1253 Y = Builder.CreateXor(Y, SignY);
1254 }
1255
1256 // The algorithm here is based on ideas from "Software Integer Division", Tom
1257 // Rodeheffer, August 2008.
1258 //
1259 // unsigned udiv(unsigned x, unsigned y) {
1260 // // Initial estimate of inv(y). The constant is less than 2^32 to ensure
1261 // // that this is a lower bound on inv(y), even if some of the calculations
1262 // // round up.
1263 // unsigned z = (unsigned)((4294967296.0 - 512.0) * v_rcp_f32((float)y));
1264 //
1265 // // One round of UNR (Unsigned integer Newton-Raphson) to improve z.
1266 // // Empirically this is guaranteed to give a "two-y" lower bound on
1267 // // inv(y).
1268 // z += umulh(z, -y * z);
1269 //
1270 // // Quotient/remainder estimate.
1271 // unsigned q = umulh(x, z);
1272 // unsigned r = x - q * y;
1273 //
1274 // // Two rounds of quotient/remainder refinement.
1275 // if (r >= y) {
1276 // ++q;
1277 // r -= y;
1278 // }
1279 // if (r >= y) {
1280 // ++q;
1281 // r -= y;
1282 // }
1283 //
1284 // return q;
1285 // }
1286
1287 // Initial estimate of inv(y).
1288 Value *FloatY = Builder.CreateUIToFP(Y, F32Ty);
1289 Value *RcpY = Builder.CreateIntrinsic(Intrinsic::amdgcn_rcp, F32Ty, {FloatY});
1290 Constant *Scale = ConstantFP::get(F32Ty, llvm::bit_cast<float>(0x4F7FFFFE));
1291 Value *ScaledY = Builder.CreateFMul(RcpY, Scale);
1292 Value *Z = Builder.CreateFPToUI(ScaledY, I32Ty);
1293
1294 // One round of UNR.
1295 Value *NegY = Builder.CreateSub(Zero, Y);
1296 Value *NegYZ = Builder.CreateMul(NegY, Z);
1297 Z = Builder.CreateAdd(Z, getMulHu(Builder, Z, NegYZ));
1298
1299 // Quotient/remainder estimate.
1300 Value *Q = getMulHu(Builder, X, Z);
1301 Value *R = Builder.CreateSub(X, Builder.CreateMul(Q, Y));
1302
1303 // First quotient/remainder refinement.
1304 Value *Cond = Builder.CreateICmpUGE(R, Y);
1305 if (IsDiv)
1306 Q = Builder.CreateSelect(Cond, Builder.CreateAdd(Q, One), Q);
1307 R = Builder.CreateSelect(Cond, Builder.CreateSub(R, Y), R);
1308
1309 // Second quotient/remainder refinement.
1310 Cond = Builder.CreateICmpUGE(R, Y);
1311 Value *Res;
1312 if (IsDiv)
1313 Res = Builder.CreateSelect(Cond, Builder.CreateAdd(Q, One), Q);
1314 else
1315 Res = Builder.CreateSelect(Cond, Builder.CreateSub(R, Y), R);
1316
1317 if (IsSigned) {
1318 Res = Builder.CreateXor(Res, Sign);
1319 Res = Builder.CreateSub(Res, Sign);
1320 Res = Builder.CreateSExtOrTrunc(Res, Ty);
1321 } else {
1322 Res = Builder.CreateZExtOrTrunc(Res, Ty);
1323 }
1324 return Res;
1325}
1326
1327Value *AMDGPUCodeGenPrepareImpl::shrinkDivRem64(IRBuilder<> &Builder,
1328 BinaryOperator &I, Value *Num,
1329 Value *Den) const {
1330 if (!ExpandDiv64InIR && divHasSpecialOptimization(I, Num, Den))
1331 return nullptr; // Keep it for later optimization.
1332
1333 Instruction::BinaryOps Opc = I.getOpcode();
1334
1335 bool IsDiv = Opc == Instruction::SDiv || Opc == Instruction::UDiv;
1336 bool IsSigned = Opc == Instruction::SDiv || Opc == Instruction::SRem;
1337
1338 unsigned NumDivBits = getDivNumBits(I, Num, Den, 32, IsSigned);
1339 if (NumDivBits > 32)
1340 return nullptr;
1341
1342 Value *Narrowed = nullptr;
1343 if (NumDivBits <= (IsSigned ? 23 : 22)) {
1344 Narrowed = expandDivRemToFloatImpl(Builder, I, Num, Den, NumDivBits, IsDiv,
1345 IsSigned);
1346 } else if (NumDivBits <= (IsSigned ? 31 : 32)) {
1347 // Do not use 32-bit division if dividend may be -2147483648.
1348 // Otherwise 32-bit division cannot be used safely.
1349 // -2147483648/1 and -2147483648/-1 are not equal,
1350 // but they produce the same lower 32-bit result.
1351 Narrowed = expandDivRem32(Builder, I, Num, Den);
1352 }
1353
1354 if (Narrowed) {
1355 return IsSigned ? Builder.CreateSExt(Narrowed, Num->getType()) :
1356 Builder.CreateZExt(Narrowed, Num->getType());
1357 }
1358
1359 return nullptr;
1360}
1361
1362void AMDGPUCodeGenPrepareImpl::expandDivRem64(BinaryOperator &I) const {
1363 Instruction::BinaryOps Opc = I.getOpcode();
1364 // Do the general expansion.
1365 if (Opc == Instruction::UDiv || Opc == Instruction::SDiv) {
1367 return;
1368 }
1369
1370 if (Opc == Instruction::URem || Opc == Instruction::SRem) {
1372 return;
1373 }
1374
1375 llvm_unreachable("not a division");
1376}
1377
1378/*
1379This will cause non-byte load in consistency, for example:
1380```
1381 %load = load i1, ptr addrspace(4) %arg, align 4
1382 %zext = zext i1 %load to
1383 i64 %add = add i64 %zext
1384```
1385Instead of creating `s_and_b32 s0, s0, 1`,
1386it will create `s_and_b32 s0, s0, 0xff`.
1387We accept this change since the non-byte load assumes the upper bits
1388within the byte are all 0.
1389*/
1390bool AMDGPUCodeGenPrepareImpl::tryNarrowMathIfNoOverflow(Instruction *I) {
1391 unsigned Opc = I->getOpcode();
1392 Type *OldType = I->getType();
1393
1394 if (Opc != Instruction::Add && Opc != Instruction::Mul)
1395 return false;
1396
1397 unsigned OrigBit = OldType->getScalarSizeInBits();
1398
1399 if (Opc != Instruction::Add && Opc != Instruction::Mul)
1400 llvm_unreachable("Unexpected opcode, only valid for Instruction::Add and "
1401 "Instruction::Mul.");
1402
1403 unsigned MaxBitsNeeded = computeKnownBits(I, DL).countMaxActiveBits();
1404
1405 MaxBitsNeeded = std::max<unsigned>(bit_ceil(MaxBitsNeeded), 8);
1406 Type *NewType = DL.getSmallestLegalIntType(I->getContext(), MaxBitsNeeded);
1407 if (!NewType)
1408 return false;
1409 unsigned NewBit = NewType->getIntegerBitWidth();
1410 if (NewBit >= OrigBit)
1411 return false;
1412 NewType = I->getType()->getWithNewBitWidth(NewBit);
1413
1414 // Old cost
1415 InstructionCost OldCost =
1417 // New cost of new op
1418 InstructionCost NewCost =
1420 // New cost of narrowing 2 operands (use trunc)
1421 int NumOfNonConstOps = 2;
1422 if (isa<Constant>(I->getOperand(0)) || isa<Constant>(I->getOperand(1))) {
1423 // Cannot be both constant, should be propagated
1424 NumOfNonConstOps = 1;
1425 }
1426 NewCost += NumOfNonConstOps * TTI.getCastInstrCost(Instruction::Trunc,
1427 NewType, OldType,
1430 // New cost of zext narrowed result to original type
1431 NewCost +=
1432 TTI.getCastInstrCost(Instruction::ZExt, OldType, NewType,
1434 if (NewCost >= OldCost)
1435 return false;
1436
1437 IRBuilder<> Builder(I);
1438 Value *Trunc0 = Builder.CreateTrunc(I->getOperand(0), NewType);
1439 Value *Trunc1 = Builder.CreateTrunc(I->getOperand(1), NewType);
1440 Value *Arith =
1441 Builder.CreateBinOp((Instruction::BinaryOps)Opc, Trunc0, Trunc1);
1442
1443 Value *Zext = Builder.CreateZExt(Arith, OldType);
1444 I->replaceAllUsesWith(Zext);
1445 DeadVals.push_back(I);
1446 return true;
1447}
1448
1449bool AMDGPUCodeGenPrepareImpl::visitBinaryOperator(BinaryOperator &I) {
1450 if (foldBinOpIntoSelect(I))
1451 return true;
1452
1453 if (UseMul24Intrin && replaceMulWithMul24(I))
1454 return true;
1455 if (tryNarrowMathIfNoOverflow(&I))
1456 return true;
1457
1458 bool Changed = false;
1459 Instruction::BinaryOps Opc = I.getOpcode();
1460 Type *Ty = I.getType();
1461 Value *NewDiv = nullptr;
1462 unsigned ScalarSize = Ty->getScalarSizeInBits();
1463
1465
1466 if ((Opc == Instruction::URem || Opc == Instruction::UDiv ||
1467 Opc == Instruction::SRem || Opc == Instruction::SDiv) &&
1468 ScalarSize <= 64 &&
1469 !DisableIDivExpand) {
1470 Value *Num = I.getOperand(0);
1471 Value *Den = I.getOperand(1);
1472 IRBuilder<> Builder(&I);
1473 Builder.SetCurrentDebugLocation(I.getDebugLoc());
1474
1475 if (auto *VT = dyn_cast<FixedVectorType>(Ty)) {
1476 NewDiv = PoisonValue::get(VT);
1477
1478 for (unsigned N = 0, E = VT->getNumElements(); N != E; ++N) {
1479 Value *NumEltN = Builder.CreateExtractElement(Num, N);
1480 Value *DenEltN = Builder.CreateExtractElement(Den, N);
1481
1482 Value *NewElt;
1483 if (ScalarSize <= 32) {
1484 NewElt = expandDivRem32(Builder, I, NumEltN, DenEltN);
1485 if (!NewElt)
1486 NewElt = Builder.CreateBinOp(Opc, NumEltN, DenEltN);
1487 } else {
1488 // See if this 64-bit division can be shrunk to 32/24-bits before
1489 // producing the general expansion.
1490 NewElt = shrinkDivRem64(Builder, I, NumEltN, DenEltN);
1491 if (!NewElt) {
1492 // The general 64-bit expansion introduces control flow and doesn't
1493 // return the new value. Just insert a scalar copy and defer
1494 // expanding it.
1495 NewElt = Builder.CreateBinOp(Opc, NumEltN, DenEltN);
1496 // CreateBinOp does constant folding. If the operands are constant,
1497 // it will return a Constant instead of a BinaryOperator.
1498 if (auto *NewEltBO = dyn_cast<BinaryOperator>(NewElt))
1499 Div64ToExpand.push_back(NewEltBO);
1500 }
1501 }
1502
1503 if (auto *NewEltI = dyn_cast<Instruction>(NewElt))
1504 NewEltI->copyIRFlags(&I);
1505
1506 NewDiv = Builder.CreateInsertElement(NewDiv, NewElt, N);
1507 }
1508 } else {
1509 if (ScalarSize <= 32)
1510 NewDiv = expandDivRem32(Builder, I, Num, Den);
1511 else {
1512 NewDiv = shrinkDivRem64(Builder, I, Num, Den);
1513 if (!NewDiv)
1514 Div64ToExpand.push_back(&I);
1515 }
1516 }
1517
1518 if (NewDiv) {
1519 I.replaceAllUsesWith(NewDiv);
1520 DeadVals.push_back(&I);
1521 Changed = true;
1522 }
1523 }
1524
1525 if (ExpandDiv64InIR) {
1526 // TODO: We get much worse code in specially handled constant cases.
1527 for (BinaryOperator *Div : Div64ToExpand) {
1528 expandDivRem64(*Div);
1529 FlowChanged = true;
1530 Changed = true;
1531 }
1532 }
1533
1534 return Changed;
1535}
1536
1537bool AMDGPUCodeGenPrepareImpl::visitLoadInst(LoadInst &I) {
1538 if (!WidenLoads)
1539 return false;
1540
1541 if ((I.getPointerAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS ||
1542 I.getPointerAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS_32BIT) &&
1543 canWidenScalarExtLoad(I)) {
1544 IRBuilder<> Builder(&I);
1545 Builder.SetCurrentDebugLocation(I.getDebugLoc());
1546
1547 Type *I32Ty = Builder.getInt32Ty();
1548 LoadInst *WidenLoad = Builder.CreateLoad(I32Ty, I.getPointerOperand());
1550
1551 // The widened load reads the original bytes in the low bits, so a !range
1552 // lower bound still holds. Convert it to the new type and don't make
1553 // assumptions about the high bits.
1554 if (auto *Range = I.getMetadata(LLVMContext::MD_range)) {
1555 ConstantInt *Lower = mdconst::extract<ConstantInt>(Range->getOperand(0));
1556
1557 if (!Lower->isNullValue()) {
1558 Metadata *LowAndHigh[] = {
1559 ConstantAsMetadata::get(ConstantInt::get(I32Ty, Lower->getValue().zext(32))),
1560 // Don't make assumptions about the high bits.
1561 ConstantAsMetadata::get(ConstantInt::get(I32Ty, 0))
1562 };
1563
1564 WidenLoad->setMetadata(LLVMContext::MD_range,
1565 MDNode::get(F.getContext(), LowAndHigh));
1566 }
1567 }
1568
1569 int TySize = DL.getTypeSizeInBits(I.getType());
1570 Type *IntNTy = Builder.getIntNTy(TySize);
1571 Value *ValTrunc = Builder.CreateTrunc(WidenLoad, IntNTy);
1572 Value *ValOrig = Builder.CreateBitCast(ValTrunc, I.getType());
1573 I.replaceAllUsesWith(ValOrig);
1574 DeadVals.push_back(&I);
1575 return true;
1576 }
1577
1578 return false;
1579}
1580
1581bool AMDGPUCodeGenPrepareImpl::visitSelectInst(SelectInst &I) {
1582 FPMathOperator *FPOp = dyn_cast<FPMathOperator>(&I);
1583 if (!FPOp)
1584 return false;
1585
1586 Value *X;
1587 Value *Fract = nullptr;
1588
1589 // Match:
1590 // (x - floor(x)) >= MIN_CONSTANT ? MIN_CONSTANT : (x - floor(x))
1591 //
1592 // This is the preferred way to implement fract.
1593 // TODO: Could also match with compare against 1.0
1594 const APFloat *C;
1596 Value *FractSrc = matchFractPatImpl(*X, *C);
1597 if (!FractSrc)
1598 return false;
1599 IRBuilder<> Builder(&I);
1600 Builder.setFastMathFlags(FPOp->getFastMathFlags());
1601 Fract = applyFractPat(Builder, FractSrc);
1602 } else {
1603 // Match patterns which may appear in legacy implementations of the fract()
1604 // function, built around the nan-avoidant minnum intrinsic. These are the
1605 // core pattern plus additional clamping of inf and nan values on the
1606 // result.
1607 Value *Cond = I.getCondition();
1608 Value *TrueVal = I.getTrueValue();
1609 Value *FalseVal = I.getFalseValue();
1610 Value *CmpVal;
1611 CmpPredicate IsNanPred;
1612
1613 // Match fract pattern with nan check.
1614 if (!match(Cond, m_FCmp(IsNanPred, m_Value(CmpVal), m_NonNaN())))
1615 return false;
1616
1617 IRBuilder<> Builder(&I);
1618 Builder.setFastMathFlags(FPOp->getFastMathFlags());
1619
1620 if (IsNanPred == FCmpInst::FCMP_UNO && TrueVal == CmpVal &&
1621 CmpVal == matchFractPatNanAvoidant(*FalseVal)) {
1622 // isnan(x) ? x : fract(x)
1623 Fract = applyFractPat(Builder, CmpVal);
1624 } else if (IsNanPred == FCmpInst::FCMP_ORD && FalseVal == CmpVal) {
1625 if (CmpVal == matchFractPatNanAvoidant(*TrueVal)) {
1626 // !isnan(x) ? fract(x) : x
1627 Fract = applyFractPat(Builder, CmpVal);
1628 } else {
1629 // Match an intermediate clamp infinity to 0 pattern. i.e.
1630 // !isnan(x) ? (!isinf(x) ? fract(x) : 0.0) : x
1631 CmpPredicate PredInf;
1632 Value *IfNotInf;
1633
1634 if (!match(TrueVal, m_Select(m_FCmp(PredInf, m_FAbs(m_Specific(CmpVal)),
1635 m_PosInf()),
1636 m_Value(IfNotInf), m_PosZeroFP())) ||
1637 PredInf != FCmpInst::FCMP_UNE ||
1638 CmpVal != matchFractPatNanAvoidant(*IfNotInf))
1639 return false;
1640
1641 SelectInst *ClampInfSelect = cast<SelectInst>(TrueVal);
1642
1643 // Insert before the fabs
1644 Value *InsertPt =
1645 cast<Instruction>(ClampInfSelect->getCondition())->getOperand(0);
1646
1647 Builder.SetInsertPoint(cast<Instruction>(InsertPt));
1648 Value *NewFract = applyFractPat(Builder, CmpVal);
1649 NewFract->takeName(TrueVal);
1650
1651 // Thread the new fract into the inf clamping sequence.
1652 DeadVals.push_back(ClampInfSelect->getOperand(1));
1653 ClampInfSelect->setOperand(1, NewFract);
1654
1655 // The outer select nan handling is also absorbed into the fract.
1656 Fract = ClampInfSelect;
1657 }
1658 } else
1659 return false;
1660 }
1661
1662 Fract->takeName(&I);
1663 I.replaceAllUsesWith(Fract);
1664 DeadVals.push_back(&I);
1665 return true;
1666}
1667
1668static bool areInSameBB(const Value *A, const Value *B) {
1669 const auto *IA = dyn_cast<Instruction>(A);
1670 const auto *IB = dyn_cast<Instruction>(B);
1671 return IA && IB && IA->getParent() == IB->getParent();
1672}
1673
1674// Helper for breaking large PHIs that returns true when an extractelement on V
1675// is likely to be folded away by the DAG combiner.
1677 const auto *FVT = dyn_cast<FixedVectorType>(V->getType());
1678 if (!FVT)
1679 return false;
1680
1681 const Value *CurVal = V;
1682
1683 // Check for insertelements, keeping track of the elements covered.
1684 BitVector EltsCovered(FVT->getNumElements());
1685 while (const auto *IE = dyn_cast<InsertElementInst>(CurVal)) {
1686 const auto *Idx = dyn_cast<ConstantInt>(IE->getOperand(2));
1687
1688 // Non constant index/out of bounds index -> folding is unlikely.
1689 // The latter is more of a sanity check because canonical IR should just
1690 // have replaced those with poison.
1691 if (!Idx || Idx->getZExtValue() >= FVT->getNumElements())
1692 return false;
1693
1694 const auto *VecSrc = IE->getOperand(0);
1695
1696 // If the vector source is another instruction, it must be in the same basic
1697 // block. Otherwise, the DAGCombiner won't see the whole thing and is
1698 // unlikely to be able to do anything interesting here.
1699 if (isa<Instruction>(VecSrc) && !areInSameBB(VecSrc, IE))
1700 return false;
1701
1702 CurVal = VecSrc;
1703 EltsCovered.set(Idx->getZExtValue());
1704
1705 // All elements covered.
1706 if (EltsCovered.all())
1707 return true;
1708 }
1709
1710 // We either didn't find a single insertelement, or the insertelement chain
1711 // ended before all elements were covered. Check for other interesting values.
1712
1713 // Constants are always interesting because we can just constant fold the
1714 // extractelements.
1715 if (isa<Constant>(CurVal))
1716 return true;
1717
1718 // shufflevector is likely to be profitable if either operand is a constant,
1719 // or if either source is in the same block.
1720 // This is because shufflevector is most often lowered as a series of
1721 // insert/extract elements anyway.
1722 if (const auto *SV = dyn_cast<ShuffleVectorInst>(CurVal)) {
1723 return isa<Constant>(SV->getOperand(1)) ||
1724 areInSameBB(SV, SV->getOperand(0)) ||
1725 areInSameBB(SV, SV->getOperand(1));
1726 }
1727
1728 return false;
1729}
1730
1731static void collectPHINodes(const PHINode &I,
1733 const auto [It, Inserted] = SeenPHIs.insert(&I);
1734 if (!Inserted)
1735 return;
1736
1737 for (const Value *Inc : I.incoming_values()) {
1738 if (const auto *PhiInc = dyn_cast<PHINode>(Inc))
1739 collectPHINodes(*PhiInc, SeenPHIs);
1740 }
1741
1742 for (const User *U : I.users()) {
1743 if (const auto *PhiU = dyn_cast<PHINode>(U))
1744 collectPHINodes(*PhiU, SeenPHIs);
1745 }
1746}
1747
1748bool AMDGPUCodeGenPrepareImpl::canBreakPHINode(const PHINode &I) {
1749 // Check in the cache first.
1750 if (const auto It = BreakPhiNodesCache.find(&I);
1751 It != BreakPhiNodesCache.end())
1752 return It->second;
1753
1754 // We consider PHI nodes as part of "chains", so given a PHI node I, we
1755 // recursively consider all its users and incoming values that are also PHI
1756 // nodes. We then make a decision about all of those PHIs at once. Either they
1757 // all get broken up, or none of them do. That way, we avoid cases where a
1758 // single PHI is/is not broken and we end up reforming/exploding a vector
1759 // multiple times, or even worse, doing it in a loop.
1760 SmallPtrSet<const PHINode *, 8> WorkList;
1761 collectPHINodes(I, WorkList);
1762
1763#ifndef NDEBUG
1764 // Check that none of the PHI nodes in the worklist are in the map. If some of
1765 // them are, it means we're not good enough at collecting related PHIs.
1766 for (const PHINode *WLP : WorkList) {
1767 assert(BreakPhiNodesCache.count(WLP) == 0);
1768 }
1769#endif
1770
1771 // To consider a PHI profitable to break, we need to see some interesting
1772 // incoming values. At least 2/3rd (rounded up) of all PHIs in the worklist
1773 // must have one to consider all PHIs breakable.
1774 //
1775 // This threshold has been determined through performance testing.
1776 //
1777 // Note that the computation below is equivalent to
1778 //
1779 // (unsigned)ceil((K / 3.0) * 2)
1780 //
1781 // It's simply written this way to avoid mixing integral/FP arithmetic.
1782 const auto Threshold = (alignTo(WorkList.size() * 2, 3) / 3);
1783 unsigned NumBreakablePHIs = 0;
1784 bool CanBreak = false;
1785 for (const PHINode *Cur : WorkList) {
1786 // Don't break PHIs that have no interesting incoming values. That is, where
1787 // there is no clear opportunity to fold the "extractelement" instructions
1788 // we would add.
1789 //
1790 // Note: IC does not run after this pass, so we're only interested in the
1791 // foldings that the DAG combiner can do.
1792 if (any_of(Cur->incoming_values(), isInterestingPHIIncomingValue)) {
1793 if (++NumBreakablePHIs >= Threshold) {
1794 CanBreak = true;
1795 break;
1796 }
1797 }
1798 }
1799
1800 for (const PHINode *Cur : WorkList)
1801 BreakPhiNodesCache[Cur] = CanBreak;
1802
1803 return CanBreak;
1804}
1805
1806/// Helper class for "break large PHIs" (visitPHINode).
1807///
1808/// This represents a slice of a PHI's incoming value, which is made up of:
1809/// - The type of the slice (Ty)
1810/// - The index in the incoming value's vector where the slice starts (Idx)
1811/// - The number of elements in the slice (NumElts).
1812/// It also keeps track of the NewPHI node inserted for this particular slice.
1813///
1814/// Slice examples:
1815/// <4 x i64> -> Split into four i64 slices.
1816/// -> [i64, 0, 1], [i64, 1, 1], [i64, 2, 1], [i64, 3, 1]
1817/// <5 x i16> -> Split into 2 <2 x i16> slices + a i16 tail.
1818/// -> [<2 x i16>, 0, 2], [<2 x i16>, 2, 2], [i16, 4, 1]
1820public:
1821 VectorSlice(Type *Ty, unsigned Idx, unsigned NumElts)
1822 : Ty(Ty), Idx(Idx), NumElts(NumElts) {}
1823
1824 Type *Ty = nullptr;
1825 unsigned Idx = 0;
1826 unsigned NumElts = 0;
1827 PHINode *NewPHI = nullptr;
1828
1829 /// Slice \p Inc according to the information contained within this slice.
1830 /// This is cached, so if called multiple times for the same \p BB & \p Inc
1831 /// pair, it returns the same Sliced value as well.
1832 ///
1833 /// Note this *intentionally* does not return the same value for, say,
1834 /// [%bb.0, %0] & [%bb.1, %0] as:
1835 /// - It could cause issues with dominance (e.g. if bb.1 is seen first, then
1836 /// the value in bb.1 may not be reachable from bb.0 if it's its
1837 /// predecessor.)
1838 /// - We also want to make our extract instructions as local as possible so
1839 /// the DAG has better chances of folding them out. Duplicating them like
1840 /// that is beneficial in that regard.
1841 ///
1842 /// This is both a minor optimization to avoid creating duplicate
1843 /// instructions, but also a requirement for correctness. It is not forbidden
1844 /// for a PHI node to have the same [BB, Val] pair multiple times. If we
1845 /// returned a new value each time, those previously identical pairs would all
1846 /// have different incoming values (from the same block) and it'd cause a "PHI
1847 /// node has multiple entries for the same basic block with different incoming
1848 /// values!" verifier error.
1849 Value *getSlicedVal(BasicBlock *BB, Value *Inc, StringRef NewValName) {
1850 Value *&Res = SlicedVals[{BB, Inc}];
1851 if (Res)
1852 return Res;
1853
1855 if (Instruction *IncInst = dyn_cast<Instruction>(Inc))
1856 B.SetCurrentDebugLocation(IncInst->getDebugLoc());
1857
1858 if (NumElts > 1) {
1860 for (unsigned K = Idx; K < (Idx + NumElts); ++K)
1861 Mask.push_back(K);
1862 Res = B.CreateShuffleVector(Inc, Mask, NewValName);
1863 } else
1864 Res = B.CreateExtractElement(Inc, Idx, NewValName);
1865
1866 return Res;
1867 }
1868
1869private:
1871};
1872
1873bool AMDGPUCodeGenPrepareImpl::visitPHINode(PHINode &I) {
1874 // Break-up fixed-vector PHIs into smaller pieces.
1875 // Default threshold is 32, so it breaks up any vector that's >32 bits into
1876 // its elements, or into 32-bit pieces (for 8/16 bit elts).
1877 //
1878 // This is only helpful for DAGISel because it doesn't handle large PHIs as
1879 // well as GlobalISel. DAGISel lowers PHIs by using CopyToReg/CopyFromReg.
1880 // With large, odd-sized PHIs we may end up needing many `build_vector`
1881 // operations with most elements being "undef". This inhibits a lot of
1882 // optimization opportunities and can result in unreasonably high register
1883 // pressure and the inevitable stack spilling.
1884 if (!BreakLargePHIs || getCGPassBuilderOption(TM).EnableGlobalISelOption ==
1885 cl::boolOrDefault::BOU_TRUE)
1886 return false;
1887
1888 FixedVectorType *FVT = dyn_cast<FixedVectorType>(I.getType());
1889 if (!FVT || FVT->getNumElements() == 1 ||
1890 DL.getTypeSizeInBits(FVT) <= BreakLargePHIsThreshold)
1891 return false;
1892
1893 if (!ForceBreakLargePHIs && !canBreakPHINode(I))
1894 return false;
1895
1896 std::vector<VectorSlice> Slices;
1897
1898 Type *EltTy = FVT->getElementType();
1899 {
1900 unsigned Idx = 0;
1901 // For 8/16 bits type, don't scalarize fully but break it up into as many
1902 // 32-bit slices as we can, and scalarize the tail.
1903 const unsigned EltSize = DL.getTypeSizeInBits(EltTy);
1904 const unsigned NumElts = FVT->getNumElements();
1905 if (EltSize == 8 || EltSize == 16) {
1906 const unsigned SubVecSize = (32 / EltSize);
1907 Type *SubVecTy = FixedVectorType::get(EltTy, SubVecSize);
1908 for (unsigned End = alignDown(NumElts, SubVecSize); Idx < End;
1909 Idx += SubVecSize)
1910 Slices.emplace_back(SubVecTy, Idx, SubVecSize);
1911 }
1912
1913 // Scalarize all remaining elements.
1914 for (; Idx < NumElts; ++Idx)
1915 Slices.emplace_back(EltTy, Idx, 1);
1916 }
1917
1918 assert(Slices.size() > 1);
1919
1920 // Create one PHI per vector piece. The "VectorSlice" class takes care of
1921 // creating the necessary instruction to extract the relevant slices of each
1922 // incoming value.
1923 IRBuilder<> B(I.getParent());
1924 B.SetCurrentDebugLocation(I.getDebugLoc());
1925
1926 unsigned IncNameSuffix = 0;
1927 for (VectorSlice &S : Slices) {
1928 // We need to reset the build on each iteration, because getSlicedVal may
1929 // have inserted something into I's BB.
1930 B.SetInsertPoint(I.getParent()->getFirstNonPHIIt());
1931 S.NewPHI = B.CreatePHI(S.Ty, I.getNumIncomingValues());
1932
1933 for (const auto &[Idx, BB] : enumerate(I.blocks())) {
1934 S.NewPHI->addIncoming(S.getSlicedVal(BB, I.getIncomingValue(Idx),
1935 "largephi.extractslice" +
1936 std::to_string(IncNameSuffix++)),
1937 BB);
1938 }
1939 }
1940
1941 // And replace this PHI with a vector of all the previous PHI values.
1942 Value *Vec = PoisonValue::get(FVT);
1943 unsigned NameSuffix = 0;
1944 for (VectorSlice &S : Slices) {
1945 const auto ValName = "largephi.insertslice" + std::to_string(NameSuffix++);
1946 if (S.NumElts > 1)
1947 Vec = B.CreateInsertVector(FVT, Vec, S.NewPHI, S.Idx, ValName);
1948 else
1949 Vec = B.CreateInsertElement(Vec, S.NewPHI, S.Idx, ValName);
1950 }
1951
1952 I.replaceAllUsesWith(Vec);
1953 DeadVals.push_back(&I);
1954 return true;
1955}
1956
1957/// \param V Value to check
1958/// \param DL DataLayout
1959/// \param TM TargetMachine (TODO: remove once DL contains nullptr values)
1960/// \param AS Target Address Space
1961/// \return true if \p V cannot be the null value of \p AS, false otherwise.
1962static bool isPtrKnownNeverNull(const Value *V, const DataLayout &DL,
1963 const AMDGPUTargetMachine &TM, unsigned AS) {
1964 // Pointer cannot be null if it's a block address, GV or alloca.
1965 // NOTE: We don't support extern_weak, but if we did, we'd need to check for
1966 // it as the symbol could be null in such cases.
1968 return true;
1969
1970 // Check nonnull arguments.
1971 if (const auto *Arg = dyn_cast<Argument>(V); Arg && Arg->hasNonNullAttr())
1972 return true;
1973
1974 // Check nonnull loads.
1975 if (const auto *Load = dyn_cast<LoadInst>(V);
1976 Load && Load->hasMetadata(LLVMContext::MD_nonnull))
1977 return true;
1978
1979 // getUnderlyingObject may have looked through another addrspacecast, although
1980 // the optimizable situations most likely folded out by now.
1981 if (AS != cast<PointerType>(V->getType())->getAddressSpace())
1982 return false;
1983
1984 // TODO: Calls that return nonnull?
1985
1986 // For all other things, use KnownBits.
1987 // We either use 0 or all bits set to indicate null, so check whether the
1988 // value can be zero or all ones.
1989 //
1990 // TODO: Use ValueTracking's isKnownNeverNull if it becomes aware that some
1991 // address spaces have non-zero null values.
1992 auto SrcPtrKB = computeKnownBits(V, DL);
1993 const auto NullVal = AMDGPU::getNullPointerValue(AS);
1994
1995 assert(SrcPtrKB.getBitWidth() == DL.getPointerSizeInBits(AS));
1996 assert((NullVal == 0 || NullVal == -1) &&
1997 "don't know how to check for this null value!");
1998 return NullVal ? !SrcPtrKB.getMaxValue().isAllOnes() : SrcPtrKB.isNonZero();
1999}
2000
2001bool AMDGPUCodeGenPrepareImpl::visitAddrSpaceCastInst(AddrSpaceCastInst &I) {
2002 // TODO: This is target-independent reasoning about the source pointer being
2003 // non-null, and would fit better in a generic pass such as
2004 // AggressiveInstCombine. It lives here for now because proving the source is
2005 // not the null value requires knowing the numeric null pointer value of the
2006 // source address space, which is not yet a first-class IR concept.
2007
2008 // If the flag is already set there is nothing to do.
2009 if (I.hasNonNull())
2010 return false;
2011
2012 // It is often difficult to prove that a vector of pointers cannot have any
2013 // nulls in it, so it's unclear if it's worth supporting.
2014 if (I.getType()->isVectorTy())
2015 return false;
2016
2017 // The nonnull flag only affects the lowering of casts from/to priv/local to
2018 // flat, so only bother proving non-null for those.
2019 const unsigned SrcAS = I.getSrcAddressSpace();
2020 const unsigned DstAS = I.getDestAddressSpace();
2021
2022 bool CanLower = false;
2023 if (SrcAS == AMDGPUAS::FLAT_ADDRESS)
2024 CanLower = (DstAS == AMDGPUAS::LOCAL_ADDRESS ||
2025 DstAS == AMDGPUAS::PRIVATE_ADDRESS);
2026 else if (DstAS == AMDGPUAS::FLAT_ADDRESS)
2027 CanLower = (SrcAS == AMDGPUAS::LOCAL_ADDRESS ||
2028 SrcAS == AMDGPUAS::PRIVATE_ADDRESS);
2029 if (!CanLower)
2030 return false;
2031
2033 getUnderlyingObjects(I.getOperand(0), WorkList);
2034 if (!all_of(WorkList, [&](const Value *V) {
2035 return isPtrKnownNeverNull(V, DL, TM, SrcAS);
2036 }))
2037 return false;
2038
2039 I.setNonNull();
2040 return true;
2041}
2042
2043bool AMDGPUCodeGenPrepareImpl::visitIntrinsicInst(IntrinsicInst &I) {
2044 Intrinsic::ID IID = I.getIntrinsicID();
2045 switch (IID) {
2046 case Intrinsic::minnum:
2047 case Intrinsic::minimumnum:
2048 case Intrinsic::minimum:
2049 return visitFMinLike(I);
2050 case Intrinsic::sqrt:
2051 return visitSqrt(I);
2052 case Intrinsic::log:
2053 case Intrinsic::log10:
2054 return visitLog(cast<FPMathOperator>(I), IID);
2055 case Intrinsic::log2:
2056 // No reason to handle log2.
2057 return false;
2058 case Intrinsic::amdgcn_mbcnt_lo:
2059 return visitMbcntLo(I);
2060 case Intrinsic::amdgcn_mbcnt_hi:
2061 return visitMbcntHi(I);
2062 case Intrinsic::vector_reduce_add:
2063 return visitVectorReduceAdd(I);
2064 case Intrinsic::uadd_sat:
2065 case Intrinsic::sadd_sat:
2066 return visitSaturatingAdd(I);
2067 default:
2068 return false;
2069 }
2070}
2071
2072/// Match the core sequence in the fract pattern (x - floor(x), which doesn't
2073/// need to consider edge case handling.
2074Value *AMDGPUCodeGenPrepareImpl::matchFractPatImpl(Value &FractSrc,
2075 const APFloat &C) const {
2076 if (ST.hasFractBug())
2077 return nullptr;
2078
2079 Type *Ty = FractSrc.getType();
2080 if (!isLegalFloatingTy(Ty->getScalarType()))
2081 return nullptr;
2082
2083 APFloat OneNextDown = APFloat::getOne(C.getSemantics());
2084 OneNextDown.next(true);
2085
2086 // Match nextafter(1.0, -1)
2087 if (OneNextDown != C)
2088 return nullptr;
2089
2090 Value *FloorSrc;
2091 if (match(&FractSrc, m_FSub(m_Value(FloorSrc), m_Intrinsic<Intrinsic::floor>(
2092 m_Deferred(FloorSrc)))))
2093 return FloorSrc;
2094 return nullptr;
2095}
2096
2097/// Match non-nan fract pattern.
2098// MIN_CONSTANT = nextafter(1.0, -1.0)
2099/// minnum(fsub(x, floor(x)), MIN_CONSTANT)
2100/// minimumnum(fsub(x, floor(x)), MIN_CONSTANT)
2101/// minimum(fsub(x, floor(x)), MIN_CONSTANT)
2102
2103// x_sub_floor >= MIN_CONSTANT ? MIN_CONSTANT : x_sub_floor;
2104///
2105/// If fract is a useful instruction for the subtarget. Does not account for the
2106/// nan handling; the instruction has a nan check on the input value.
2107Value *AMDGPUCodeGenPrepareImpl::matchFractPatNanAvoidant(Value &V) {
2108 Value *Arg0;
2109 const APFloat *C;
2110
2111 // The value is only used in contexts where we know the input isn't a nan, so
2112 // any of the fmin variants are fine.
2113 if (!match(&V,
2117 return nullptr;
2118
2119 return matchFractPatImpl(*Arg0, *C);
2120}
2121
2122Value *AMDGPUCodeGenPrepareImpl::applyFractPat(IRBuilder<> &Builder,
2123 Value *FractArg) {
2124 SmallVector<Value *, 4> FractVals;
2125 extractValues(Builder, FractVals, FractArg);
2126
2127 SmallVector<Value *, 4> ResultVals(FractVals.size());
2128
2129 Type *Ty = FractArg->getType()->getScalarType();
2130 for (unsigned I = 0, E = FractVals.size(); I != E; ++I) {
2131 ResultVals[I] =
2132 Builder.CreateIntrinsic(Intrinsic::amdgcn_fract, {Ty}, {FractVals[I]});
2133 }
2134
2135 return insertValues(Builder, FractArg->getType(), ResultVals);
2136}
2137
2138bool AMDGPUCodeGenPrepareImpl::visitFMinLike(IntrinsicInst &I) {
2139 const APFloat *C;
2140 Value *FractArg;
2141
2142 // minimum(x - floor(x), MIN_CONSTANT)
2143 Value *X;
2144 if (!ST.hasFractBug() &&
2146 FractArg = matchFractPatImpl(*X, *C);
2147 if (!FractArg)
2148 return false;
2149 } else {
2150 // minnum(x - floor(x), MIN_CONSTANT)
2151 FractArg = matchFractPatNanAvoidant(I);
2152 if (!FractArg)
2153 return false;
2154
2155 // Match pattern for fract intrinsic in contexts where the nan check has
2156 // been optimized out (and hope the knowledge the source can't be nan wasn't
2157 // lost).
2158 if (!I.hasNoNaNs() && !isKnownNeverNaN(FractArg, SQ.getWithInstruction(&I)))
2159 return false;
2160 }
2161
2162 IRBuilder<> Builder(&I);
2163 FastMathFlags FMF = I.getFastMathFlags();
2164 FMF.setNoNaNs();
2165 Builder.setFastMathFlags(FMF);
2166
2167 Value *Fract = applyFractPat(Builder, FractArg);
2168 Fract->takeName(&I);
2169 I.replaceAllUsesWith(Fract);
2170 DeadVals.push_back(&I);
2171 return true;
2172}
2173
2174// Expand llvm.sqrt.f32 calls with !fpmath metadata in a semi-fast way.
2175bool AMDGPUCodeGenPrepareImpl::visitSqrt(IntrinsicInst &Sqrt) {
2176 Type *Ty = Sqrt.getType()->getScalarType();
2177 if (!Ty->isFloatTy())
2178 return false;
2179
2180 const FPMathOperator *FPOp = cast<const FPMathOperator>(&Sqrt);
2181 FastMathFlags SqrtFMF = FPOp->getFastMathFlags();
2182
2183 // We're trying to handle the fast-but-not-that-fast case only. The lowering
2184 // of fast llvm.sqrt will give the raw instruction anyway.
2185 if (SqrtFMF.approxFunc())
2186 return false;
2187
2188 const float ReqdAccuracy = FPOp->getFPAccuracy();
2189
2190 // Defer correctly rounded expansion to codegen.
2191 if (ReqdAccuracy < 1.0f)
2192 return false;
2193
2194 Value *SrcVal = Sqrt.getOperand(0);
2195 bool CanTreatAsDAZ = canIgnoreDenormalInput(SrcVal, &Sqrt);
2196
2197 // The raw instruction is 1 ulp, but the correction for denormal handling
2198 // brings it to 2.
2199 if (!CanTreatAsDAZ && ReqdAccuracy < 2.0f)
2200 return false;
2201
2202 IRBuilder<> Builder(&Sqrt);
2203 SmallVector<Value *, 4> SrcVals;
2204 extractValues(Builder, SrcVals, SrcVal);
2205
2206 SmallVector<Value *, 4> ResultVals(SrcVals.size());
2207 for (int I = 0, E = SrcVals.size(); I != E; ++I) {
2208 if (CanTreatAsDAZ)
2209 ResultVals[I] = Builder.CreateCall(getSqrtF32(), SrcVals[I]);
2210 else
2211 ResultVals[I] = emitSqrtIEEE2ULP(Builder, SrcVals[I], SqrtFMF);
2212 }
2213
2214 Value *NewSqrt = insertValues(Builder, Sqrt.getType(), ResultVals);
2215 NewSqrt->takeName(&Sqrt);
2216 Sqrt.replaceAllUsesWith(NewSqrt);
2217 DeadVals.push_back(&Sqrt);
2218 return true;
2219}
2220
2221/// Replace log and log10 intrinsic calls based on fpmath metadata.
2222bool AMDGPUCodeGenPrepareImpl::visitLog(FPMathOperator &Log,
2223 Intrinsic::ID IID) {
2224 Type *Ty = Log.getType();
2225 if (!Ty->getScalarType()->isHalfTy() || !ST.has16BitInsts())
2226 return false;
2227
2228 FastMathFlags FMF = Log.getFastMathFlags();
2229
2230 // Defer fast math cases to codegen.
2231 if (FMF.approxFunc())
2232 return false;
2233
2234 // Limit experimentally determined from OpenCL conformance test (1.79)
2235 if (Log.getFPAccuracy() < 1.80f)
2236 return false;
2237
2238 IRBuilder<> Builder(&cast<CallInst>(Log));
2239
2240 // Use the generic intrinsic for convenience in the vector case. Codegen will
2241 // recognize the denormal handling is not necessary from the fpext.
2242 // TODO: Move to generic code
2243 Value *Log2 =
2244 Builder.CreateUnaryIntrinsic(Intrinsic::log2, Log.getOperand(0), FMF);
2245
2246 double Log2BaseInverted =
2247 IID == Intrinsic::log10 ? numbers::ln2 / numbers::ln10 : numbers::ln2;
2248 Value *Mul =
2249 Builder.CreateFMulFMF(Log2, ConstantFP::get(Ty, Log2BaseInverted), FMF);
2250
2251 Mul->takeName(&Log);
2252
2253 Log.replaceAllUsesWith(Mul);
2254 DeadVals.push_back(&Log);
2255 return true;
2256}
2257
2258bool AMDGPUCodeGenPrepare::runOnFunction(Function &F) {
2259 if (skipFunction(F))
2260 return false;
2261
2262 auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
2263 if (!TPC)
2264 return false;
2265
2266 const AMDGPUTargetMachine &TM = TPC->getTM<AMDGPUTargetMachine>();
2267 const TargetTransformInfo &TTI =
2268 getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
2269 const TargetLibraryInfo *TLI =
2270 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
2271 AssumptionCache *AC =
2272 &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
2273 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
2274 const DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr;
2275 const UniformityInfo &UA =
2276 getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
2277 return AMDGPUCodeGenPrepareImpl(F, TM, TTI, TLI, AC, DT, UA).run();
2278}
2279
2282 const AMDGPUTargetMachine &ATM = static_cast<const AMDGPUTargetMachine &>(TM);
2283 const TargetTransformInfo &TTI = FAM.getResult<TargetIRAnalysis>(F);
2284 const TargetLibraryInfo *TLI = &FAM.getResult<TargetLibraryAnalysis>(F);
2285 AssumptionCache *AC = &FAM.getResult<AssumptionAnalysis>(F);
2286 const DominatorTree *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
2287 const UniformityInfo &UA = FAM.getResult<UniformityInfoAnalysis>(F);
2288 AMDGPUCodeGenPrepareImpl Impl(F, ATM, TTI, TLI, AC, DT, UA);
2289 if (!Impl.run())
2290 return PreservedAnalyses::all();
2292 if (!Impl.FlowChanged)
2294 return PA;
2295}
2296
2297INITIALIZE_PASS_BEGIN(AMDGPUCodeGenPrepare, DEBUG_TYPE,
2298 "AMDGPU IR optimizations", false, false)
2303INITIALIZE_PASS_END(AMDGPUCodeGenPrepare, DEBUG_TYPE, "AMDGPU IR optimizations",
2305
2306/// Create a workitem.id.x intrinsic call with range metadata.
2307CallInst *AMDGPUCodeGenPrepareImpl::createWorkitemIdX(IRBuilder<> &B) const {
2308 CallInst *Tid =
2309 B.CreateIntrinsicWithoutFolding(Intrinsic::amdgcn_workitem_id_x, {});
2310 ST.makeLIDRangeMetadata(Tid);
2311 return Tid;
2312}
2313
2314/// Replace the instruction with a direct workitem.id.x call.
2315void AMDGPUCodeGenPrepareImpl::replaceWithWorkitemIdX(Instruction &I) const {
2316 IRBuilder<> B(&I);
2317 CallInst *Tid = createWorkitemIdX(B);
2319 ReplaceInstWithValue(BI, Tid);
2320}
2321
2322/// Replace the instruction with (workitem.id.x & mask).
2323void AMDGPUCodeGenPrepareImpl::replaceWithMaskedWorkitemIdX(
2324 Instruction &I, unsigned WaveSize) const {
2325 IRBuilder<> B(&I);
2326 CallInst *Tid = createWorkitemIdX(B);
2327 Constant *Mask = ConstantInt::get(Tid->getType(), WaveSize - 1);
2328 Value *AndInst = B.CreateAnd(Tid, Mask);
2330 ReplaceInstWithValue(BI, AndInst);
2331}
2332
2333/// Try to optimize mbcnt instruction by replacing with workitem.id.x when
2334/// work group size allows direct computation of lane ID.
2335/// Returns true if optimization was applied, false otherwise.
2336bool AMDGPUCodeGenPrepareImpl::tryReplaceWithWorkitemId(Instruction &I,
2337 unsigned Wave) const {
2338 std::optional<unsigned> MaybeX = ST.getReqdWorkGroupSize(F, 0);
2339 if (!MaybeX)
2340 return false;
2341
2342 // When work group size == wave_size, each work group contains exactly one
2343 // wave, so the instruction can be replaced with workitem.id.x directly.
2344 if (*MaybeX == Wave) {
2345 replaceWithWorkitemIdX(I);
2346 return true;
2347 }
2348
2349 // When work group evenly splits into waves, compute lane ID within wave
2350 // using bit masking: lane_id = workitem.id.x & (wave_size - 1).
2351 if (ST.hasWavefrontsEvenlySplittingXDim(F, /*RequiresUniformYZ=*/true)) {
2352 replaceWithMaskedWorkitemIdX(I, Wave);
2353 return true;
2354 }
2355
2356 return false;
2357}
2358
2359/// Optimize mbcnt.lo calls on wave32 architectures for lane ID computation.
2360bool AMDGPUCodeGenPrepareImpl::visitMbcntLo(IntrinsicInst &I) const {
2361 // This optimization only applies to wave32 targets where mbcnt.lo operates on
2362 // the full execution mask.
2363 if (!ST.isWave32())
2364 return false;
2365
2366 // Only optimize the pattern mbcnt.lo(~0, 0) which counts active lanes with
2367 // lower IDs.
2368 if (!match(&I,
2370 return false;
2371
2372 return tryReplaceWithWorkitemId(I, ST.getWavefrontSize());
2373}
2374
2375/// Optimize mbcnt.hi calls for lane ID computation.
2376bool AMDGPUCodeGenPrepareImpl::visitMbcntHi(IntrinsicInst &I) const {
2377 // Abort if wave size is not known at compile time.
2378 if (!ST.isWaveSizeKnown())
2379 return false;
2380
2381 unsigned Wave = ST.getWavefrontSize();
2382
2383 // On wave32, the upper 32 bits of execution mask are always 0, so
2384 // mbcnt.hi(mask, val) always returns val unchanged.
2385 if (ST.isWave32()) {
2387 ReplaceInstWithValue(BI, I.getArgOperand(1));
2388 return true;
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:665
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
SmallVector< MachineOperand, 4 > Cond
MachineInstr *& Lo
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
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
unsigned getWavefrontSize() const
bool hasWavefrontsEvenlySplittingXDim(const Function &F, bool RequiresUniformYZ=false) 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:548
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:44
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
static FastMathFlags intersectValue(FastMathFlags LHS, FastMathFlags RHS)
Intersect value flags.
Definition FMF.h:130
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:843
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
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:2669
Value * CreateFDiv(Value *L, Value *R, const Twine &Name="", MDNode *FPMD=nullptr)
Definition IRBuilder.h:1689
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2657
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Definition IRBuilder.h:535
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
Definition IRBuilder.h:2139
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition IRBuilder.h:2716
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateFPToUI(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2167
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2133
void SetCurrentDebugLocation(const DebugLoc &L)
Set location information used by debugging information.
Definition IRBuilder.h:228
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition IRBuilder.h:522
Value * CreateUIToFP(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false, MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2181
void setFastMathFlags(FastMathFlags NewFMF)
Set the fast-math flags to be used with generated fp-math operators.
Definition IRBuilder.h:288
Value * CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2437
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
Definition IRBuilder.h:1826
LLVM_ABI Value * createIsFPClass(Value *FPNum, unsigned Test)
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition IRBuilder.h:465
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1435
Value * CreateFMA(Value *Factor1, Value *Factor2, Value *Summand, FMFSource FMFSource={}, const Twine &Name="")
Create call to the fma intrinsic.
Definition IRBuilder.h:1088
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2243
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Definition IRBuilder.h:1907
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Definition IRBuilder.h:2121
Value * CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2422
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:1418
Type * getFloatTy()
Fetch the type representing a 32-bit floating point value.
Definition IRBuilder.h:550
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2561
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition IRBuilder.h:2107
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1727
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2394
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:196
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1618
Value * CreateSIToFP(Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2193
Value * CreateFMul(Value *L, Value *R, const Twine &Name="", MDNode *FPMD=nullptr)
Definition IRBuilder.h:1670
Value * CreateFNeg(Value *V, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1835
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1588
Value * CreateSExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a SExt or Trunc from the integer value V to DestTy.
Definition IRBuilder.h:2154
Value * CreateFMulFMF(Value *L, Value *R, FMFSource FMFSource, const Twine &Name="", MDNode *FPMD=nullptr)
Definition IRBuilder.h:1675
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1452
LLVM_ABI Value * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *Op, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
Value * CreateFPToSI(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2174
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2909
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.
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.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
An instruction for reading from memory.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1579
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 *CtxI=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:300
LLVM_ABI unsigned getIntegerBitWidth() const
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
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:363
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:222
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:252
LLVM_ABI const fltSemantics & getFltSemantics() const
Definition Type.cpp:96
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:257
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:441
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:549
bool use_empty() const
Definition Value.h:348
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition Value.cpp:396
Type * getElementType() const
self_iterator getIterator()
Definition ilist_node.h:123
#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.
is_zero< true > m_Zero()
Match any null constant or a vector with all elements equal to 0.
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.
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:679
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:1755
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:2570
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:649
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=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 T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
Definition MathExtras.h:546
LLVM_ABI void ReplaceInstWithValue(BasicBlock::iterator &BI, Value *V)
Replace all uses of an instruction (specified by BI) with a value, then remove and delete the origina...
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Definition bit.h:362
LLVM_ABI unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=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.
LLVM_ABI unsigned ComputeMaxSignificantBits(const Value *Op, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Get the upper bound on bit size for this Value Op as a signed integer.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, AssumptionCache *AC=nullptr, const Instruction *CtxI=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.
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:1762
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:408
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
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.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
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...
LLVM_ABI CGPassBuilderOption getCGPassBuilderOption(const TargetMachine &TM)
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
FunctionPass * createAMDGPUCodeGenPreparePass()
To bit_cast(const From &from) noexcept
Definition bit.h:90
DWARFExpression::Operation Op
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...
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition Alignment.h:202
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
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...
#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()
const DataLayout & DL
const DominatorTree * DT
SimplifyQuery getWithInstruction(const Instruction *I) const
AssumptionCache * AC