LLVM  16.0.0git
ExpandVectorPredication.cpp
Go to the documentation of this file.
1 //===----- CodeGen/ExpandVectorPredication.cpp - Expand VP intrinsics -----===//
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 // This pass implements IR expansion for vector predication intrinsics, allowing
10 // targets to enable vector predication until just before codegen.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/ADT/Statistic.h"
19 #include "llvm/CodeGen/Passes.h"
20 #include "llvm/IR/Constants.h"
21 #include "llvm/IR/Function.h"
22 #include "llvm/IR/IRBuilder.h"
23 #include "llvm/IR/InstIterator.h"
24 #include "llvm/IR/Instructions.h"
25 #include "llvm/IR/IntrinsicInst.h"
26 #include "llvm/IR/Intrinsics.h"
27 #include "llvm/InitializePasses.h"
28 #include "llvm/Pass.h"
30 #include "llvm/Support/Compiler.h"
31 #include "llvm/Support/Debug.h"
32 
33 using namespace llvm;
34 
37 
38 // Keep this in sync with TargetTransformInfo::VPLegalization.
39 #define VPINTERNAL_VPLEGAL_CASES \
40  VPINTERNAL_CASE(Legal) \
41  VPINTERNAL_CASE(Discard) \
42  VPINTERNAL_CASE(Convert)
43 
44 #define VPINTERNAL_CASE(X) "|" #X
45 
46 // Override options.
48  "expandvp-override-evl-transform", cl::init(""), cl::Hidden,
49  cl::desc("Options: <empty>" VPINTERNAL_VPLEGAL_CASES
50  ". If non-empty, ignore "
51  "TargetTransformInfo and "
52  "always use this transformation for the %evl parameter (Used in "
53  "testing)."));
54 
56  "expandvp-override-mask-transform", cl::init(""), cl::Hidden,
57  cl::desc("Options: <empty>" VPINTERNAL_VPLEGAL_CASES
58  ". If non-empty, Ignore "
59  "TargetTransformInfo and "
60  "always use this transformation for the %mask parameter (Used in "
61  "testing)."));
62 
63 #undef VPINTERNAL_CASE
64 #define VPINTERNAL_CASE(X) .Case(#X, VPLegalization::X)
65 
66 static VPTransform parseOverrideOption(const std::string &TextOpt) {
68 }
69 
70 #undef VPINTERNAL_VPLEGAL_CASES
71 
72 // Whether any override options are set.
73 static bool anyExpandVPOverridesSet() {
74  return !EVLTransformOverride.empty() || !MaskTransformOverride.empty();
75 }
76 
77 #define DEBUG_TYPE "expandvp"
78 
79 STATISTIC(NumFoldedVL, "Number of folded vector length params");
80 STATISTIC(NumLoweredVPOps, "Number of folded vector predication operations");
81 
82 ///// Helpers {
83 
84 /// \returns Whether the vector mask \p MaskVal has all lane bits set.
85 static bool isAllTrueMask(Value *MaskVal) {
86  if (Value *SplattedVal = getSplatValue(MaskVal))
87  if (auto *ConstValue = dyn_cast<Constant>(SplattedVal))
88  return ConstValue->isAllOnesValue();
89 
90  return false;
91 }
92 
93 /// \returns A non-excepting divisor constant for this type.
94 static Constant *getSafeDivisor(Type *DivTy) {
95  assert(DivTy->isIntOrIntVectorTy() && "Unsupported divisor type");
96  return ConstantInt::get(DivTy, 1u, false);
97 }
98 
99 /// Transfer operation properties from \p OldVPI to \p NewVal.
100 static void transferDecorations(Value &NewVal, VPIntrinsic &VPI) {
101  auto *NewInst = dyn_cast<Instruction>(&NewVal);
102  if (!NewInst || !isa<FPMathOperator>(NewVal))
103  return;
104 
105  auto *OldFMOp = dyn_cast<FPMathOperator>(&VPI);
106  if (!OldFMOp)
107  return;
108 
109  NewInst->setFastMathFlags(OldFMOp->getFastMathFlags());
110 }
111 
112 /// Transfer all properties from \p OldOp to \p NewOp and replace all uses.
113 /// OldVP gets erased.
114 static void replaceOperation(Value &NewOp, VPIntrinsic &OldOp) {
115  transferDecorations(NewOp, OldOp);
116  OldOp.replaceAllUsesWith(&NewOp);
117  OldOp.eraseFromParent();
118 }
119 
120 static bool maySpeculateLanes(VPIntrinsic &VPI) {
121  // The result of VP reductions depends on the mask and evl.
122  if (isa<VPReductionIntrinsic>(VPI))
123  return false;
124  // Fallback to whether the intrinsic is speculatable.
126  unsigned FunctionalOpc = OpcOpt.value_or((unsigned)Instruction::Call);
127  return isSafeToSpeculativelyExecuteWithOpcode(FunctionalOpc, &VPI);
128 }
129 
130 //// } Helpers
131 
132 namespace {
133 
134 // Expansion pass state at function scope.
135 struct CachingVPExpander {
136  Function &F;
137  const TargetTransformInfo &TTI;
138 
139  /// \returns A (fixed length) vector with ascending integer indices
140  /// (<0, 1, ..., NumElems-1>).
141  /// \p Builder
142  /// Used for instruction creation.
143  /// \p LaneTy
144  /// Integer element type of the result vector.
145  /// \p NumElems
146  /// Number of vector elements.
147  Value *createStepVector(IRBuilder<> &Builder, Type *LaneTy,
148  unsigned NumElems);
149 
150  /// \returns A bitmask that is true where the lane position is less-than \p
151  /// EVLParam
152  ///
153  /// \p Builder
154  /// Used for instruction creation.
155  /// \p VLParam
156  /// The explicit vector length parameter to test against the lane
157  /// positions.
158  /// \p ElemCount
159  /// Static (potentially scalable) number of vector elements.
160  Value *convertEVLToMask(IRBuilder<> &Builder, Value *EVLParam,
161  ElementCount ElemCount);
162 
163  Value *foldEVLIntoMask(VPIntrinsic &VPI);
164 
165  /// "Remove" the %evl parameter of \p PI by setting it to the static vector
166  /// length of the operation.
167  void discardEVLParameter(VPIntrinsic &PI);
168 
169  /// Lower this VP binary operator to a unpredicated binary operator.
170  Value *expandPredicationInBinaryOperator(IRBuilder<> &Builder,
171  VPIntrinsic &PI);
172 
173  /// Lower this VP reduction to a call to an unpredicated reduction intrinsic.
174  Value *expandPredicationInReduction(IRBuilder<> &Builder,
176 
177  /// Lower this VP memory operation to a non-VP intrinsic.
178  Value *expandPredicationInMemoryIntrinsic(IRBuilder<> &Builder,
179  VPIntrinsic &VPI);
180 
181  /// Lower this VP comparison to a call to an unpredicated comparison.
182  Value *expandPredicationInComparison(IRBuilder<> &Builder,
183  VPCmpIntrinsic &PI);
184 
185  /// Query TTI and expand the vector predication in \p P accordingly.
186  Value *expandPredication(VPIntrinsic &PI);
187 
188  /// Determine how and whether the VPIntrinsic \p VPI shall be expanded. This
189  /// overrides TTI with the cl::opts listed at the top of this file.
190  VPLegalization getVPLegalizationStrategy(const VPIntrinsic &VPI) const;
191  bool UsingTTIOverrides;
192 
193 public:
194  CachingVPExpander(Function &F, const TargetTransformInfo &TTI)
195  : F(F), TTI(TTI), UsingTTIOverrides(anyExpandVPOverridesSet()) {}
196 
197  bool expandVectorPredication();
198 };
199 
200 //// CachingVPExpander {
201 
202 Value *CachingVPExpander::createStepVector(IRBuilder<> &Builder, Type *LaneTy,
203  unsigned NumElems) {
204  // TODO add caching
205  SmallVector<Constant *, 16> ConstElems;
206 
207  for (unsigned Idx = 0; Idx < NumElems; ++Idx)
208  ConstElems.push_back(ConstantInt::get(LaneTy, Idx, false));
209 
210  return ConstantVector::get(ConstElems);
211 }
212 
213 Value *CachingVPExpander::convertEVLToMask(IRBuilder<> &Builder,
214  Value *EVLParam,
215  ElementCount ElemCount) {
216  // TODO add caching
217  // Scalable vector %evl conversion.
218  if (ElemCount.isScalable()) {
219  auto *M = Builder.GetInsertBlock()->getModule();
220  Type *BoolVecTy = VectorType::get(Builder.getInt1Ty(), ElemCount);
221  Function *ActiveMaskFunc = Intrinsic::getDeclaration(
222  M, Intrinsic::get_active_lane_mask, {BoolVecTy, EVLParam->getType()});
223  // `get_active_lane_mask` performs an implicit less-than comparison.
224  Value *ConstZero = Builder.getInt32(0);
225  return Builder.CreateCall(ActiveMaskFunc, {ConstZero, EVLParam});
226  }
227 
228  // Fixed vector %evl conversion.
229  Type *LaneTy = EVLParam->getType();
230  unsigned NumElems = ElemCount.getFixedValue();
231  Value *VLSplat = Builder.CreateVectorSplat(NumElems, EVLParam);
232  Value *IdxVec = createStepVector(Builder, LaneTy, NumElems);
233  return Builder.CreateICmp(CmpInst::ICMP_ULT, IdxVec, VLSplat);
234 }
235 
236 Value *
237 CachingVPExpander::expandPredicationInBinaryOperator(IRBuilder<> &Builder,
238  VPIntrinsic &VPI) {
240  "Implicitly dropping %evl in non-speculatable operator!");
241 
242  auto OC = static_cast<Instruction::BinaryOps>(*VPI.getFunctionalOpcode());
244 
245  Value *Op0 = VPI.getOperand(0);
246  Value *Op1 = VPI.getOperand(1);
247  Value *Mask = VPI.getMaskParam();
248 
249  // Blend in safe operands.
250  if (Mask && !isAllTrueMask(Mask)) {
251  switch (OC) {
252  default:
253  // Can safely ignore the predicate.
254  break;
255 
256  // Division operators need a safe divisor on masked-off lanes (1).
257  case Instruction::UDiv:
258  case Instruction::SDiv:
259  case Instruction::URem:
260  case Instruction::SRem:
261  // 2nd operand must not be zero.
262  Value *SafeDivisor = getSafeDivisor(VPI.getType());
263  Op1 = Builder.CreateSelect(Mask, Op1, SafeDivisor);
264  }
265  }
266 
267  Value *NewBinOp = Builder.CreateBinOp(OC, Op0, Op1, VPI.getName());
268 
269  replaceOperation(*NewBinOp, VPI);
270  return NewBinOp;
271 }
272 
273 static Value *getNeutralReductionElement(const VPReductionIntrinsic &VPI,
274  Type *EltTy) {
275  bool Negative = false;
276  unsigned EltBits = EltTy->getScalarSizeInBits();
277  switch (VPI.getIntrinsicID()) {
278  default:
279  llvm_unreachable("Expecting a VP reduction intrinsic");
280  case Intrinsic::vp_reduce_add:
281  case Intrinsic::vp_reduce_or:
282  case Intrinsic::vp_reduce_xor:
283  case Intrinsic::vp_reduce_umax:
284  return Constant::getNullValue(EltTy);
285  case Intrinsic::vp_reduce_mul:
286  return ConstantInt::get(EltTy, 1, /*IsSigned*/ false);
287  case Intrinsic::vp_reduce_and:
288  case Intrinsic::vp_reduce_umin:
289  return ConstantInt::getAllOnesValue(EltTy);
290  case Intrinsic::vp_reduce_smin:
291  return ConstantInt::get(EltTy->getContext(),
292  APInt::getSignedMaxValue(EltBits));
293  case Intrinsic::vp_reduce_smax:
294  return ConstantInt::get(EltTy->getContext(),
295  APInt::getSignedMinValue(EltBits));
296  case Intrinsic::vp_reduce_fmax:
297  Negative = true;
298  [[fallthrough]];
299  case Intrinsic::vp_reduce_fmin: {
301  const fltSemantics &Semantics = EltTy->getFltSemantics();
302  return !Flags.noNaNs() ? ConstantFP::getQNaN(EltTy, Negative)
303  : !Flags.noInfs()
304  ? ConstantFP::getInfinity(EltTy, Negative)
305  : ConstantFP::get(EltTy,
306  APFloat::getLargest(Semantics, Negative));
307  }
308  case Intrinsic::vp_reduce_fadd:
309  return ConstantFP::getNegativeZero(EltTy);
310  case Intrinsic::vp_reduce_fmul:
311  return ConstantFP::get(EltTy, 1.0);
312  }
313 }
314 
315 Value *
316 CachingVPExpander::expandPredicationInReduction(IRBuilder<> &Builder,
317  VPReductionIntrinsic &VPI) {
319  "Implicitly dropping %evl in non-speculatable operator!");
320 
321  Value *Mask = VPI.getMaskParam();
322  Value *RedOp = VPI.getOperand(VPI.getVectorParamPos());
323 
324  // Insert neutral element in masked-out positions
325  if (Mask && !isAllTrueMask(Mask)) {
326  auto *NeutralElt = getNeutralReductionElement(VPI, VPI.getType());
327  auto *NeutralVector = Builder.CreateVectorSplat(
328  cast<VectorType>(RedOp->getType())->getElementCount(), NeutralElt);
329  RedOp = Builder.CreateSelect(Mask, RedOp, NeutralVector);
330  }
331 
332  Value *Reduction;
333  Value *Start = VPI.getOperand(VPI.getStartParamPos());
334 
335  switch (VPI.getIntrinsicID()) {
336  default:
337  llvm_unreachable("Impossible reduction kind");
338  case Intrinsic::vp_reduce_add:
339  Reduction = Builder.CreateAddReduce(RedOp);
340  Reduction = Builder.CreateAdd(Reduction, Start);
341  break;
342  case Intrinsic::vp_reduce_mul:
343  Reduction = Builder.CreateMulReduce(RedOp);
344  Reduction = Builder.CreateMul(Reduction, Start);
345  break;
346  case Intrinsic::vp_reduce_and:
347  Reduction = Builder.CreateAndReduce(RedOp);
348  Reduction = Builder.CreateAnd(Reduction, Start);
349  break;
350  case Intrinsic::vp_reduce_or:
351  Reduction = Builder.CreateOrReduce(RedOp);
352  Reduction = Builder.CreateOr(Reduction, Start);
353  break;
354  case Intrinsic::vp_reduce_xor:
355  Reduction = Builder.CreateXorReduce(RedOp);
356  Reduction = Builder.CreateXor(Reduction, Start);
357  break;
358  case Intrinsic::vp_reduce_smax:
359  Reduction = Builder.CreateIntMaxReduce(RedOp, /*IsSigned*/ true);
360  Reduction =
361  Builder.CreateBinaryIntrinsic(Intrinsic::smax, Reduction, Start);
362  break;
363  case Intrinsic::vp_reduce_smin:
364  Reduction = Builder.CreateIntMinReduce(RedOp, /*IsSigned*/ true);
365  Reduction =
366  Builder.CreateBinaryIntrinsic(Intrinsic::smin, Reduction, Start);
367  break;
368  case Intrinsic::vp_reduce_umax:
369  Reduction = Builder.CreateIntMaxReduce(RedOp, /*IsSigned*/ false);
370  Reduction =
371  Builder.CreateBinaryIntrinsic(Intrinsic::umax, Reduction, Start);
372  break;
373  case Intrinsic::vp_reduce_umin:
374  Reduction = Builder.CreateIntMinReduce(RedOp, /*IsSigned*/ false);
375  Reduction =
376  Builder.CreateBinaryIntrinsic(Intrinsic::umin, Reduction, Start);
377  break;
378  case Intrinsic::vp_reduce_fmax:
379  Reduction = Builder.CreateFPMaxReduce(RedOp);
381  Reduction =
382  Builder.CreateBinaryIntrinsic(Intrinsic::maxnum, Reduction, Start);
383  break;
384  case Intrinsic::vp_reduce_fmin:
385  Reduction = Builder.CreateFPMinReduce(RedOp);
387  Reduction =
388  Builder.CreateBinaryIntrinsic(Intrinsic::minnum, Reduction, Start);
389  break;
390  case Intrinsic::vp_reduce_fadd:
391  Reduction = Builder.CreateFAddReduce(Start, RedOp);
392  break;
393  case Intrinsic::vp_reduce_fmul:
394  Reduction = Builder.CreateFMulReduce(Start, RedOp);
395  break;
396  }
397 
399  return Reduction;
400 }
401 
402 Value *
403 CachingVPExpander::expandPredicationInMemoryIntrinsic(IRBuilder<> &Builder,
404  VPIntrinsic &VPI) {
406 
407  const auto &DL = F.getParent()->getDataLayout();
408 
409  Value *MaskParam = VPI.getMaskParam();
410  Value *PtrParam = VPI.getMemoryPointerParam();
411  Value *DataParam = VPI.getMemoryDataParam();
412  bool IsUnmasked = isAllTrueMask(MaskParam);
413 
414  MaybeAlign AlignOpt = VPI.getPointerAlignment();
415 
416  Value *NewMemoryInst = nullptr;
417  switch (VPI.getIntrinsicID()) {
418  default:
419  llvm_unreachable("Not a VP memory intrinsic");
420  case Intrinsic::vp_store:
421  if (IsUnmasked) {
422  StoreInst *NewStore =
423  Builder.CreateStore(DataParam, PtrParam, /*IsVolatile*/ false);
424  if (AlignOpt.has_value())
425  NewStore->setAlignment(AlignOpt.value());
426  NewMemoryInst = NewStore;
427  } else
428  NewMemoryInst = Builder.CreateMaskedStore(
429  DataParam, PtrParam, AlignOpt.valueOrOne(), MaskParam);
430 
431  break;
432  case Intrinsic::vp_load:
433  if (IsUnmasked) {
434  LoadInst *NewLoad =
435  Builder.CreateLoad(VPI.getType(), PtrParam, /*IsVolatile*/ false);
436  if (AlignOpt.has_value())
437  NewLoad->setAlignment(AlignOpt.value());
438  NewMemoryInst = NewLoad;
439  } else
440  NewMemoryInst = Builder.CreateMaskedLoad(
441  VPI.getType(), PtrParam, AlignOpt.valueOrOne(), MaskParam);
442 
443  break;
444  case Intrinsic::vp_scatter: {
445  auto *ElementType =
446  cast<VectorType>(DataParam->getType())->getElementType();
447  NewMemoryInst = Builder.CreateMaskedScatter(
448  DataParam, PtrParam,
449  AlignOpt.value_or(DL.getPrefTypeAlign(ElementType)), MaskParam);
450  break;
451  }
452  case Intrinsic::vp_gather: {
453  auto *ElementType = cast<VectorType>(VPI.getType())->getElementType();
454  NewMemoryInst = Builder.CreateMaskedGather(
455  VPI.getType(), PtrParam,
456  AlignOpt.value_or(DL.getPrefTypeAlign(ElementType)), MaskParam, nullptr,
457  VPI.getName());
458  break;
459  }
460  }
461 
462  assert(NewMemoryInst);
463  replaceOperation(*NewMemoryInst, VPI);
464  return NewMemoryInst;
465 }
466 
467 Value *CachingVPExpander::expandPredicationInComparison(IRBuilder<> &Builder,
468  VPCmpIntrinsic &VPI) {
470  "Implicitly dropping %evl in non-speculatable operator!");
471 
472  assert(*VPI.getFunctionalOpcode() == Instruction::ICmp ||
473  *VPI.getFunctionalOpcode() == Instruction::FCmp);
474 
475  Value *Op0 = VPI.getOperand(0);
476  Value *Op1 = VPI.getOperand(1);
477  auto Pred = VPI.getPredicate();
478 
479  auto *NewCmp = Builder.CreateCmp(Pred, Op0, Op1);
480 
481  replaceOperation(*NewCmp, VPI);
482  return NewCmp;
483 }
484 
485 void CachingVPExpander::discardEVLParameter(VPIntrinsic &VPI) {
486  LLVM_DEBUG(dbgs() << "Discard EVL parameter in " << VPI << "\n");
487 
488  if (VPI.canIgnoreVectorLengthParam())
489  return;
490 
491  Value *EVLParam = VPI.getVectorLengthParam();
492  if (!EVLParam)
493  return;
494 
495  ElementCount StaticElemCount = VPI.getStaticVectorLength();
496  Value *MaxEVL = nullptr;
498  if (StaticElemCount.isScalable()) {
499  // TODO add caching
500  auto *M = VPI.getModule();
501  Function *VScaleFunc =
502  Intrinsic::getDeclaration(M, Intrinsic::vscale, Int32Ty);
504  Value *FactorConst = Builder.getInt32(StaticElemCount.getKnownMinValue());
505  Value *VScale = Builder.CreateCall(VScaleFunc, {}, "vscale");
506  MaxEVL = Builder.CreateMul(VScale, FactorConst, "scalable_size",
507  /*NUW*/ true, /*NSW*/ false);
508  } else {
509  MaxEVL = ConstantInt::get(Int32Ty, StaticElemCount.getFixedValue(), false);
510  }
511  VPI.setVectorLengthParam(MaxEVL);
512 }
513 
514 Value *CachingVPExpander::foldEVLIntoMask(VPIntrinsic &VPI) {
515  LLVM_DEBUG(dbgs() << "Folding vlen for " << VPI << '\n');
516 
517  IRBuilder<> Builder(&VPI);
518 
519  // Ineffective %evl parameter and so nothing to do here.
520  if (VPI.canIgnoreVectorLengthParam())
521  return &VPI;
522 
523  // Only VP intrinsics can have an %evl parameter.
524  Value *OldMaskParam = VPI.getMaskParam();
525  Value *OldEVLParam = VPI.getVectorLengthParam();
526  assert(OldMaskParam && "no mask param to fold the vl param into");
527  assert(OldEVLParam && "no EVL param to fold away");
528 
529  LLVM_DEBUG(dbgs() << "OLD evl: " << *OldEVLParam << '\n');
530  LLVM_DEBUG(dbgs() << "OLD mask: " << *OldMaskParam << '\n');
531 
532  // Convert the %evl predication into vector mask predication.
533  ElementCount ElemCount = VPI.getStaticVectorLength();
534  Value *VLMask = convertEVLToMask(Builder, OldEVLParam, ElemCount);
535  Value *NewMaskParam = Builder.CreateAnd(VLMask, OldMaskParam);
536  VPI.setMaskParam(NewMaskParam);
537 
538  // Drop the %evl parameter.
539  discardEVLParameter(VPI);
541  "transformation did not render the evl param ineffective!");
542 
543  // Reassess the modified instruction.
544  return &VPI;
545 }
546 
547 Value *CachingVPExpander::expandPredication(VPIntrinsic &VPI) {
548  LLVM_DEBUG(dbgs() << "Lowering to unpredicated op: " << VPI << '\n');
549 
550  IRBuilder<> Builder(&VPI);
551 
552  // Try lowering to a LLVM instruction first.
553  auto OC = VPI.getFunctionalOpcode();
554 
555  if (OC && Instruction::isBinaryOp(*OC))
556  return expandPredicationInBinaryOperator(Builder, VPI);
557 
558  if (auto *VPRI = dyn_cast<VPReductionIntrinsic>(&VPI))
559  return expandPredicationInReduction(Builder, *VPRI);
560 
561  if (auto *VPCmp = dyn_cast<VPCmpIntrinsic>(&VPI))
562  return expandPredicationInComparison(Builder, *VPCmp);
563 
564  switch (VPI.getIntrinsicID()) {
565  default:
566  break;
567  case Intrinsic::vp_load:
568  case Intrinsic::vp_store:
569  case Intrinsic::vp_gather:
570  case Intrinsic::vp_scatter:
571  return expandPredicationInMemoryIntrinsic(Builder, VPI);
572  }
573 
574  return &VPI;
575 }
576 
577 //// } CachingVPExpander
578 
579 struct TransformJob {
580  VPIntrinsic *PI;
582  TransformJob(VPIntrinsic *PI, TargetTransformInfo::VPLegalization InitStrat)
583  : PI(PI), Strategy(InitStrat) {}
584 
585  bool isDone() const { return Strategy.shouldDoNothing(); }
586 };
587 
588 void sanitizeStrategy(VPIntrinsic &VPI, VPLegalization &LegalizeStrat) {
589  // Operations with speculatable lanes do not strictly need predication.
590  if (maySpeculateLanes(VPI)) {
591  // Converting a speculatable VP intrinsic means dropping %mask and %evl.
592  // No need to expand %evl into the %mask only to ignore that code.
593  if (LegalizeStrat.OpStrategy == VPLegalization::Convert)
595  return;
596  }
597 
598  // We have to preserve the predicating effect of %evl for this
599  // non-speculatable VP intrinsic.
600  // 1) Never discard %evl.
601  // 2) If this VP intrinsic will be expanded to non-VP code, make sure that
602  // %evl gets folded into %mask.
603  if ((LegalizeStrat.EVLParamStrategy == VPLegalization::Discard) ||
604  (LegalizeStrat.OpStrategy == VPLegalization::Convert)) {
606  }
607 }
608 
610 CachingVPExpander::getVPLegalizationStrategy(const VPIntrinsic &VPI) const {
611  auto VPStrat = TTI.getVPLegalizationStrategy(VPI);
612  if (LLVM_LIKELY(!UsingTTIOverrides)) {
613  // No overrides - we are in production.
614  return VPStrat;
615  }
616 
617  // Overrides set - we are in testing, the following does not need to be
618  // efficient.
620  VPStrat.OpStrategy = parseOverrideOption(MaskTransformOverride);
621  return VPStrat;
622 }
623 
624 /// Expand llvm.vp.* intrinsics as requested by \p TTI.
625 bool CachingVPExpander::expandVectorPredication() {
627 
628  // Collect all VPIntrinsics that need expansion and determine their expansion
629  // strategy.
630  for (auto &I : instructions(F)) {
631  auto *VPI = dyn_cast<VPIntrinsic>(&I);
632  if (!VPI)
633  continue;
634  auto VPStrat = getVPLegalizationStrategy(*VPI);
635  sanitizeStrategy(*VPI, VPStrat);
636  if (!VPStrat.shouldDoNothing())
637  Worklist.emplace_back(VPI, VPStrat);
638  }
639  if (Worklist.empty())
640  return false;
641 
642  // Transform all VPIntrinsics on the worklist.
643  LLVM_DEBUG(dbgs() << "\n:::: Transforming " << Worklist.size()
644  << " instructions ::::\n");
645  for (TransformJob Job : Worklist) {
646  // Transform the EVL parameter.
647  switch (Job.Strategy.EVLParamStrategy) {
649  break;
651  discardEVLParameter(*Job.PI);
652  break;
654  if (foldEVLIntoMask(*Job.PI))
655  ++NumFoldedVL;
656  break;
657  }
658  Job.Strategy.EVLParamStrategy = VPLegalization::Legal;
659 
660  // Replace with a non-predicated operation.
661  switch (Job.Strategy.OpStrategy) {
663  break;
665  llvm_unreachable("Invalid strategy for operators.");
667  expandPredication(*Job.PI);
668  ++NumLoweredVPOps;
669  break;
670  }
671  Job.Strategy.OpStrategy = VPLegalization::Legal;
672 
673  assert(Job.isDone() && "incomplete transformation");
674  }
675 
676  return true;
677 }
678 class ExpandVectorPredication : public FunctionPass {
679 public:
680  static char ID;
681  ExpandVectorPredication() : FunctionPass(ID) {
683  }
684 
685  bool runOnFunction(Function &F) override {
686  const auto *TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
687  CachingVPExpander VPExpander(F, *TTI);
688  return VPExpander.expandVectorPredication();
689  }
690 
691  void getAnalysisUsage(AnalysisUsage &AU) const override {
693  AU.setPreservesCFG();
694  }
695 };
696 } // namespace
697 
699 INITIALIZE_PASS_BEGIN(ExpandVectorPredication, "expandvp",
700  "Expand vector predication intrinsics", false, false)
703 INITIALIZE_PASS_END(ExpandVectorPredication, "expandvp",
704  "Expand vector predication intrinsics", false, false)
705 
707  return new ExpandVectorPredication();
708 }
709 
712  const auto &TTI = AM.getResult<TargetIRAnalysis>(F);
713  CachingVPExpander VPExpander(F, TTI);
714  if (!VPExpander.expandVectorPredication())
715  return PreservedAnalyses::all();
717  PA.preserveSet<CFGAnalyses>();
718  return PA;
719 }
transferDecorations
static void transferDecorations(Value &NewVal, VPIntrinsic &VPI)
Transfer operation properties from OldVPI to NewVal.
Definition: ExpandVectorPredication.cpp:100
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
Int32Ty
IntegerType * Int32Ty
Definition: NVVMIntrRange.cpp:67
llvm::TargetIRAnalysis
Analysis pass providing the TargetTransformInfo.
Definition: TargetTransformInfo.h:2586
llvm::initializeExpandVectorPredicationPass
void initializeExpandVectorPredicationPass(PassRegistry &)
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::Instruction::getModule
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Definition: Instruction.cpp:69
llvm::AArch64PACKey::ID
ID
Definition: AArch64BaseInfo.h:818
expandvp
expandvp
Definition: ExpandVectorPredication.cpp:703
llvm::Intrinsic::getDeclaration
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:1481
IntrinsicInst.h
llvm::ElementCount
Definition: TypeSize.h:404
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:774
InstIterator.h
llvm::Function
Definition: Function.h:60
Pass.h
llvm::IntrinsicInst::getIntrinsicID
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
Definition: IntrinsicInst.h:53
llvm::TargetTransformInfo::getVPLegalizationStrategy
VPLegalization getVPLegalizationStrategy(const VPIntrinsic &PI) const
Definition: TargetTransformInfo.cpp:1154
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
Statistic.h
llvm::Type::getFltSemantics
const fltSemantics & getFltSemantics() const
Definition: Type.cpp:67
llvm::getSplatValue
Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
Definition: VectorUtils.cpp:371
llvm::TargetTransformInfo
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Definition: TargetTransformInfo.h:173
llvm::VPIntrinsic::setVectorLengthParam
void setVectorLengthParam(Value *)
Definition: IntrinsicInst.cpp:410
llvm::IRBuilder<>
llvm::VPCmpIntrinsic::getPredicate
CmpInst::Predicate getPredicate() const
Definition: IntrinsicInst.cpp:684
ValueTracking.h
llvm::VPIntrinsic::canIgnoreVectorLengthParam
bool canIgnoreVectorLengthParam() const
Definition: IntrinsicInst.cpp:525
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:140
llvm::TargetTransformInfo::VPLegalization
Definition: TargetTransformInfo.h:1513
llvm::APInt::getSignedMaxValue
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
Definition: APInt.h:189
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::TargetTransformInfo::VPLegalization::Convert
@ Convert
Definition: TargetTransformInfo.h:1520
llvm::MaybeAlign::valueOrOne
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition: Alignment.h:142
llvm::StoreInst::setAlignment
void setAlignment(Align Align)
Definition: Instructions.h:346
llvm::VPIntrinsic::getMemoryDataParam
Value * getMemoryDataParam() const
Definition: IntrinsicInst.cpp:468
llvm::Optional< unsigned >
parseOverrideOption
static VPTransform parseOverrideOption(const std::string &TextOpt)
Definition: ExpandVectorPredication.cpp:66
llvm::FastMathFlags
Convenience struct for specifying and reasoning about fast-math flags.
Definition: FMF.h:21
llvm::ConstantFP::getNegativeZero
static Constant * getNegativeZero(Type *Ty)
Definition: Constants.h:293
llvm::LinearPolySize::isScalable
bool isScalable() const
Returns whether the size is scaled by a runtime quantity (vscale).
Definition: TypeSize.h:298
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:239
llvm::APIntOps::umin
const APInt & umin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be unsigned.
Definition: APInt.h:2157
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::VPIntrinsic::setMaskParam
void setMaskParam(Value *)
Definition: IntrinsicInst.cpp:399
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::BitmaskEnumDetail::Mask
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.
Definition: BitmaskEnum.h:80
CommandLine.h
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:24
intrinsics
Expand vector predication intrinsics
Definition: ExpandVectorPredication.cpp:704
Constants.h
llvm::VPReductionIntrinsic
This represents vector predication reduction intrinsics.
Definition: IntrinsicInst.h:539
Intrinsics.h
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
false
Definition: StackSlotColoring.cpp:141
llvm::MaybeAlign
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
llvm::Constant::getAllOnesValue
static Constant * getAllOnesValue(Type *Ty)
Definition: Constants.cpp:395
llvm::Type::getScalarSizeInBits
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition: Type.cpp:189
llvm::DominatorTreeWrapperPass
Legacy analysis pass which computes a DominatorTree.
Definition: Dominators.h:302
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::ConstantFP
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:257
llvm::ConstantInt::get
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:879
llvm::MCID::Call
@ Call
Definition: MCInstrDesc.h:155
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
llvm::maxnum
LLVM_READONLY APFloat maxnum(const APFloat &A, const APFloat &B)
Implements IEEE maxNum semantics.
Definition: APFloat.h:1322
llvm::VPIntrinsic::getVectorLengthParam
Value * getVectorLengthParam() const
Definition: IntrinsicInst.cpp:404
llvm::TargetTransformInfo::VPLegalization::EVLParamStrategy
VPTransform EVLParamStrategy
Definition: TargetTransformInfo.h:1527
Passes.h
llvm::VPIntrinsic::getFunctionalOpcode
Optional< unsigned > getFunctionalOpcode() const
Definition: IntrinsicInst.h:530
ExpandVectorPredication.h
llvm::TargetTransformInfo::VPLegalization::VPTransform
VPTransform
Definition: TargetTransformInfo.h:1514
VectorUtils.h
llvm::cl::opt
Definition: CommandLine.h:1412
llvm::APFloat
Definition: APFloat.h:716
llvm::instructions
inst_range instructions(Function *F)
Definition: InstIterator.h:133
llvm::ConstantFP::getQNaN
static Constant * getQNaN(Type *Ty, bool Negative=false, APInt *Payload=nullptr)
Definition: Constants.cpp:978
llvm::StoreInst
An instruction for storing to memory.
Definition: Instructions.h:298
llvm::VPIntrinsic::getStaticVectorLength
ElementCount getStaticVectorLength() const
Definition: IntrinsicInst.cpp:376
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::Instruction::eraseFromParent
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:81
EVLTransformOverride
static cl::opt< std::string > EVLTransformOverride("expandvp-override-evl-transform", cl::init(""), cl::Hidden, cl::desc("Options: <empty>" VPINTERNAL_VPLEGAL_CASES ". If non-empty, ignore " "TargetTransformInfo and " "always use this transformation for the %evl parameter (Used in " "testing)."))
llvm::TargetTransformInfo::VPLegalization::OpStrategy
VPTransform OpStrategy
Definition: TargetTransformInfo.h:1533
llvm::TargetTransformInfoWrapperPass
Wrapper pass for TargetTransformInfo.
Definition: TargetTransformInfo.h:2642
llvm::VPIntrinsic::getPointerAlignment
MaybeAlign getPointerAlignment() const
Definition: IntrinsicInst.cpp:442
replaceOperation
static void replaceOperation(Value &NewOp, VPIntrinsic &OldOp)
Transfer all properties from OldOp to NewOp and replace all uses.
Definition: ExpandVectorPredication.cpp:114
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
llvm::TargetTransformInfo::VPLegalization::shouldDoNothing
bool shouldDoNothing() const
Definition: TargetTransformInfo.h:1535
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::LoadInst::setAlignment
void setAlignment(Align Align)
Definition: Instructions.h:221
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:447
anyExpandVPOverridesSet
static bool anyExpandVPOverridesSet()
Definition: ExpandVectorPredication.cpp:73
IRBuilder.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::TargetTransformInfo::VPLegalization::Discard
@ Discard
Definition: TargetTransformInfo.h:1518
llvm::SystemZISD::OC
@ OC
Definition: SystemZISelLowering.h:122
llvm::Instruction::getFastMathFlags
FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
Definition: Instruction.cpp:319
llvm::createExpandVectorPredicationPass
FunctionPass * createExpandVectorPredicationPass()
This pass expands the vector predication intrinsics into unpredicated instructions with selects or ju...
Definition: ExpandVectorPredication.cpp:706
llvm::TTI
TargetTransformInfo TTI
Definition: TargetTransformInfo.h:168
llvm::Instruction::isBinaryOp
bool isBinaryOp() const
Definition: Instruction.h:169
predication
loop predication
Definition: LoopPredication.cpp:363
llvm::LinearPolySize::getKnownMinValue
ScalarTy getKnownMinValue() const
Returns the minimum value this size can represent.
Definition: TypeSize.h:296
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:651
llvm::APIntOps::smin
const APInt & smin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be signed.
Definition: APInt.h:2147
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:265
llvm::CmpInst::ICMP_ULT
@ ICMP_ULT
unsigned less than
Definition: InstrTypes.h:745
llvm::LinearPolySize::getFixedValue
ScalarTy getFixedValue() const
Definition: TypeSize.h:312
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
llvm::CFGAnalyses
Represents analyses that only rely on functions' control flow.
Definition: PassManager.h:113
llvm::Value::replaceAllUsesWith
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:532
Compiler.h
llvm::Value::getContext
LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:994
llvm::ilist_node_impl::getIterator
self_iterator getIterator()
Definition: ilist_node.h:82
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::Optional::has_value
constexpr bool has_value() const
Definition: Optional.h:285
llvm::ConstantVector::get
static Constant * get(ArrayRef< Constant * > V)
Definition: Constants.cpp:1348
llvm::VPReductionIntrinsic::getStartParamPos
unsigned getStartParamPos() const
Definition: IntrinsicInst.cpp:707
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:308
llvm::VPCmpIntrinsic
Definition: IntrinsicInst.h:575
llvm::Type::getContext
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition: Type.h:128
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:174
MaskTransformOverride
static cl::opt< std::string > MaskTransformOverride("expandvp-override-mask-transform", cl::init(""), cl::Hidden, cl::desc("Options: <empty>" VPINTERNAL_VPLEGAL_CASES ". If non-empty, Ignore " "TargetTransformInfo and " "always use this transformation for the %mask parameter (Used in " "testing)."))
llvm::ExpandVectorPredicationPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: ExpandVectorPredication.cpp:711
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(ExpandVectorPredication, "expandvp", "Expand vector predication intrinsics", false, false) INITIALIZE_PASS_END(ExpandVectorPredication
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:85
llvm::APIntOps::umax
const APInt & umax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be unsigned.
Definition: APInt.h:2162
llvm::minnum
LLVM_READONLY APFloat minnum(const APFloat &A, const APFloat &B)
Implements IEEE minNum semantics.
Definition: APFloat.h:1311
llvm::Constant::getNullValue
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:350
llvm::VPIntrinsic::getMemoryPointerParam
Value * getMemoryPointerParam() const
Definition: IntrinsicInst.cpp:449
get
Should compile to something r4 addze r3 instead we get
Definition: README.txt:24
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:158
llvm::VPIntrinsic
This is the common base class for vector predication intrinsics.
Definition: IntrinsicInst.h:475
llvm::Type::isIntOrIntVectorTy
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
Definition: Type.h:216
VPLegalization
TargetTransformInfo::VPLegalization VPLegalization
Definition: ExpandVectorPredication.cpp:35
llvm::VPReductionIntrinsic::getVectorParamPos
unsigned getVectorParamPos() const
Definition: IntrinsicInst.cpp:703
llvm::ConstantFP::get
static Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
Definition: Constants.cpp:926
maySpeculateLanes
static bool maySpeculateLanes(VPIntrinsic &VPI)
Definition: ExpandVectorPredication.cpp:120
llvm::fltSemantics
Definition: APFloat.cpp:71
Function.h
VPINTERNAL_VPLEGAL_CASES
#define VPINTERNAL_VPLEGAL_CASES
Definition: ExpandVectorPredication.cpp:39
llvm::APInt::getSignedMinValue
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
Definition: APInt.h:199
llvm::Instruction::BinaryOps
BinaryOps
Definition: Instruction.h:788
Instructions.h
llvm::PreservedAnalyses::preserveSet
void preserveSet()
Mark an analysis set as preserved.
Definition: PassManager.h:188
llvm::Instruction::getParent
const BasicBlock * getParent() const
Definition: Instruction.h:91
llvm::TargetTransformInfo::VPLegalization::Legal
@ Legal
Definition: TargetTransformInfo.h:1516
getSafeDivisor
static Constant * getSafeDivisor(Type *DivTy)
Definition: ExpandVectorPredication.cpp:94
TargetTransformInfo.h
LLVM_LIKELY
#define LLVM_LIKELY(EXPR)
Definition: Compiler.h:209
llvm::Optional::value
constexpr const T & value() const &
Definition: Optional.h:281
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:45
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:42
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
llvm::omp::RTLDependInfoFields::Flags
@ Flags
llvm::VPIntrinsic::getMaskParam
Value * getMaskParam() const
Definition: IntrinsicInst.cpp:393
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
llvm::User::getOperand
Value * getOperand(unsigned i) const
Definition: User.h:169
llvm::cl::desc
Definition: CommandLine.h:413
isAllTrueMask
static bool isAllTrueMask(Value *MaskVal)
Definition: ExpandVectorPredication.cpp:85
Reduction
loop Loop Strength Reduction
Definition: LoopStrengthReduce.cpp:6965
llvm::Optional::value_or
constexpr T value_or(U &&alt) const &
Definition: Optional.h:291
InitializePasses.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
Debug.h
llvm::VectorType::get
static VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Definition: Type.cpp:668
llvm::APIntOps::smax
const APInt & smax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be signed.
Definition: APInt.h:2152
llvm::SmallVectorImpl::emplace_back
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:941
llvm::isSafeToSpeculativelyExecuteWithOpcode
bool isSafeToSpeculativelyExecuteWithOpcode(unsigned Opcode, const Instruction *Inst, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
This returns the same result as isSafeToSpeculativelyExecute if Opcode is the actual opcode of Inst.
Definition: ValueTracking.cpp:4740