LLVM  14.0.0git
AMDGPUInstCombineIntrinsic.cpp
Go to the documentation of this file.
1 //===- AMDGPInstCombineIntrinsic.cpp - AMDGPU specific InstCombine pass ---===//
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 file implements a TargetTransformInfo analysis pass specific to the
11 // AMDGPU target machine. It uses the target's detailed information to provide
12 // more precise answers to certain TTI queries, while letting the target
13 // independent and default TTI implementations handle the rest.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #include "AMDGPUInstrInfo.h"
19 #include "GCNSubtarget.h"
20 #include "R600Subtarget.h"
21 #include "llvm/IR/IntrinsicsAMDGPU.h"
23 
24 using namespace llvm;
25 
26 #define DEBUG_TYPE "AMDGPUtti"
27 
28 namespace {
29 
30 struct AMDGPUImageDMaskIntrinsic {
31  unsigned Intr;
32 };
33 
34 #define GET_AMDGPUImageDMaskIntrinsicTable_IMPL
35 #include "InstCombineTables.inc"
36 
37 } // end anonymous namespace
38 
39 // Constant fold llvm.amdgcn.fmed3 intrinsics for standard inputs.
40 //
41 // A single NaN input is folded to minnum, so we rely on that folding for
42 // handling NaNs.
43 static APFloat fmed3AMDGCN(const APFloat &Src0, const APFloat &Src1,
44  const APFloat &Src2) {
45  APFloat Max3 = maxnum(maxnum(Src0, Src1), Src2);
46 
47  APFloat::cmpResult Cmp0 = Max3.compare(Src0);
48  assert(Cmp0 != APFloat::cmpUnordered && "nans handled separately");
49  if (Cmp0 == APFloat::cmpEqual)
50  return maxnum(Src1, Src2);
51 
52  APFloat::cmpResult Cmp1 = Max3.compare(Src1);
53  assert(Cmp1 != APFloat::cmpUnordered && "nans handled separately");
54  if (Cmp1 == APFloat::cmpEqual)
55  return maxnum(Src0, Src2);
56 
57  return maxnum(Src0, Src1);
58 }
59 
60 // Check if a value can be converted to a 16-bit value without losing
61 // precision.
62 static bool canSafelyConvertTo16Bit(Value &V) {
63  Type *VTy = V.getType();
64  if (VTy->isHalfTy() || VTy->isIntegerTy(16)) {
65  // The value is already 16-bit, so we don't want to convert to 16-bit again!
66  return false;
67  }
68  if (ConstantFP *ConstFloat = dyn_cast<ConstantFP>(&V)) {
69  // We need to check that if we cast the index down to a half, we do not lose
70  // precision.
71  APFloat FloatValue(ConstFloat->getValueAPF());
72  bool LosesInfo = true;
73  FloatValue.convert(APFloat::IEEEhalf(), APFloat::rmTowardZero, &LosesInfo);
74  return !LosesInfo;
75  }
76  Value *CastSrc;
77  if (match(&V, m_FPExt(PatternMatch::m_Value(CastSrc))) ||
78  match(&V, m_SExt(PatternMatch::m_Value(CastSrc))) ||
79  match(&V, m_ZExt(PatternMatch::m_Value(CastSrc)))) {
80  Type *CastSrcTy = CastSrc->getType();
81  if (CastSrcTy->isHalfTy() || CastSrcTy->isIntegerTy(16))
82  return true;
83  }
84 
85  return false;
86 }
87 
88 // Convert a value to 16-bit.
90  Type *VTy = V.getType();
91  if (isa<FPExtInst>(&V) || isa<SExtInst>(&V) || isa<ZExtInst>(&V))
92  return cast<Instruction>(&V)->getOperand(0);
93  if (VTy->isIntegerTy())
94  return Builder.CreateIntCast(&V, Type::getInt16Ty(V.getContext()), false);
95  if (VTy->isFloatingPointTy())
96  return Builder.CreateFPCast(&V, Type::getHalfTy(V.getContext()));
97 
98  llvm_unreachable("Should never be called!");
99 }
100 
103  const AMDGPU::ImageDimIntrinsicInfo *ImageDimIntr,
104  IntrinsicInst &II, InstCombiner &IC) {
105  if (!ST->hasA16() && !ST->hasG16())
106  return None;
107 
108  bool FloatCoord = false;
109  // true means derivatives can be converted to 16 bit, coordinates not
110  bool OnlyDerivatives = false;
111 
112  for (unsigned OperandIndex = ImageDimIntr->GradientStart;
113  OperandIndex < ImageDimIntr->VAddrEnd; OperandIndex++) {
114  Value *Coord = II.getOperand(OperandIndex);
115  // If the values are not derived from 16-bit values, we cannot optimize.
116  if (!canSafelyConvertTo16Bit(*Coord)) {
117  if (OperandIndex < ImageDimIntr->CoordStart ||
118  ImageDimIntr->GradientStart == ImageDimIntr->CoordStart) {
119  return None;
120  }
121  // All gradients can be converted, so convert only them
122  OnlyDerivatives = true;
123  break;
124  }
125 
126  assert(OperandIndex == ImageDimIntr->GradientStart ||
127  FloatCoord == Coord->getType()->isFloatingPointTy());
128  FloatCoord = Coord->getType()->isFloatingPointTy();
129  }
130 
131  if (OnlyDerivatives) {
132  if (!ST->hasG16())
133  return None;
134  } else {
135  if (!ST->hasA16())
136  OnlyDerivatives = true; // Only supports G16
137  }
138 
139  Type *CoordType = FloatCoord ? Type::getHalfTy(II.getContext())
141 
142  SmallVector<Type *, 4> ArgTys;
144  return None;
145 
146  ArgTys[ImageDimIntr->GradientTyArg] = CoordType;
147  if (!OnlyDerivatives)
148  ArgTys[ImageDimIntr->CoordTyArg] = CoordType;
149  Function *I =
151 
153 
154  unsigned EndIndex =
155  OnlyDerivatives ? ImageDimIntr->CoordStart : ImageDimIntr->VAddrEnd;
156  for (unsigned OperandIndex = ImageDimIntr->GradientStart;
157  OperandIndex < EndIndex; OperandIndex++) {
158  Args[OperandIndex] =
159  convertTo16Bit(*II.getOperand(OperandIndex), IC.Builder);
160  }
161 
162  CallInst *NewCall = IC.Builder.CreateCall(I, Args);
163  NewCall->takeName(&II);
164  NewCall->copyMetadata(II);
165  if (isa<FPMathOperator>(NewCall))
166  NewCall->copyFastMathFlags(&II);
167  return IC.replaceInstUsesWith(II, NewCall);
168 }
169 
171  InstCombiner &IC) const {
172  // The legacy behaviour is that multiplying +/-0.0 by anything, even NaN or
173  // infinity, gives +0.0. If we can prove we don't have one of the special
174  // cases then we can use a normal multiply instead.
175  // TODO: Create and use isKnownFiniteNonZero instead of just matching
176  // constants here.
177  if (match(Op0, PatternMatch::m_FiniteNonZero()) ||
179  // One operand is not zero or infinity or NaN.
180  return true;
181  }
182  auto *TLI = &IC.getTargetLibraryInfo();
183  if (isKnownNeverInfinity(Op0, TLI) && isKnownNeverNaN(Op0, TLI) &&
184  isKnownNeverInfinity(Op1, TLI) && isKnownNeverNaN(Op1, TLI)) {
185  // Neither operand is infinity or NaN.
186  return true;
187  }
188  return false;
189 }
190 
193  Intrinsic::ID IID = II.getIntrinsicID();
194  switch (IID) {
195  case Intrinsic::amdgcn_rcp: {
196  Value *Src = II.getArgOperand(0);
197 
198  // TODO: Move to ConstantFolding/InstSimplify?
199  if (isa<UndefValue>(Src)) {
200  Type *Ty = II.getType();
201  auto *QNaN = ConstantFP::get(Ty, APFloat::getQNaN(Ty->getFltSemantics()));
202  return IC.replaceInstUsesWith(II, QNaN);
203  }
204 
205  if (II.isStrictFP())
206  break;
207 
208  if (const ConstantFP *C = dyn_cast<ConstantFP>(Src)) {
209  const APFloat &ArgVal = C->getValueAPF();
210  APFloat Val(ArgVal.getSemantics(), 1);
212 
213  // This is more precise than the instruction may give.
214  //
215  // TODO: The instruction always flushes denormal results (except for f16),
216  // should this also?
217  return IC.replaceInstUsesWith(II, ConstantFP::get(II.getContext(), Val));
218  }
219 
220  break;
221  }
222  case Intrinsic::amdgcn_rsq: {
223  Value *Src = II.getArgOperand(0);
224 
225  // TODO: Move to ConstantFolding/InstSimplify?
226  if (isa<UndefValue>(Src)) {
227  Type *Ty = II.getType();
228  auto *QNaN = ConstantFP::get(Ty, APFloat::getQNaN(Ty->getFltSemantics()));
229  return IC.replaceInstUsesWith(II, QNaN);
230  }
231 
232  break;
233  }
234  case Intrinsic::amdgcn_frexp_mant:
235  case Intrinsic::amdgcn_frexp_exp: {
236  Value *Src = II.getArgOperand(0);
237  if (const ConstantFP *C = dyn_cast<ConstantFP>(Src)) {
238  int Exp;
239  APFloat Significand =
240  frexp(C->getValueAPF(), Exp, APFloat::rmNearestTiesToEven);
241 
242  if (IID == Intrinsic::amdgcn_frexp_mant) {
243  return IC.replaceInstUsesWith(
244  II, ConstantFP::get(II.getContext(), Significand));
245  }
246 
247  // Match instruction special case behavior.
248  if (Exp == APFloat::IEK_NaN || Exp == APFloat::IEK_Inf)
249  Exp = 0;
250 
251  return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), Exp));
252  }
253 
254  if (isa<UndefValue>(Src)) {
255  return IC.replaceInstUsesWith(II, UndefValue::get(II.getType()));
256  }
257 
258  break;
259  }
260  case Intrinsic::amdgcn_class: {
261  enum {
262  S_NAN = 1 << 0, // Signaling NaN
263  Q_NAN = 1 << 1, // Quiet NaN
264  N_INFINITY = 1 << 2, // Negative infinity
265  N_NORMAL = 1 << 3, // Negative normal
266  N_SUBNORMAL = 1 << 4, // Negative subnormal
267  N_ZERO = 1 << 5, // Negative zero
268  P_ZERO = 1 << 6, // Positive zero
269  P_SUBNORMAL = 1 << 7, // Positive subnormal
270  P_NORMAL = 1 << 8, // Positive normal
271  P_INFINITY = 1 << 9 // Positive infinity
272  };
273 
274  const uint32_t FullMask = S_NAN | Q_NAN | N_INFINITY | N_NORMAL |
277 
278  Value *Src0 = II.getArgOperand(0);
279  Value *Src1 = II.getArgOperand(1);
280  const ConstantInt *CMask = dyn_cast<ConstantInt>(Src1);
281  if (!CMask) {
282  if (isa<UndefValue>(Src0)) {
283  return IC.replaceInstUsesWith(II, UndefValue::get(II.getType()));
284  }
285 
286  if (isa<UndefValue>(Src1)) {
287  return IC.replaceInstUsesWith(II,
288  ConstantInt::get(II.getType(), false));
289  }
290  break;
291  }
292 
293  uint32_t Mask = CMask->getZExtValue();
294 
295  // If all tests are made, it doesn't matter what the value is.
296  if ((Mask & FullMask) == FullMask) {
297  return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), true));
298  }
299 
300  if ((Mask & FullMask) == 0) {
301  return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), false));
302  }
303 
304  if (Mask == (S_NAN | Q_NAN)) {
305  // Equivalent of isnan. Replace with standard fcmp.
306  Value *FCmp = IC.Builder.CreateFCmpUNO(Src0, Src0);
307  FCmp->takeName(&II);
308  return IC.replaceInstUsesWith(II, FCmp);
309  }
310 
311  if (Mask == (N_ZERO | P_ZERO)) {
312  // Equivalent of == 0.
313  Value *FCmp =
314  IC.Builder.CreateFCmpOEQ(Src0, ConstantFP::get(Src0->getType(), 0.0));
315 
316  FCmp->takeName(&II);
317  return IC.replaceInstUsesWith(II, FCmp);
318  }
319 
320  // fp_class (nnan x), qnan|snan|other -> fp_class (nnan x), other
321  if (((Mask & S_NAN) || (Mask & Q_NAN)) &&
322  isKnownNeverNaN(Src0, &IC.getTargetLibraryInfo())) {
323  return IC.replaceOperand(
324  II, 1, ConstantInt::get(Src1->getType(), Mask & ~(S_NAN | Q_NAN)));
325  }
326 
327  const ConstantFP *CVal = dyn_cast<ConstantFP>(Src0);
328  if (!CVal) {
329  if (isa<UndefValue>(Src0)) {
330  return IC.replaceInstUsesWith(II, UndefValue::get(II.getType()));
331  }
332 
333  // Clamp mask to used bits
334  if ((Mask & FullMask) != Mask) {
335  CallInst *NewCall = IC.Builder.CreateCall(
336  II.getCalledFunction(),
337  {Src0, ConstantInt::get(Src1->getType(), Mask & FullMask)});
338 
339  NewCall->takeName(&II);
340  return IC.replaceInstUsesWith(II, NewCall);
341  }
342 
343  break;
344  }
345 
346  const APFloat &Val = CVal->getValueAPF();
347 
348  bool Result =
349  ((Mask & S_NAN) && Val.isNaN() && Val.isSignaling()) ||
350  ((Mask & Q_NAN) && Val.isNaN() && !Val.isSignaling()) ||
351  ((Mask & N_INFINITY) && Val.isInfinity() && Val.isNegative()) ||
352  ((Mask & N_NORMAL) && Val.isNormal() && Val.isNegative()) ||
353  ((Mask & N_SUBNORMAL) && Val.isDenormal() && Val.isNegative()) ||
354  ((Mask & N_ZERO) && Val.isZero() && Val.isNegative()) ||
355  ((Mask & P_ZERO) && Val.isZero() && !Val.isNegative()) ||
356  ((Mask & P_SUBNORMAL) && Val.isDenormal() && !Val.isNegative()) ||
357  ((Mask & P_NORMAL) && Val.isNormal() && !Val.isNegative()) ||
358  ((Mask & P_INFINITY) && Val.isInfinity() && !Val.isNegative());
359 
360  return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), Result));
361  }
362  case Intrinsic::amdgcn_cvt_pkrtz: {
363  Value *Src0 = II.getArgOperand(0);
364  Value *Src1 = II.getArgOperand(1);
365  if (const ConstantFP *C0 = dyn_cast<ConstantFP>(Src0)) {
366  if (const ConstantFP *C1 = dyn_cast<ConstantFP>(Src1)) {
367  const fltSemantics &HalfSem =
369  bool LosesInfo;
370  APFloat Val0 = C0->getValueAPF();
371  APFloat Val1 = C1->getValueAPF();
372  Val0.convert(HalfSem, APFloat::rmTowardZero, &LosesInfo);
373  Val1.convert(HalfSem, APFloat::rmTowardZero, &LosesInfo);
374 
375  Constant *Folded =
377  ConstantFP::get(II.getContext(), Val1)});
378  return IC.replaceInstUsesWith(II, Folded);
379  }
380  }
381 
382  if (isa<UndefValue>(Src0) && isa<UndefValue>(Src1)) {
383  return IC.replaceInstUsesWith(II, UndefValue::get(II.getType()));
384  }
385 
386  break;
387  }
388  case Intrinsic::amdgcn_cvt_pknorm_i16:
389  case Intrinsic::amdgcn_cvt_pknorm_u16:
390  case Intrinsic::amdgcn_cvt_pk_i16:
391  case Intrinsic::amdgcn_cvt_pk_u16: {
392  Value *Src0 = II.getArgOperand(0);
393  Value *Src1 = II.getArgOperand(1);
394 
395  if (isa<UndefValue>(Src0) && isa<UndefValue>(Src1)) {
396  return IC.replaceInstUsesWith(II, UndefValue::get(II.getType()));
397  }
398 
399  break;
400  }
401  case Intrinsic::amdgcn_ubfe:
402  case Intrinsic::amdgcn_sbfe: {
403  // Decompose simple cases into standard shifts.
404  Value *Src = II.getArgOperand(0);
405  if (isa<UndefValue>(Src)) {
406  return IC.replaceInstUsesWith(II, Src);
407  }
408 
409  unsigned Width;
410  Type *Ty = II.getType();
411  unsigned IntSize = Ty->getIntegerBitWidth();
412 
413  ConstantInt *CWidth = dyn_cast<ConstantInt>(II.getArgOperand(2));
414  if (CWidth) {
415  Width = CWidth->getZExtValue();
416  if ((Width & (IntSize - 1)) == 0) {
418  }
419 
420  // Hardware ignores high bits, so remove those.
421  if (Width >= IntSize) {
422  return IC.replaceOperand(
423  II, 2, ConstantInt::get(CWidth->getType(), Width & (IntSize - 1)));
424  }
425  }
426 
427  unsigned Offset;
428  ConstantInt *COffset = dyn_cast<ConstantInt>(II.getArgOperand(1));
429  if (COffset) {
430  Offset = COffset->getZExtValue();
431  if (Offset >= IntSize) {
432  return IC.replaceOperand(
433  II, 1,
434  ConstantInt::get(COffset->getType(), Offset & (IntSize - 1)));
435  }
436  }
437 
438  bool Signed = IID == Intrinsic::amdgcn_sbfe;
439 
440  if (!CWidth || !COffset)
441  break;
442 
443  // The case of Width == 0 is handled above, which makes this tranformation
444  // safe. If Width == 0, then the ashr and lshr instructions become poison
445  // value since the shift amount would be equal to the bit size.
446  assert(Width != 0);
447 
448  // TODO: This allows folding to undef when the hardware has specific
449  // behavior?
450  if (Offset + Width < IntSize) {
451  Value *Shl = IC.Builder.CreateShl(Src, IntSize - Offset - Width);
452  Value *RightShift = Signed ? IC.Builder.CreateAShr(Shl, IntSize - Width)
453  : IC.Builder.CreateLShr(Shl, IntSize - Width);
454  RightShift->takeName(&II);
455  return IC.replaceInstUsesWith(II, RightShift);
456  }
457 
458  Value *RightShift = Signed ? IC.Builder.CreateAShr(Src, Offset)
459  : IC.Builder.CreateLShr(Src, Offset);
460 
461  RightShift->takeName(&II);
462  return IC.replaceInstUsesWith(II, RightShift);
463  }
464  case Intrinsic::amdgcn_exp:
465  case Intrinsic::amdgcn_exp_compr: {
466  ConstantInt *En = cast<ConstantInt>(II.getArgOperand(1));
467  unsigned EnBits = En->getZExtValue();
468  if (EnBits == 0xf)
469  break; // All inputs enabled.
470 
471  bool IsCompr = IID == Intrinsic::amdgcn_exp_compr;
472  bool Changed = false;
473  for (int I = 0; I < (IsCompr ? 2 : 4); ++I) {
474  if ((!IsCompr && (EnBits & (1 << I)) == 0) ||
475  (IsCompr && ((EnBits & (0x3 << (2 * I))) == 0))) {
476  Value *Src = II.getArgOperand(I + 2);
477  if (!isa<UndefValue>(Src)) {
478  IC.replaceOperand(II, I + 2, UndefValue::get(Src->getType()));
479  Changed = true;
480  }
481  }
482  }
483 
484  if (Changed) {
485  return &II;
486  }
487 
488  break;
489  }
490  case Intrinsic::amdgcn_fmed3: {
491  // Note this does not preserve proper sNaN behavior if IEEE-mode is enabled
492  // for the shader.
493 
494  Value *Src0 = II.getArgOperand(0);
495  Value *Src1 = II.getArgOperand(1);
496  Value *Src2 = II.getArgOperand(2);
497 
498  // Checking for NaN before canonicalization provides better fidelity when
499  // mapping other operations onto fmed3 since the order of operands is
500  // unchanged.
501  CallInst *NewCall = nullptr;
502  if (match(Src0, PatternMatch::m_NaN()) || isa<UndefValue>(Src0)) {
503  NewCall = IC.Builder.CreateMinNum(Src1, Src2);
504  } else if (match(Src1, PatternMatch::m_NaN()) || isa<UndefValue>(Src1)) {
505  NewCall = IC.Builder.CreateMinNum(Src0, Src2);
506  } else if (match(Src2, PatternMatch::m_NaN()) || isa<UndefValue>(Src2)) {
507  NewCall = IC.Builder.CreateMaxNum(Src0, Src1);
508  }
509 
510  if (NewCall) {
511  NewCall->copyFastMathFlags(&II);
512  NewCall->takeName(&II);
513  return IC.replaceInstUsesWith(II, NewCall);
514  }
515 
516  bool Swap = false;
517  // Canonicalize constants to RHS operands.
518  //
519  // fmed3(c0, x, c1) -> fmed3(x, c0, c1)
520  if (isa<Constant>(Src0) && !isa<Constant>(Src1)) {
521  std::swap(Src0, Src1);
522  Swap = true;
523  }
524 
525  if (isa<Constant>(Src1) && !isa<Constant>(Src2)) {
526  std::swap(Src1, Src2);
527  Swap = true;
528  }
529 
530  if (isa<Constant>(Src0) && !isa<Constant>(Src1)) {
531  std::swap(Src0, Src1);
532  Swap = true;
533  }
534 
535  if (Swap) {
536  II.setArgOperand(0, Src0);
537  II.setArgOperand(1, Src1);
538  II.setArgOperand(2, Src2);
539  return &II;
540  }
541 
542  if (const ConstantFP *C0 = dyn_cast<ConstantFP>(Src0)) {
543  if (const ConstantFP *C1 = dyn_cast<ConstantFP>(Src1)) {
544  if (const ConstantFP *C2 = dyn_cast<ConstantFP>(Src2)) {
545  APFloat Result = fmed3AMDGCN(C0->getValueAPF(), C1->getValueAPF(),
546  C2->getValueAPF());
547  return IC.replaceInstUsesWith(
548  II, ConstantFP::get(IC.Builder.getContext(), Result));
549  }
550  }
551  }
552 
553  break;
554  }
555  case Intrinsic::amdgcn_icmp:
556  case Intrinsic::amdgcn_fcmp: {
557  const ConstantInt *CC = cast<ConstantInt>(II.getArgOperand(2));
558  // Guard against invalid arguments.
559  int64_t CCVal = CC->getZExtValue();
560  bool IsInteger = IID == Intrinsic::amdgcn_icmp;
561  if ((IsInteger && (CCVal < CmpInst::FIRST_ICMP_PREDICATE ||
562  CCVal > CmpInst::LAST_ICMP_PREDICATE)) ||
563  (!IsInteger && (CCVal < CmpInst::FIRST_FCMP_PREDICATE ||
565  break;
566 
567  Value *Src0 = II.getArgOperand(0);
568  Value *Src1 = II.getArgOperand(1);
569 
570  if (auto *CSrc0 = dyn_cast<Constant>(Src0)) {
571  if (auto *CSrc1 = dyn_cast<Constant>(Src1)) {
572  Constant *CCmp = ConstantExpr::getCompare(CCVal, CSrc0, CSrc1);
573  if (CCmp->isNullValue()) {
574  return IC.replaceInstUsesWith(
575  II, ConstantExpr::getSExt(CCmp, II.getType()));
576  }
577 
578  // The result of V_ICMP/V_FCMP assembly instructions (which this
579  // intrinsic exposes) is one bit per thread, masked with the EXEC
580  // register (which contains the bitmask of live threads). So a
581  // comparison that always returns true is the same as a read of the
582  // EXEC register.
584  II.getModule(), Intrinsic::read_register, II.getType());
585  Metadata *MDArgs[] = {MDString::get(II.getContext(), "exec")};
586  MDNode *MD = MDNode::get(II.getContext(), MDArgs);
587  Value *Args[] = {MetadataAsValue::get(II.getContext(), MD)};
588  CallInst *NewCall = IC.Builder.CreateCall(NewF, Args);
591  NewCall->takeName(&II);
592  return IC.replaceInstUsesWith(II, NewCall);
593  }
594 
595  // Canonicalize constants to RHS.
596  CmpInst::Predicate SwapPred =
598  II.setArgOperand(0, Src1);
599  II.setArgOperand(1, Src0);
600  II.setArgOperand(
601  2, ConstantInt::get(CC->getType(), static_cast<int>(SwapPred)));
602  return &II;
603  }
604 
605  if (CCVal != CmpInst::ICMP_EQ && CCVal != CmpInst::ICMP_NE)
606  break;
607 
608  // Canonicalize compare eq with true value to compare != 0
609  // llvm.amdgcn.icmp(zext (i1 x), 1, eq)
610  // -> llvm.amdgcn.icmp(zext (i1 x), 0, ne)
611  // llvm.amdgcn.icmp(sext (i1 x), -1, eq)
612  // -> llvm.amdgcn.icmp(sext (i1 x), 0, ne)
613  Value *ExtSrc;
614  if (CCVal == CmpInst::ICMP_EQ &&
615  ((match(Src1, PatternMatch::m_One()) &&
616  match(Src0, m_ZExt(PatternMatch::m_Value(ExtSrc)))) ||
617  (match(Src1, PatternMatch::m_AllOnes()) &&
618  match(Src0, m_SExt(PatternMatch::m_Value(ExtSrc))))) &&
619  ExtSrc->getType()->isIntegerTy(1)) {
621  IC.replaceOperand(II, 2,
623  return &II;
624  }
625 
626  CmpInst::Predicate SrcPred;
627  Value *SrcLHS;
628  Value *SrcRHS;
629 
630  // Fold compare eq/ne with 0 from a compare result as the predicate to the
631  // intrinsic. The typical use is a wave vote function in the library, which
632  // will be fed from a user code condition compared with 0. Fold in the
633  // redundant compare.
634 
635  // llvm.amdgcn.icmp([sz]ext ([if]cmp pred a, b), 0, ne)
636  // -> llvm.amdgcn.[if]cmp(a, b, pred)
637  //
638  // llvm.amdgcn.icmp([sz]ext ([if]cmp pred a, b), 0, eq)
639  // -> llvm.amdgcn.[if]cmp(a, b, inv pred)
640  if (match(Src1, PatternMatch::m_Zero()) &&
642  m_Cmp(SrcPred, PatternMatch::m_Value(SrcLHS),
643  PatternMatch::m_Value(SrcRHS))))) {
644  if (CCVal == CmpInst::ICMP_EQ)
645  SrcPred = CmpInst::getInversePredicate(SrcPred);
646 
647  Intrinsic::ID NewIID = CmpInst::isFPPredicate(SrcPred)
648  ? Intrinsic::amdgcn_fcmp
649  : Intrinsic::amdgcn_icmp;
650 
651  Type *Ty = SrcLHS->getType();
652  if (auto *CmpType = dyn_cast<IntegerType>(Ty)) {
653  // Promote to next legal integer type.
654  unsigned Width = CmpType->getBitWidth();
655  unsigned NewWidth = Width;
656 
657  // Don't do anything for i1 comparisons.
658  if (Width == 1)
659  break;
660 
661  if (Width <= 16)
662  NewWidth = 16;
663  else if (Width <= 32)
664  NewWidth = 32;
665  else if (Width <= 64)
666  NewWidth = 64;
667  else if (Width > 64)
668  break; // Can't handle this.
669 
670  if (Width != NewWidth) {
671  IntegerType *CmpTy = IC.Builder.getIntNTy(NewWidth);
672  if (CmpInst::isSigned(SrcPred)) {
673  SrcLHS = IC.Builder.CreateSExt(SrcLHS, CmpTy);
674  SrcRHS = IC.Builder.CreateSExt(SrcRHS, CmpTy);
675  } else {
676  SrcLHS = IC.Builder.CreateZExt(SrcLHS, CmpTy);
677  SrcRHS = IC.Builder.CreateZExt(SrcRHS, CmpTy);
678  }
679  }
680  } else if (!Ty->isFloatTy() && !Ty->isDoubleTy() && !Ty->isHalfTy())
681  break;
682 
684  II.getModule(), NewIID, {II.getType(), SrcLHS->getType()});
685  Value *Args[] = {SrcLHS, SrcRHS,
686  ConstantInt::get(CC->getType(), SrcPred)};
687  CallInst *NewCall = IC.Builder.CreateCall(NewF, Args);
688  NewCall->takeName(&II);
689  return IC.replaceInstUsesWith(II, NewCall);
690  }
691 
692  break;
693  }
694  case Intrinsic::amdgcn_ballot: {
695  if (auto *Src = dyn_cast<ConstantInt>(II.getArgOperand(0))) {
696  if (Src->isZero()) {
697  // amdgcn.ballot(i1 0) is zero.
699  }
700 
701  if (Src->isOne()) {
702  // amdgcn.ballot(i1 1) is exec.
703  const char *RegName = "exec";
704  if (II.getType()->isIntegerTy(32))
705  RegName = "exec_lo";
706  else if (!II.getType()->isIntegerTy(64))
707  break;
708 
710  II.getModule(), Intrinsic::read_register, II.getType());
711  Metadata *MDArgs[] = {MDString::get(II.getContext(), RegName)};
712  MDNode *MD = MDNode::get(II.getContext(), MDArgs);
713  Value *Args[] = {MetadataAsValue::get(II.getContext(), MD)};
714  CallInst *NewCall = IC.Builder.CreateCall(NewF, Args);
717  NewCall->takeName(&II);
718  return IC.replaceInstUsesWith(II, NewCall);
719  }
720  }
721  break;
722  }
723  case Intrinsic::amdgcn_wqm_vote: {
724  // wqm_vote is identity when the argument is constant.
725  if (!isa<Constant>(II.getArgOperand(0)))
726  break;
727 
728  return IC.replaceInstUsesWith(II, II.getArgOperand(0));
729  }
730  case Intrinsic::amdgcn_kill: {
731  const ConstantInt *C = dyn_cast<ConstantInt>(II.getArgOperand(0));
732  if (!C || !C->getZExtValue())
733  break;
734 
735  // amdgcn.kill(i1 1) is a no-op
736  return IC.eraseInstFromFunction(II);
737  }
738  case Intrinsic::amdgcn_update_dpp: {
739  Value *Old = II.getArgOperand(0);
740 
741  auto *BC = cast<ConstantInt>(II.getArgOperand(5));
742  auto *RM = cast<ConstantInt>(II.getArgOperand(3));
743  auto *BM = cast<ConstantInt>(II.getArgOperand(4));
744  if (BC->isZeroValue() || RM->getZExtValue() != 0xF ||
745  BM->getZExtValue() != 0xF || isa<UndefValue>(Old))
746  break;
747 
748  // If bound_ctrl = 1, row mask = bank mask = 0xf we can omit old value.
749  return IC.replaceOperand(II, 0, UndefValue::get(Old->getType()));
750  }
751  case Intrinsic::amdgcn_permlane16:
752  case Intrinsic::amdgcn_permlanex16: {
753  // Discard vdst_in if it's not going to be read.
754  Value *VDstIn = II.getArgOperand(0);
755  if (isa<UndefValue>(VDstIn))
756  break;
757 
758  ConstantInt *FetchInvalid = cast<ConstantInt>(II.getArgOperand(4));
759  ConstantInt *BoundCtrl = cast<ConstantInt>(II.getArgOperand(5));
760  if (!FetchInvalid->getZExtValue() && !BoundCtrl->getZExtValue())
761  break;
762 
763  return IC.replaceOperand(II, 0, UndefValue::get(VDstIn->getType()));
764  }
765  case Intrinsic::amdgcn_readfirstlane:
766  case Intrinsic::amdgcn_readlane: {
767  // A constant value is trivially uniform.
768  if (Constant *C = dyn_cast<Constant>(II.getArgOperand(0))) {
769  return IC.replaceInstUsesWith(II, C);
770  }
771 
772  // The rest of these may not be safe if the exec may not be the same between
773  // the def and use.
774  Value *Src = II.getArgOperand(0);
775  Instruction *SrcInst = dyn_cast<Instruction>(Src);
776  if (SrcInst && SrcInst->getParent() != II.getParent())
777  break;
778 
779  // readfirstlane (readfirstlane x) -> readfirstlane x
780  // readlane (readfirstlane x), y -> readfirstlane x
781  if (match(Src,
782  PatternMatch::m_Intrinsic<Intrinsic::amdgcn_readfirstlane>())) {
783  return IC.replaceInstUsesWith(II, Src);
784  }
785 
786  if (IID == Intrinsic::amdgcn_readfirstlane) {
787  // readfirstlane (readlane x, y) -> readlane x, y
788  if (match(Src, PatternMatch::m_Intrinsic<Intrinsic::amdgcn_readlane>())) {
789  return IC.replaceInstUsesWith(II, Src);
790  }
791  } else {
792  // readlane (readlane x, y), y -> readlane x, y
793  if (match(Src, PatternMatch::m_Intrinsic<Intrinsic::amdgcn_readlane>(
796  return IC.replaceInstUsesWith(II, Src);
797  }
798  }
799 
800  break;
801  }
802  case Intrinsic::amdgcn_ldexp: {
803  // FIXME: This doesn't introduce new instructions and belongs in
804  // InstructionSimplify.
805  Type *Ty = II.getType();
806  Value *Op0 = II.getArgOperand(0);
807  Value *Op1 = II.getArgOperand(1);
808 
809  // Folding undef to qnan is safe regardless of the FP mode.
810  if (isa<UndefValue>(Op0)) {
811  auto *QNaN = ConstantFP::get(Ty, APFloat::getQNaN(Ty->getFltSemantics()));
812  return IC.replaceInstUsesWith(II, QNaN);
813  }
814 
815  const APFloat *C = nullptr;
817 
818  // FIXME: Should flush denorms depending on FP mode, but that's ignored
819  // everywhere else.
820  //
821  // These cases should be safe, even with strictfp.
822  // ldexp(0.0, x) -> 0.0
823  // ldexp(-0.0, x) -> -0.0
824  // ldexp(inf, x) -> inf
825  // ldexp(-inf, x) -> -inf
826  if (C && (C->isZero() || C->isInfinity())) {
827  return IC.replaceInstUsesWith(II, Op0);
828  }
829 
830  // With strictfp, be more careful about possibly needing to flush denormals
831  // or not, and snan behavior depends on ieee_mode.
832  if (II.isStrictFP())
833  break;
834 
835  if (C && C->isNaN()) {
836  // FIXME: We just need to make the nan quiet here, but that's unavailable
837  // on APFloat, only IEEEfloat
838  auto *Quieted =
840  return IC.replaceInstUsesWith(II, Quieted);
841  }
842 
843  // ldexp(x, 0) -> x
844  // ldexp(x, undef) -> x
845  if (isa<UndefValue>(Op1) || match(Op1, PatternMatch::m_ZeroInt())) {
846  return IC.replaceInstUsesWith(II, Op0);
847  }
848 
849  break;
850  }
851  case Intrinsic::amdgcn_fmul_legacy: {
852  Value *Op0 = II.getArgOperand(0);
853  Value *Op1 = II.getArgOperand(1);
854 
855  // The legacy behaviour is that multiplying +/-0.0 by anything, even NaN or
856  // infinity, gives +0.0.
857  // TODO: Move to InstSimplify?
858  if (match(Op0, PatternMatch::m_AnyZeroFP()) ||
861 
862  // If we can prove we don't have one of the special cases then we can use a
863  // normal fmul instruction instead.
864  if (canSimplifyLegacyMulToMul(Op0, Op1, IC)) {
865  auto *FMul = IC.Builder.CreateFMulFMF(Op0, Op1, &II);
866  FMul->takeName(&II);
867  return IC.replaceInstUsesWith(II, FMul);
868  }
869  break;
870  }
871  case Intrinsic::amdgcn_fma_legacy: {
872  Value *Op0 = II.getArgOperand(0);
873  Value *Op1 = II.getArgOperand(1);
874  Value *Op2 = II.getArgOperand(2);
875 
876  // The legacy behaviour is that multiplying +/-0.0 by anything, even NaN or
877  // infinity, gives +0.0.
878  // TODO: Move to InstSimplify?
879  if (match(Op0, PatternMatch::m_AnyZeroFP()) ||
881  // It's tempting to just return Op2 here, but that would give the wrong
882  // result if Op2 was -0.0.
883  auto *Zero = ConstantFP::getNullValue(II.getType());
884  auto *FAdd = IC.Builder.CreateFAddFMF(Zero, Op2, &II);
885  FAdd->takeName(&II);
886  return IC.replaceInstUsesWith(II, FAdd);
887  }
888 
889  // If we can prove we don't have one of the special cases then we can use a
890  // normal fma instead.
891  if (canSimplifyLegacyMulToMul(Op0, Op1, IC)) {
893  II.getModule(), Intrinsic::fma, II.getType()));
894  return &II;
895  }
896  break;
897  }
898  default: {
899  if (const AMDGPU::ImageDimIntrinsicInfo *ImageDimIntr =
901  return simplifyAMDGCNImageIntrinsic(ST, ImageDimIntr, II, IC);
902  }
903  }
904  }
905  return None;
906 }
907 
908 /// Implement SimplifyDemandedVectorElts for amdgcn buffer and image intrinsics.
909 ///
910 /// Note: This only supports non-TFE/LWE image intrinsic calls; those have
911 /// struct returns.
913  IntrinsicInst &II,
914  APInt DemandedElts,
915  int DMaskIdx = -1) {
916 
917  auto *IIVTy = cast<FixedVectorType>(II.getType());
918  unsigned VWidth = IIVTy->getNumElements();
919  if (VWidth == 1)
920  return nullptr;
921 
923  IC.Builder.SetInsertPoint(&II);
924 
925  // Assume the arguments are unchanged and later override them, if needed.
927 
928  if (DMaskIdx < 0) {
929  // Buffer case.
930 
931  const unsigned ActiveBits = DemandedElts.getActiveBits();
932  const unsigned UnusedComponentsAtFront = DemandedElts.countTrailingZeros();
933 
934  // Start assuming the prefix of elements is demanded, but possibly clear
935  // some other bits if there are trailing zeros (unused components at front)
936  // and update offset.
937  DemandedElts = (1 << ActiveBits) - 1;
938 
939  if (UnusedComponentsAtFront > 0) {
940  static const unsigned InvalidOffsetIdx = 0xf;
941 
942  unsigned OffsetIdx;
943  switch (II.getIntrinsicID()) {
944  case Intrinsic::amdgcn_raw_buffer_load:
945  OffsetIdx = 1;
946  break;
947  case Intrinsic::amdgcn_s_buffer_load:
948  // If resulting type is vec3, there is no point in trimming the
949  // load with updated offset, as the vec3 would most likely be widened to
950  // vec4 anyway during lowering.
951  if (ActiveBits == 4 && UnusedComponentsAtFront == 1)
952  OffsetIdx = InvalidOffsetIdx;
953  else
954  OffsetIdx = 1;
955  break;
956  case Intrinsic::amdgcn_struct_buffer_load:
957  OffsetIdx = 2;
958  break;
959  default:
960  // TODO: handle tbuffer* intrinsics.
961  OffsetIdx = InvalidOffsetIdx;
962  break;
963  }
964 
965  if (OffsetIdx != InvalidOffsetIdx) {
966  // Clear demanded bits and update the offset.
967  DemandedElts &= ~((1 << UnusedComponentsAtFront) - 1);
968  auto *Offset = II.getArgOperand(OffsetIdx);
969  unsigned SingleComponentSizeInBits =
971  unsigned OffsetAdd =
972  UnusedComponentsAtFront * SingleComponentSizeInBits / 8;
973  auto *OffsetAddVal = ConstantInt::get(Offset->getType(), OffsetAdd);
974  Args[OffsetIdx] = IC.Builder.CreateAdd(Offset, OffsetAddVal);
975  }
976  }
977  } else {
978  // Image case.
979 
980  ConstantInt *DMask = cast<ConstantInt>(II.getArgOperand(DMaskIdx));
981  unsigned DMaskVal = DMask->getZExtValue() & 0xf;
982 
983  // Mask off values that are undefined because the dmask doesn't cover them
984  DemandedElts &= (1 << countPopulation(DMaskVal)) - 1;
985 
986  unsigned NewDMaskVal = 0;
987  unsigned OrigLoadIdx = 0;
988  for (unsigned SrcIdx = 0; SrcIdx < 4; ++SrcIdx) {
989  const unsigned Bit = 1 << SrcIdx;
990  if (!!(DMaskVal & Bit)) {
991  if (!!DemandedElts[OrigLoadIdx])
992  NewDMaskVal |= Bit;
993  OrigLoadIdx++;
994  }
995  }
996 
997  if (DMaskVal != NewDMaskVal)
998  Args[DMaskIdx] = ConstantInt::get(DMask->getType(), NewDMaskVal);
999  }
1000 
1001  unsigned NewNumElts = DemandedElts.countPopulation();
1002  if (!NewNumElts)
1003  return UndefValue::get(II.getType());
1004 
1005  if (NewNumElts >= VWidth && DemandedElts.isMask()) {
1006  if (DMaskIdx >= 0)
1007  II.setArgOperand(DMaskIdx, Args[DMaskIdx]);
1008  return nullptr;
1009  }
1010 
1011  // Validate function argument and return types, extracting overloaded types
1012  // along the way.
1013  SmallVector<Type *, 6> OverloadTys;
1014  if (!Intrinsic::getIntrinsicSignature(II.getCalledFunction(), OverloadTys))
1015  return nullptr;
1016 
1017  Module *M = II.getParent()->getParent()->getParent();
1018  Type *EltTy = IIVTy->getElementType();
1019  Type *NewTy =
1020  (NewNumElts == 1) ? EltTy : FixedVectorType::get(EltTy, NewNumElts);
1021 
1022  OverloadTys[0] = NewTy;
1023  Function *NewIntrin =
1024  Intrinsic::getDeclaration(M, II.getIntrinsicID(), OverloadTys);
1025 
1026  CallInst *NewCall = IC.Builder.CreateCall(NewIntrin, Args);
1027  NewCall->takeName(&II);
1028  NewCall->copyMetadata(II);
1029 
1030  if (NewNumElts == 1) {
1032  NewCall,
1033  DemandedElts.countTrailingZeros());
1034  }
1035 
1036  SmallVector<int, 8> EltMask;
1037  unsigned NewLoadIdx = 0;
1038  for (unsigned OrigLoadIdx = 0; OrigLoadIdx < VWidth; ++OrigLoadIdx) {
1039  if (!!DemandedElts[OrigLoadIdx])
1040  EltMask.push_back(NewLoadIdx++);
1041  else
1042  EltMask.push_back(NewNumElts);
1043  }
1044 
1045  Value *Shuffle = IC.Builder.CreateShuffleVector(NewCall, EltMask);
1046 
1047  return Shuffle;
1048 }
1049 
1051  InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
1052  APInt &UndefElts2, APInt &UndefElts3,
1053  std::function<void(Instruction *, unsigned, APInt, APInt &)>
1054  SimplifyAndSetOp) const {
1055  switch (II.getIntrinsicID()) {
1056  case Intrinsic::amdgcn_buffer_load:
1057  case Intrinsic::amdgcn_buffer_load_format:
1058  case Intrinsic::amdgcn_raw_buffer_load:
1059  case Intrinsic::amdgcn_raw_buffer_load_format:
1060  case Intrinsic::amdgcn_raw_tbuffer_load:
1061  case Intrinsic::amdgcn_s_buffer_load:
1062  case Intrinsic::amdgcn_struct_buffer_load:
1063  case Intrinsic::amdgcn_struct_buffer_load_format:
1064  case Intrinsic::amdgcn_struct_tbuffer_load:
1065  case Intrinsic::amdgcn_tbuffer_load:
1066  return simplifyAMDGCNMemoryIntrinsicDemanded(IC, II, DemandedElts);
1067  default: {
1068  if (getAMDGPUImageDMaskIntrinsic(II.getIntrinsicID())) {
1069  return simplifyAMDGCNMemoryIntrinsicDemanded(IC, II, DemandedElts, 0);
1070  }
1071  break;
1072  }
1073  }
1074  return None;
1075 }
llvm::APFloat::isDenormal
bool isDenormal() const
Definition: APFloat.h:1218
llvm::InstCombiner::getTargetLibraryInfo
TargetLibraryInfo & getTargetLibraryInfo() const
Definition: InstCombiner.h:368
llvm::APFloat::isInfinity
bool isInfinity() const
Definition: APFloat.h:1214
Signed
@ Signed
Definition: NVPTXISelLowering.cpp:4630
llvm::CmpInst::getSwappedPredicate
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Definition: InstrTypes.h:836
llvm::IRBuilderBase::SetInsertPoint
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition: IRBuilder.h:184
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
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:66
llvm::CmpInst::ICMP_EQ
@ ICMP_EQ
equal
Definition: InstrTypes.h:741
InstCombiner.h
llvm::RecurKind::FMul
@ FMul
Product of floats.
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:1336
llvm::CmpInst::Predicate
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:720
llvm::APFloatBase::IEK_NaN
@ IEK_NaN
Definition: APFloat.h:231
llvm::ConstantInt::getType
IntegerType * getType() const
getType - Specialize the getType() method to always return an IntegerType, which reduces the amount o...
Definition: Constants.h:173
llvm::BasicBlock::getParent
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:107
llvm::AMDGPU::ImageDimIntrinsicInfo::CoordTyArg
uint8_t CoordTyArg
Definition: AMDGPUInstrInfo.h:75
llvm::APInt::isMask
bool isMask(unsigned numBits) const
Definition: APInt.h:500
llvm::Function
Definition: Function.h:61
llvm::IntrinsicInst::getIntrinsicID
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
Definition: IntrinsicInst.h:52
llvm::IRBuilderBase::CreateFCmpOEQ
Value * CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2267
llvm::PatternMatch::m_NaN
cstfp_pred_ty< is_nan > m_NaN()
Match an arbitrary NaN constant.
Definition: PatternMatch.h:638
llvm::DataLayout::getTypeSizeInBits
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
Definition: DataLayout.h:655
C1
instcombine should handle this C2 when C1
Definition: README.txt:263
llvm::Type::getScalarType
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition: Type.h:319
llvm::ConstantExpr::getSExt
static Constant * getSExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:2097
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::InstCombiner::Builder
BuilderTy & Builder
Definition: InstCombiner.h:56
llvm::AMDGPU::ImageDimIntrinsicInfo
Definition: AMDGPUInstrInfo.h:50
llvm::IRBuilder< TargetFolder, IRBuilderCallbackInserter >
llvm::CmpInst::ICMP_NE
@ ICMP_NE
not equal
Definition: InstrTypes.h:742
llvm::CmpInst::getInversePredicate
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition: InstrTypes.h:820
llvm::PatternMatch::m_APFloat
apfloat_match m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
Definition: PatternMatch.h:287
llvm::APFloat::isZero
bool isZero() const
Definition: APFloat.h:1213
llvm::APFloat::divide
opStatus divide(const APFloat &RHS, roundingMode RM)
Definition: APFloat.h:999
llvm::CallBase::isStrictFP
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
Definition: InstrTypes.h:1778
llvm::IRBuilderBase::CreateMaxNum
CallInst * CreateMaxNum(Value *LHS, Value *RHS, const Twine &Name="")
Create call to the maxnum intrinsic.
Definition: IRBuilder.h:897
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::IRBuilderBase::CreateShuffleVector
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Definition: IRBuilder.h:2465
llvm::APFloatBase::IEK_Inf
@ IEK_Inf
Definition: APFloat.h:232
llvm::AMDGPU::ImageDimIntrinsicInfo::GradientTyArg
uint8_t GradientTyArg
Definition: AMDGPUInstrInfo.h:74
llvm::ConstantFP::getValueAPF
const APFloat & getValueAPF() const
Definition: Constants.h:297
llvm::Optional
Definition: APInt.h:33
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::MCID::Convergent
@ Convergent
Definition: MCInstrDesc.h:182
llvm::GCNSubtarget
Definition: GCNSubtarget.h:38
llvm::Instruction::copyMetadata
void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
Definition: Instruction.cpp:829
llvm::Type::isFloatingPointTy
bool isFloatingPointTy() const
Return true if this is one of the six floating-point types.
Definition: Type.h:162
llvm::IRBuilderBase::CreateAShr
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1338
llvm::BitmaskEnumDetail::Mask
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
llvm::APFloat::getSemantics
const fltSemantics & getSemantics() const
Definition: APFloat.h:1225
llvm::Intrinsic::getIntrinsicSignature
bool getIntrinsicSignature(Function *F, SmallVectorImpl< Type * > &ArgTys)
Gets the type arguments of an intrinsic call by matching type contraints specified by the ....
Definition: Function.cpp:1645
llvm::MDNode::get
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1198
llvm::APInt::countPopulation
unsigned countPopulation() const
Count the number of bits set.
Definition: APInt.h:1728
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition: Constants.h:79
llvm::InstCombiner::replaceOperand
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
Definition: InstCombiner.h:437
llvm::GCNTTIImpl::instCombineIntrinsic
Optional< Instruction * > instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const
Definition: AMDGPUInstCombineIntrinsic.cpp:192
fmed3AMDGCN
static APFloat fmed3AMDGCN(const APFloat &Src0, const APFloat &Src1, const APFloat &Src2)
Definition: AMDGPUInstCombineIntrinsic.cpp:43
llvm::IRBuilderBase::CreateFMulFMF
Value * CreateFMulFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name="")
Copy fast-math-flags from an instruction rather than using the builder's default FMF.
Definition: IRBuilder.h:1486
llvm::CmpInst::isFPPredicate
bool isFPPredicate() const
Definition: InstrTypes.h:813
llvm::PatternMatch::m_ZExtOrSExt
match_combine_or< CastClass_match< OpTy, Instruction::ZExt >, CastClass_match< OpTy, Instruction::SExt > > m_ZExtOrSExt(const OpTy &Op)
Definition: PatternMatch.h:1658
llvm::PatternMatch::match
bool match(Val *V, const Pattern &P)
Definition: PatternMatch.h:49
llvm::CmpInst::FIRST_FCMP_PREDICATE
@ FIRST_FCMP_PREDICATE
Definition: InstrTypes.h:738
llvm::Constant::isNullValue
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Definition: Constants.cpp:74
GCNSubtarget.h
llvm::APFloatBase::IEEEhalf
static const fltSemantics & IEEEhalf() LLVM_READNONE
Definition: APFloat.cpp:164
llvm::SIInstrFlags::N_INFINITY
@ N_INFINITY
Definition: SIDefines.h:123
Intr
unsigned Intr
Definition: AMDGPUBaseInfo.cpp:1987
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::CallBase::getCalledFunction
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
Definition: InstrTypes.h:1393
llvm::AMDGPU::ImageDimIntrinsicInfo::CoordStart
uint8_t CoordStart
Definition: AMDGPUInstrInfo.h:64
llvm::IRBuilderBase::getIntNTy
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Definition: IRBuilder.h:531
llvm::CmpInst::FIRST_ICMP_PREDICATE
@ FIRST_ICMP_PREDICATE
Definition: InstrTypes.h:751
llvm::APFloat::isNaN
bool isNaN() const
Definition: APFloat.h:1215
llvm::PatternMatch::m_ZExt
CastClass_match< OpTy, Instruction::ZExt > m_ZExt(const OpTy &Op)
Matches ZExt.
Definition: PatternMatch.h:1639
llvm::Type::getFltSemantics
const fltSemantics & getFltSemantics() const
Definition: Type.h:169
llvm::IntegerType
Class to represent integer types.
Definition: DerivedTypes.h:40
llvm::APFloat::isNegative
bool isNegative() const
Definition: APFloat.h:1217
llvm::Instruction
Definition: Instruction.h:45
llvm::InstCombiner::eraseInstFromFunction
virtual Instruction * eraseInstFromFunction(Instruction &I)=0
Combiner aware instruction erasure.
llvm::IRBuilderBase::getContext
LLVMContext & getContext() const
Definition: IRBuilder.h:180
llvm::ConstantFP
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:257
llvm::IRBuilderBase::CreateInsertElement
Value * CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2451
llvm::UndefValue::get
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1784
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:899
llvm::APInt::countTrailingZeros
unsigned countTrailingZeros() const
Count the number of trailing zero bits.
Definition: APInt.h:1700
llvm::FixedVectorType::get
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition: Type.cpp:650
llvm::Metadata
Root of the metadata hierarchy.
Definition: Metadata.h:62
llvm::None
const NoneType None
Definition: None.h:23
llvm::Type::getIntegerBitWidth
unsigned getIntegerBitWidth() const
Definition: DerivedTypes.h:96
llvm::PatternMatch::m_One
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
Definition: PatternMatch.h:513
simplifyAMDGCNMemoryIntrinsicDemanded
static Value * simplifyAMDGCNMemoryIntrinsicDemanded(InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, int DMaskIdx=-1)
Implement SimplifyDemandedVectorElts for amdgcn buffer and image intrinsics.
Definition: AMDGPUInstCombineIntrinsic.cpp:912
llvm::maxnum
LLVM_READONLY APFloat maxnum(const APFloat &A, const APFloat &B)
Implements IEEE maxNum semantics.
Definition: APFloat.h:1309
AMDGPUTargetTransformInfo.h
llvm::SIInstrFlags::Q_NAN
@ Q_NAN
Definition: SIDefines.h:122
llvm::IRBuilderBase::CreateZExt
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2021
llvm::Type::isIntegerTy
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:201
llvm::APFloat::getQNaN
static APFloat getQNaN(const fltSemantics &Sem, bool Negative=false, const APInt *payload=nullptr)
Factory for QNaN values.
Definition: APFloat.h:916
llvm::SIInstrFlags::N_NORMAL
@ N_NORMAL
Definition: SIDefines.h:124
llvm::APFloat
Definition: APFloat.h:701
llvm::ConstantExpr::getCompare
static Constant * getCompare(unsigned short pred, Constant *C1, Constant *C2, bool OnlyIfReduced=false)
Return an ICmp or FCmp comparison operator constant expression.
Definition: Constants.cpp:2386
llvm::PatternMatch::m_Zero
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
Definition: PatternMatch.h:535
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::countPopulation
unsigned countPopulation(T Value)
Count the number of set bits in a value.
Definition: MathExtras.h:567
llvm::IRBuilderBase::CreateFAddFMF
Value * CreateFAddFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name="")
Copy fast-math-flags from an instruction rather than using the builder's default FMF.
Definition: IRBuilder.h:1436
llvm::APFloat::isNormal
bool isNormal() const
Definition: APFloat.h:1221
llvm::SIInstrFlags::S_NAN
@ S_NAN
Definition: SIDefines.h:121
llvm::InstCombiner::getDataLayout
const DataLayout & getDataLayout() const
Definition: InstCombiner.h:370
llvm::APFloatBase::cmpResult
cmpResult
IEEE-754R 5.11: Floating Point Comparison Relations.
Definition: APFloat.h:180
llvm::GlobalValue::getParent
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:572
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
llvm::APFloatBase::cmpUnordered
@ cmpUnordered
Definition: APFloat.h:184
llvm::PatternMatch::m_AllOnes
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
Definition: PatternMatch.h:445
I
#define I(x, y, z)
Definition: MD5.cpp:59
convertTo16Bit
static Value * convertTo16Bit(Value &V, InstCombiner::BuilderTy &Builder)
Definition: AMDGPUInstCombineIntrinsic.cpp:89
llvm::IRBuilderBase::CreateAdd
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1208
llvm::Type::isHalfTy
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
Definition: Type.h:141
llvm::MDString::get
static MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:473
canSafelyConvertTo16Bit
static bool canSafelyConvertTo16Bit(Value &V)
Definition: AMDGPUInstCombineIntrinsic.cpp:62
simplifyAMDGCNImageIntrinsic
static Optional< Instruction * > simplifyAMDGCNImageIntrinsic(const GCNSubtarget *ST, const AMDGPU::ImageDimIntrinsicInfo *ImageDimIntr, IntrinsicInst &II, InstCombiner &IC)
Definition: AMDGPUInstCombineIntrinsic.cpp:102
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:840
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:83
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::MDNode
Metadata node.
Definition: Metadata.h:897
llvm::AMDGPU::ImageDimIntrinsicInfo::VAddrEnd
uint8_t VAddrEnd
Definition: AMDGPUInstrInfo.h:67
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:651
llvm::PatternMatch::m_Value
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
Definition: PatternMatch.h:76
llvm::APInt
Class for arbitrary precision integers.
Definition: APInt.h:70
llvm::PatternMatch::m_SExt
CastClass_match< OpTy, Instruction::SExt > m_SExt(const OpTy &Op)
Matches SExt.
Definition: PatternMatch.h:1633
llvm::AArch64::RM
@ RM
Definition: AArch64ISelLowering.h:472
llvm::scalbn
APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM)
Definition: APFloat.h:1264
llvm::APFloat::isSignaling
bool isSignaling() const
Definition: APFloat.h:1219
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
uint32_t
llvm::PatternMatch::m_FiniteNonZero
cstfp_pred_ty< is_finitenonzero > m_FiniteNonZero()
Match a finite non-zero FP constant.
Definition: PatternMatch.h:684
llvm::Value::getContext
LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:979
llvm::IRBuilderBase::InsertPointGuard
Definition: IRBuilder.h:367
llvm::Instruction::copyFastMathFlags
void copyFastMathFlags(FastMathFlags FMF)
Convenience function for transferring all fast-math flag values to this instruction,...
Definition: Instruction.cpp:235
llvm::ConstantVector::get
static Constant * get(ArrayRef< Constant * > V)
Definition: Constants.cpp:1368
llvm::isKnownNeverInfinity
bool isKnownNeverInfinity(const Value *V, const TargetLibraryInfo *TLI, unsigned Depth=0)
Return true if the floating-point scalar value is not an infinity or if the floating-point vector val...
Definition: ValueTracking.cpp:3653
llvm::isKnownNeverNaN
bool isKnownNeverNaN(const Value *V, const TargetLibraryInfo *TLI, unsigned Depth=0)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
Definition: ValueTracking.cpp:3717
llvm::CallBase::setArgOperand
void setArgOperand(unsigned i, Value *v)
Definition: InstrTypes.h:1343
llvm::ConstantInt::getZExtValue
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition: Constants.h:142
llvm::InstCombiner::replaceInstUsesWith
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
Definition: InstCombiner.h:416
llvm::SIInstrFlags::P_SUBNORMAL
@ P_SUBNORMAL
Definition: SIDefines.h:128
llvm::SIInstrFlags::P_INFINITY
@ P_INFINITY
Definition: SIDefines.h:130
llvm::PatternMatch::m_FPExt
CastClass_match< OpTy, Instruction::FPExt > m_FPExt(const OpTy &Op)
Definition: PatternMatch.h:1697
AMDGPUInstrInfo.h
llvm::APFloatBase::rmTowardZero
static constexpr roundingMode rmTowardZero
Definition: APFloat.h:194
llvm::SIInstrFlags::P_ZERO
@ P_ZERO
Definition: SIDefines.h:127
llvm::Constant::getNullValue
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:346
llvm::Type::isFloatTy
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition: Type.h:147
llvm::Type::getHalfTy
static Type * getHalfTy(LLVMContext &C)
Definition: Type.cpp:188
llvm::MetadataAsValue::get
static MetadataAsValue * get(LLVMContext &Context, Metadata *MD)
Definition: Metadata.cpp:106
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:946
llvm::fltSemantics
Definition: APFloat.cpp:54
R600Subtarget.h
llvm::CmpInst::isSigned
bool isSigned() const
Definition: InstrTypes.h:934
llvm::AMDGPU::getImageDimIntrinsicInfo
const ImageDimIntrinsicInfo * getImageDimIntrinsicInfo(unsigned Intr)
llvm::Type::isDoubleTy
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition: Type.h:150
llvm::PatternMatch::m_ZeroInt
cst_pred_ty< is_zero_int > m_ZeroInt()
Match an integer 0 or a vector with all elements equal to 0.
Definition: PatternMatch.h:522
llvm::frexp
APFloat frexp(const APFloat &X, int &Exp, APFloat::roundingMode RM)
Equivalent of C standard library function.
Definition: APFloat.h:1276
llvm::InstCombiner
The core instruction combiner logic.
Definition: InstCombiner.h:45
llvm::AMDGPU::Hwreg::Width
Width
Definition: SIDefines.h:403
llvm::IntrinsicInst
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:45
llvm::CallBase::setCalledOperand
void setCalledOperand(Value *V)
Definition: InstrTypes.h:1426
llvm::PatternMatch::m_AnyZeroFP
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
Definition: PatternMatch.h:696
llvm::IRBuilderBase::CreateMinNum
CallInst * CreateMinNum(Value *LHS, Value *RHS, const Twine &Name="")
Create call to the minnum intrinsic.
Definition: IRBuilder.h:892
llvm::AttributeList::FunctionIndex
@ FunctionIndex
Definition: Attributes.h:402
llvm::IRBuilderBase::CreateSExt
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2025
llvm::SIInstrFlags::N_ZERO
@ N_ZERO
Definition: SIDefines.h:126
llvm::APFloatBase::rmNearestTiesToEven
static constexpr roundingMode rmNearestTiesToEven
Definition: APFloat.h:190
llvm::RecurKind::FAdd
@ FAdd
Sum of floats.
llvm::APFloat::convert
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Definition: APFloat.cpp:4825
llvm::PatternMatch::m_Specific
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
Definition: PatternMatch.h:802
llvm::IRBuilderBase::CreateLShr
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1318
llvm::CallBase::getArgOperand
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1338
llvm::IRBuilderBase::CreateFCmpUNO
Value * CreateFCmpUNO(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2302
llvm::IRBuilderBase::CreateShl
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1297
llvm::Instruction::getParent
const BasicBlock * getParent() const
Definition: Instruction.h:94
llvm::APInt::getActiveBits
unsigned getActiveBits() const
Compute the number of active bits in the value.
Definition: APInt.h:1605
llvm::tgtok::Bit
@ Bit
Definition: TGLexer.h:50
llvm::SIInstrFlags::N_SUBNORMAL
@ N_SUBNORMAL
Definition: SIDefines.h:125
llvm::CallBase::addAttribute
void addAttribute(unsigned i, Attribute::AttrKind Kind)
adds the attribute to the list of attributes.
Definition: InstrTypes.h:1489
llvm::CmpInst::LAST_FCMP_PREDICATE
@ LAST_FCMP_PREDICATE
Definition: InstrTypes.h:739
RegName
#define RegName(no)
llvm::Type::getInt16Ty
static IntegerType * getInt16Ty(LLVMContext &C)
Definition: Type.cpp:202
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1475
llvm::APFloat::compare
cmpResult compare(const APFloat &RHS) const
Definition: APFloat.h:1172
llvm::AMDGPU::ImageDimIntrinsicInfo::GradientStart
uint8_t GradientStart
Definition: AMDGPUInstrInfo.h:63
llvm::Value::takeName
void takeName(Value *V)
Transfer the name from V to this value.
Definition: Value.cpp:370
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::User::getOperand
Value * getOperand(unsigned i) const
Definition: User.h:169
llvm::GCNTTIImpl::canSimplifyLegacyMulToMul
bool canSimplifyLegacyMulToMul(const Value *Op0, const Value *Op1, InstCombiner &IC) const
Definition: AMDGPUInstCombineIntrinsic.cpp:170
llvm::GCNTTIImpl::simplifyDemandedVectorEltsIntrinsic
Optional< Value * > simplifyDemandedVectorEltsIntrinsic(InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts, APInt &UndefElts2, APInt &UndefElts3, std::function< void(Instruction *, unsigned, APInt, APInt &)> SimplifyAndSetOp) const
Definition: AMDGPUInstCombineIntrinsic.cpp:1050
llvm::CallBase::arg_operands
iterator_range< User::op_iterator > arg_operands()
Definition: InstrTypes.h:1330
llvm::APFloatBase::cmpEqual
@ cmpEqual
Definition: APFloat.h:182
llvm::SIInstrFlags::P_NORMAL
@ P_NORMAL
Definition: SIDefines.h:129
llvm::PatternMatch::m_Cmp
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
Definition: PatternMatch.h:89
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::IRBuilderBase::CreateCall
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2391
llvm::CallBase::args
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
Definition: InstrTypes.h:1319
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38
llvm::CmpInst::LAST_ICMP_PREDICATE
@ LAST_ICMP_PREDICATE
Definition: InstrTypes.h:752