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(FDiv.getParent(), 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().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()) {
2386 if (auto MaybeX = ST.getReqdWorkGroupSize(F, 0)) {
2387 // Replace mbcnt.hi(mask, val) with val only when work group size matches
2388 // wave size (single wave per work group).
2389 if (*MaybeX == Wave) {
2391 ReplaceInstWithValue(BI, I.getArgOperand(1));
2392 return true;
2393 }
2394 }
2395 }
2396
2397 // Optimize the complete lane ID computation pattern:
2398 // mbcnt.hi(~0, mbcnt.lo(~0, 0)) which counts all active lanes with lower IDs
2399 // across the full execution mask.
2400 using namespace PatternMatch;
2401
2402 // Check for pattern: mbcnt.hi(~0, mbcnt.lo(~0, 0))
2405 m_AllOnes(), m_Zero()))))
2406 return false;
2407
2408 return tryReplaceWithWorkitemId(I, Wave);
2409}
2410
2411/// Check if type is <4 x i8>.
2412static bool isV4I8(Type *Ty) {
2414 return VTy && VTy->getNumElements() == 4 &&
2415 VTy->getElementType()->isIntegerTy(8);
2416}
2417
2418/// Helper to match the dot4 pattern: mul(zext/sext <4 x i8>, zext/sext <4 x
2419/// i8>) Returns true if pattern matches and signedness matches IsSigned.
2420/// Sets A, B to the <4 x i8> sources.
2421static bool matchDot4Pattern(Value *MulOp, Value *&A, Value *&B,
2422 bool IsSigned) {
2423 Value *Src0, *Src1;
2424 if (!match(MulOp, m_Mul(m_Value(Src0), m_Value(Src1))))
2425 return false;
2426
2427 // Check that result type is <4 x i32>
2429 if (!MulTy || MulTy->getNumElements() != 4 ||
2430 !MulTy->getElementType()->isIntegerTy(32))
2431 return false;
2432
2433 // Match zext or sext based on IsSigned
2434 Value *ExtSrc0, *ExtSrc1;
2435 if (IsSigned) {
2436 if (!match(Src0, m_SExt(m_Value(ExtSrc0))) || !isV4I8(ExtSrc0->getType()))
2437 return false;
2438 if (!match(Src1, m_SExt(m_Value(ExtSrc1))) || !isV4I8(ExtSrc1->getType()))
2439 return false;
2440 } else {
2441 if (!match(Src0, m_ZExt(m_Value(ExtSrc0))) || !isV4I8(ExtSrc0->getType()))
2442 return false;
2443 if (!match(Src1, m_ZExt(m_Value(ExtSrc1))) || !isV4I8(ExtSrc1->getType()))
2444 return false;
2445 }
2446
2447 A = ExtSrc0;
2448 B = ExtSrc1;
2449 return true;
2450}
2451
2452/// Try to convert vector.reduce.add(mul(zext/sext <4 x i8>, zext/sext <4 x
2453/// i8>)) to a dot4 intrinsic call (non-saturating case only).
2454bool AMDGPUCodeGenPrepareImpl::visitVectorReduceAdd(IntrinsicInst &I) {
2455 // Check if we have dot4 instructions available
2456 if (!ST.hasDot7Insts() || (!ST.hasDot1Insts() && !ST.hasDot8Insts()))
2457 return false;
2458
2459 Value *A = nullptr, *B = nullptr;
2460
2461 // Try unsigned first, then signed
2462 bool IsSigned = false;
2463 if (!matchDot4Pattern(I.getArgOperand(0), A, B, /*IsSigned=*/false)) {
2464 if (!matchDot4Pattern(I.getArgOperand(0), A, B, /*IsSigned=*/true))
2465 return false;
2466 IsSigned = true;
2467 }
2468
2469 LLVMContext &Ctx = I.getContext();
2470 Type *I32Ty = Type::getInt32Ty(Ctx);
2471 IRBuilder<> Builder(&I);
2472
2473 // Bitcast <4 x i8> to i32
2474 Value *ASrc = Builder.CreateBitCast(A, I32Ty);
2475 Value *BSrc = Builder.CreateBitCast(B, I32Ty);
2476
2477 // Non-saturating case: accumulator is 0, clamp is false
2478 Value *Acc = ConstantInt::get(I32Ty, 0);
2479 Value *Clamp = ConstantInt::getFalse(Ctx);
2480
2481 Intrinsic::ID DotIID =
2482 IsSigned ? Intrinsic::amdgcn_sdot4 : Intrinsic::amdgcn_udot4;
2483
2484 Value *Dot = Builder.CreateIntrinsic(DotIID, {}, {ASrc, BSrc, Acc, Clamp});
2485 Dot->takeName(&I);
2486
2487 I.replaceAllUsesWith(Dot);
2488 DeadVals.push_back(&I);
2489
2490 return true;
2491}
2492
2493/// Try to convert uadd.sat/sadd.sat(vector.reduce.add(mul(...)), c) to a
2494/// saturating dot4 intrinsic. This combine starts at the root (saturating add)
2495/// and looks at its operands.
2496bool AMDGPUCodeGenPrepareImpl::visitSaturatingAdd(IntrinsicInst &I) {
2497 // Check if we have dot4 instructions available
2498 if (!ST.hasDot7Insts() || (!ST.hasDot1Insts() && !ST.hasDot8Insts()))
2499 return false;
2500
2501 Intrinsic::ID IID = I.getIntrinsicID();
2502 bool IsSigned = (IID == Intrinsic::sadd_sat);
2503
2504 // Look for vector.reduce.add as one of the operands (commutative match)
2505 Value *Op0 = I.getArgOperand(0);
2506 Value *Op1 = I.getArgOperand(1);
2507 Value *MulOp = nullptr;
2508 Value *Accum = nullptr;
2509 IntrinsicInst *ReduceInst = nullptr;
2510
2512 ReduceInst = cast<IntrinsicInst>(Op0);
2513 Accum = Op1;
2514 } else if (match(Op1,
2516 ReduceInst = cast<IntrinsicInst>(Op1);
2517 Accum = Op0;
2518 } else {
2519 return false;
2520 }
2521
2522 Value *A = nullptr, *B = nullptr;
2523
2524 if (!matchDot4Pattern(MulOp, A, B, IsSigned))
2525 return false;
2526
2527 LLVMContext &Ctx = I.getContext();
2528 Type *I32Ty = Type::getInt32Ty(Ctx);
2529 IRBuilder<> Builder(&I);
2530
2531 // Bitcast <4 x i8> to i32
2532 Value *ASrc = Builder.CreateBitCast(A, I32Ty);
2533 Value *BSrc = Builder.CreateBitCast(B, I32Ty);
2534
2535 // Saturating case: use the accumulator and set clamp to true
2536 Value *Clamp = ConstantInt::getTrue(Ctx);
2537
2538 Intrinsic::ID DotIID =
2539 IsSigned ? Intrinsic::amdgcn_sdot4 : Intrinsic::amdgcn_udot4;
2540
2541 Value *Dot = Builder.CreateIntrinsic(DotIID, {}, {ASrc, BSrc, Accum, Clamp});
2542 Dot->takeName(&I);
2543
2544 I.replaceAllUsesWith(Dot);
2545 DeadVals.push_back(&I);
2546 // The reduce.add will be dead after this and cleaned up later
2547 if (ReduceInst->use_empty())
2548 DeadVals.push_back(ReduceInst);
2549
2550 return true;
2551}
2552
2553char AMDGPUCodeGenPrepare::ID = 0;
2554
2556 return new AMDGPUCodeGenPrepare();
2557}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static Value * insertValues(IRBuilder<> &Builder, Type *Ty, SmallVectorImpl< Value * > &Values)
static void extractValues(IRBuilder<> &Builder, SmallVectorImpl< Value * > &Values, Value *V)
static Value * getMulHu(IRBuilder<> &Builder, Value *LHS, Value *RHS)
static bool isInterestingPHIIncomingValue(const Value *V)
static SelectInst * findSelectThroughCast(Value *V, CastInst *&Cast)
static bool matchDot4Pattern(Value *MulOp, Value *&A, Value *&B, bool IsSigned)
Helper to match the dot4 pattern: mul(zext/sext <4 x i8>, zext/sext <4 x i8>) Returns true if pattern...
static bool isV4I8(Type *Ty)
Check if type is <4 x i8>.
static std::pair< Value *, Value * > getMul64(IRBuilder<> &Builder, Value *LHS, Value *RHS)
static Value * emitRsqIEEE1ULP(IRBuilder<> &Builder, Value *Src, bool IsNegative)
Emit an expansion of 1.0 / sqrt(Src) good for 1ulp that supports denormals.
static Value * getSign32(Value *V, IRBuilder<> &Builder, const DataLayout DL)
static void collectPHINodes(const PHINode &I, SmallPtrSet< const PHINode *, 8 > &SeenPHIs)
static bool isPtrKnownNeverNull(const Value *V, const DataLayout &DL, const AMDGPUTargetMachine &TM, unsigned AS)
static bool areInSameBB(const Value *A, const Value *B)
static cl::opt< bool > WidenLoads("amdgpu-late-codegenprepare-widen-constant-loads", cl::desc("Widen sub-dword constant address space loads in " "AMDGPULateCodeGenPrepare"), cl::ReallyHidden, cl::init(true))
The AMDGPU TargetMachine interface definition for hw codegen targets.
@ Scaled
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
dxil translate DXIL Translate Metadata
static bool runOnFunction(Function &F, bool PostInlining)
#define DEBUG_TYPE
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
const SmallVectorImpl< MachineOperand > & Cond
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static cl::opt< cl::boolOrDefault > EnableGlobalISelOption("global-isel", cl::Hidden, cl::desc("Enable the \"global\" instruction selector"))
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
LLVM IR instance of the generic uniformity analysis.
Value * RHS
Value * LHS
BinaryOperator * Mul
VectorSlice(Type *Ty, unsigned Idx, unsigned NumElts)
Value * getSlicedVal(BasicBlock *BB, Value *Inc, StringRef NewValName)
Slice Inc according to the information contained within this slice.
PreservedAnalyses run(Function &, FunctionAnalysisManager &)
std::optional< unsigned > getReqdWorkGroupSize(const Function &F, unsigned Dim) const
bool hasWavefrontsEvenlySplittingXDim(const Function &F, bool REquiresUniformYZ=false) const
unsigned getWavefrontSize() const
static APFloat getOne(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative One.
Definition APFloat.h:1192
static APFloat getSmallestNormalized(const fltSemantics &Sem, bool Negative=false)
Returns the smallest (by magnitude) normalized finite number in the given semantics.
Definition APFloat.h:1262
opStatus next(bool nextDown)
Definition APFloat.h:1358
This class represents a conversion between pointers from one address space to another.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
BinaryOps getOpcode() const
Definition InstrTypes.h:409
BitVector & set()
Set all bits in the bitvector.
Definition BitVector.h:366
bool all() const
Returns true if all bits are set.
Definition BitVector.h:194
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
Definition InstrTypes.h:512
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition InstrTypes.h:674
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:537
bool isMinusOne() const
Returns true if this value is exactly -1.0.
Definition Constants.h:488
static LLVM_ABI ConstantFP * getZero(Type *Ty, bool Negative=false)
bool isOne() const
Returns true if this value is exactly +1.0.
Definition Constants.h:485
static LLVM_ABI ConstantFP * getInfinity(Type *Ty, bool Negative=false)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
This is an important base class in LLVM.
Definition Constant.h:43
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
Utility class for floating point operations which can have information about relaxed accuracy require...
Definition Operator.h:202
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags.
Definition Operator.h:291
LLVM_ABI float getFPAccuracy() const
Get the maximum error permitted by this operation in ULPs.
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
void setFast(bool B=true)
Definition FMF.h:96
bool noSignedZeros() const
Definition FMF.h:67
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:867
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
bool isWave32() const
bool isWaveSizeKnown() const
Returns if the wavesize of this subtarget is known reliable.
bool hasFractBug() const
bool isUniformAtDef(ConstValueRefT V) const
Whether V is uniform/non-divergent at its definition.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2679
Value * CreateFDiv(Value *L, Value *R, const Twine &Name="", MDNode *FPMD=nullptr)
Definition IRBuilder.h:1703
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2667
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Definition IRBuilder.h:547
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
Definition IRBuilder.h:2149
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition IRBuilder.h:2726
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateFPToUI(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2177
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2143
void SetCurrentDebugLocation(const DebugLoc &L)
Set location information used by debugging information.
Definition IRBuilder.h:221
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition IRBuilder.h:534
Value * CreateUIToFP(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false, MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2191
void setFastMathFlags(FastMathFlags NewFMF)
Set the fast-math flags to be used with generated fp-math operators.
Definition IRBuilder.h:300
Value * CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2447
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
Definition IRBuilder.h:1840
LLVM_ABI Value * createIsFPClass(Value *FPNum, unsigned Test)
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition IRBuilder.h:477
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1449
Value * CreateFMA(Value *Factor1, Value *Factor2, Value *Summand, FMFSource FMFSource={}, const Twine &Name="")
Create call to the fma intrinsic.
Definition IRBuilder.h:1102
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2253
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Definition IRBuilder.h:1916
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Definition IRBuilder.h:2131
Value * CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2432
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1432
Type * getFloatTy()
Fetch the type representing a 32-bit floating point value.
Definition IRBuilder.h:562
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2571
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition IRBuilder.h:2117
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1741
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2404
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:181
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1632
Value * CreateSIToFP(Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2203
Value * CreateFMul(Value *L, Value *R, const Twine &Name="", MDNode *FPMD=nullptr)
Definition IRBuilder.h:1684
Value * CreateFNeg(Value *V, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1849
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1602
Value * CreateSExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a SExt or Trunc from the integer value V to DestTy.
Definition IRBuilder.h:2164
Value * CreateFMulFMF(Value *L, Value *R, FMFSource FMFSource, const Twine &Name="", MDNode *FPMD=nullptr)
Definition IRBuilder.h:1689
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1466
LLVM_ABI Value * CreateUnaryIntrinsic(Intrinsic::ID ID, Value *Op, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 1 operand which is mangled on its type.
Value * CreateFPToSI(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2184
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2910
Base class for instruction visitors.
Definition InstVisitor.h:78
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
An instruction for reading from memory.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1567
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
This class represents the LLVM 'select' instruction.
const Value * getFalseValue() const
const Value * getCondition() const
const Value * getTrueValue() const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
Wrapper pass for TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
static LLVM_ABI CastContextHint getCastContextHint(const Instruction *I)
Calculates a CastContextHint from I.
LLVM_ABI InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const
@ TCK_RecipThroughput
Reciprocal throughput.
LLVM_ABI InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Opd1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Opd2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr, const TargetLibraryInfo *TLibInfo=nullptr) const
This is an approximation of reciprocal throughput of a math/logic op.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:310
LLVM_ABI unsigned getIntegerBitWidth() const
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:309
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition Type.h:155
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:368
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
Definition Type.h:144
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:232
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition Type.h:158
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
LLVM_ABI const fltSemantics & getFltSemantics() const
Definition Type.cpp:106
Analysis pass which computes UniformityInfo.
Legacy analysis pass which computes a CycleInfo.
void setOperand(unsigned i, Value *Val)
Definition User.h:212
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:439
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
bool use_empty() const
Definition Value.h:346
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition Value.cpp:400
Type * getElementType() const
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CONSTANT_ADDRESS_32BIT
Address space for 32-bit constant memory.
@ LOCAL_ADDRESS
Address space for local memory.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
@ FLAT_ADDRESS
Address space for flat memory.
@ PRIVATE_ADDRESS
Address space for private memory.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr int64_t getNullPointerValue(unsigned AS)
Get the null pointer value for the given address space.
void copyMetadataForWidenedLoad(LoadInst &Dest, const LoadInst &Source)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
auto m_PosZeroFP()
Matches a floating-point positive zero.
AllOnesConstantMatch m_AllOnes()
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
CmpClass_match< LHS, RHS, FCmpInst > m_FCmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
match_deferred< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
ap_match< APFloat > m_APFloatAllowPoison(const APFloat *&Res)
Match APFloat while allowing poison in splat vector constants.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
FMaxMin_match< LHS, RHS, ufmin_pred_ty > m_UnordFMin(const LHS &L, const RHS &R)
Match an 'unordered' floating point minimum function.
auto m_FMinimum(const Opnd0 &Op0, const Opnd1 &Op1)
auto m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
cstfp_pred_ty< is_nonnan > m_NonNaN()
Match a non-NaN FP constant.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
auto m_FMinNum_or_FMinimumNum(const Opnd0 &Op0, const Opnd1 &Op1)
cstfp_pred_ty< is_signed_inf< false > > m_PosInf()
Match a positive infinity FP constant.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
auto m_FAbs(const Opnd0 &Op0)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
initializer< Ty > init(const Ty &Val)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:668
constexpr double ln2
constexpr double ln10
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
GenericUniformityInfo< SSAContext > UniformityInfo
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
Definition Local.cpp:522
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
@ Known
Known to have no common set bits.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2554
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI bool expandRemainderUpTo64Bits(BinaryOperator *Rem)
Generate code to calculate the remainder of two integers, replacing Rem with the generated code.
@ Load
The value being inserted comes from a load (InsertElement only).
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:633
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
Definition MathExtras.h:541
LLVM_ABI void ReplaceInstWithValue(BasicBlock::iterator &BI, Value *V)
Replace all uses of an instruction (specified by BI) with a value, then remove and delete the origina...
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Definition bit.h:362
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
Definition Local.cpp:402
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
LLVM_ABI bool expandDivisionUpTo64Bits(BinaryOperator *Div)
Generate code to divide two integers, replacing Div with the generated code.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
TargetTransformInfo TTI
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
FunctionPass * createAMDGPUCodeGenPreparePass()
To bit_cast(const From &from) noexcept
Definition bit.h:90
DWARFExpression::Operation Op
LLVM_ABI unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return the number of times the sign bit of the register is replicated into the other bits.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI bool isKnownNeverNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
LLVM_ABI unsigned ComputeMaxSignificantBits(const Value *Op, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Get the upper bound on bit size for this Value Op as a signed integer.
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition Alignment.h:197
LLVM_ABI bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return true if the given value is known to have exactly one bit set when defined.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, const LoopInfo *LI=nullptr, unsigned MaxLookup=MaxLookupSearchDepth)
This method is similar to getUnderlyingObject except that it can look through phi and select instruct...
LLVM_ABI CGPassBuilderOption getCGPassBuilderOption()
#define N
DenormalModeKind Input
Denormal treatment kind for floating point instruction inputs in the default floating-point environme...
constexpr bool inputsAreZero() const
Return true if input denormals must be implicitly treated as 0.
static constexpr DenormalMode getPreserveSign()
bool isKnownNeverSubnormal() const
Return true if it's known this can never be a subnormal.
LLVM_ABI bool isKnownNeverLogicalZero(DenormalMode Mode) const
Return true if it's known this can never be interpreted as a zero.
bool isKnownNeverPosInfinity() const
Return true if it's known this can never be +infinity.
const DataLayout & DL
const DominatorTree * DT
SimplifyQuery getWithInstruction(const Instruction *I) const
AssumptionCache * AC