clang  16.0.0git
RISCVVIntrinsicUtils.cpp
Go to the documentation of this file.
1 //===- RISCVVIntrinsicUtils.cpp - RISC-V Vector Intrinsic Utils -*- C++ -*-===//
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 
10 #include "llvm/ADT/ArrayRef.h"
11 #include "llvm/ADT/Optional.h"
12 #include "llvm/ADT/SmallSet.h"
13 #include "llvm/ADT/StringExtras.h"
14 #include "llvm/ADT/StringMap.h"
15 #include "llvm/ADT/StringSet.h"
16 #include "llvm/ADT/Twine.h"
17 #include "llvm/Support/raw_ostream.h"
18 #include <numeric>
19 
20 using namespace llvm;
21 
22 namespace clang {
23 namespace RISCV {
24 
25 const PrototypeDescriptor PrototypeDescriptor::Mask = PrototypeDescriptor(
26  BaseTypeModifier::Vector, VectorTypeModifier::MaskVector);
27 const PrototypeDescriptor PrototypeDescriptor::VL =
28  PrototypeDescriptor(BaseTypeModifier::SizeT);
29 const PrototypeDescriptor PrototypeDescriptor::Vector =
30  PrototypeDescriptor(BaseTypeModifier::Vector);
31 
32 //===----------------------------------------------------------------------===//
33 // Type implementation
34 //===----------------------------------------------------------------------===//
35 
36 LMULType::LMULType(int NewLog2LMUL) {
37  // Check Log2LMUL is -3, -2, -1, 0, 1, 2, 3
38  assert(NewLog2LMUL <= 3 && NewLog2LMUL >= -3 && "Bad LMUL number!");
39  Log2LMUL = NewLog2LMUL;
40 }
41 
42 std::string LMULType::str() const {
43  if (Log2LMUL < 0)
44  return "mf" + utostr(1ULL << (-Log2LMUL));
45  return "m" + utostr(1ULL << Log2LMUL);
46 }
47 
48 VScaleVal LMULType::getScale(unsigned ElementBitwidth) const {
49  int Log2ScaleResult = 0;
50  switch (ElementBitwidth) {
51  default:
52  break;
53  case 8:
54  Log2ScaleResult = Log2LMUL + 3;
55  break;
56  case 16:
57  Log2ScaleResult = Log2LMUL + 2;
58  break;
59  case 32:
60  Log2ScaleResult = Log2LMUL + 1;
61  break;
62  case 64:
63  Log2ScaleResult = Log2LMUL;
64  break;
65  }
66  // Illegal vscale result would be less than 1
67  if (Log2ScaleResult < 0)
68  return llvm::None;
69  return 1 << Log2ScaleResult;
70 }
71 
72 void LMULType::MulLog2LMUL(int log2LMUL) { Log2LMUL += log2LMUL; }
73 
74 RVVType::RVVType(BasicType BT, int Log2LMUL,
75  const PrototypeDescriptor &prototype)
76  : BT(BT), LMUL(LMULType(Log2LMUL)) {
77  applyBasicType();
78  applyModifier(prototype);
79  Valid = verifyType();
80  if (Valid) {
81  initBuiltinStr();
82  initTypeStr();
83  if (isVector()) {
84  initClangBuiltinStr();
85  }
86  }
87 }
88 
89 // clang-format off
90 // boolean type are encoded the ratio of n (SEW/LMUL)
91 // SEW/LMUL | 1 | 2 | 4 | 8 | 16 | 32 | 64
92 // c type | vbool64_t | vbool32_t | vbool16_t | vbool8_t | vbool4_t | vbool2_t | vbool1_t
93 // IR type | nxv1i1 | nxv2i1 | nxv4i1 | nxv8i1 | nxv16i1 | nxv32i1 | nxv64i1
94 
95 // type\lmul | 1/8 | 1/4 | 1/2 | 1 | 2 | 4 | 8
96 // -------- |------ | -------- | ------- | ------- | -------- | -------- | --------
97 // i64 | N/A | N/A | N/A | nxv1i64 | nxv2i64 | nxv4i64 | nxv8i64
98 // i32 | N/A | N/A | nxv1i32 | nxv2i32 | nxv4i32 | nxv8i32 | nxv16i32
99 // i16 | N/A | nxv1i16 | nxv2i16 | nxv4i16 | nxv8i16 | nxv16i16 | nxv32i16
100 // i8 | nxv1i8 | nxv2i8 | nxv4i8 | nxv8i8 | nxv16i8 | nxv32i8 | nxv64i8
101 // double | N/A | N/A | N/A | nxv1f64 | nxv2f64 | nxv4f64 | nxv8f64
102 // float | N/A | N/A | nxv1f32 | nxv2f32 | nxv4f32 | nxv8f32 | nxv16f32
103 // half | N/A | nxv1f16 | nxv2f16 | nxv4f16 | nxv8f16 | nxv16f16 | nxv32f16
104 // clang-format on
105 
106 bool RVVType::verifyType() const {
107  if (ScalarType == Invalid)
108  return false;
109  if (isScalar())
110  return true;
111  if (!Scale)
112  return false;
113  if (isFloat() && ElementBitwidth == 8)
114  return false;
115  unsigned V = Scale.value();
116  switch (ElementBitwidth) {
117  case 1:
118  case 8:
119  // Check Scale is 1,2,4,8,16,32,64
120  return (V <= 64 && isPowerOf2_32(V));
121  case 16:
122  // Check Scale is 1,2,4,8,16,32
123  return (V <= 32 && isPowerOf2_32(V));
124  case 32:
125  // Check Scale is 1,2,4,8,16
126  return (V <= 16 && isPowerOf2_32(V));
127  case 64:
128  // Check Scale is 1,2,4,8
129  return (V <= 8 && isPowerOf2_32(V));
130  }
131  return false;
132 }
133 
134 void RVVType::initBuiltinStr() {
135  assert(isValid() && "RVVType is invalid");
136  switch (ScalarType) {
137  case ScalarTypeKind::Void:
138  BuiltinStr = "v";
139  return;
141  BuiltinStr = "z";
142  if (IsImmediate)
143  BuiltinStr = "I" + BuiltinStr;
144  if (IsPointer)
145  BuiltinStr += "*";
146  return;
148  BuiltinStr = "Y";
149  return;
151  BuiltinStr = "ULi";
152  return;
154  BuiltinStr = "Li";
155  return;
157  assert(ElementBitwidth == 1);
158  BuiltinStr += "b";
159  break;
162  switch (ElementBitwidth) {
163  case 8:
164  BuiltinStr += "c";
165  break;
166  case 16:
167  BuiltinStr += "s";
168  break;
169  case 32:
170  BuiltinStr += "i";
171  break;
172  case 64:
173  BuiltinStr += "Wi";
174  break;
175  default:
176  llvm_unreachable("Unhandled ElementBitwidth!");
177  }
178  if (isSignedInteger())
179  BuiltinStr = "S" + BuiltinStr;
180  else
181  BuiltinStr = "U" + BuiltinStr;
182  break;
184  switch (ElementBitwidth) {
185  case 16:
186  BuiltinStr += "x";
187  break;
188  case 32:
189  BuiltinStr += "f";
190  break;
191  case 64:
192  BuiltinStr += "d";
193  break;
194  default:
195  llvm_unreachable("Unhandled ElementBitwidth!");
196  }
197  break;
198  default:
199  llvm_unreachable("ScalarType is invalid!");
200  }
201  if (IsImmediate)
202  BuiltinStr = "I" + BuiltinStr;
203  if (isScalar()) {
204  if (IsConstant)
205  BuiltinStr += "C";
206  if (IsPointer)
207  BuiltinStr += "*";
208  return;
209  }
210  BuiltinStr = "q" + utostr(*Scale) + BuiltinStr;
211  // Pointer to vector types. Defined for segment load intrinsics.
212  // segment load intrinsics have pointer type arguments to store the loaded
213  // vector values.
214  if (IsPointer)
215  BuiltinStr += "*";
216 }
217 
218 void RVVType::initClangBuiltinStr() {
219  assert(isValid() && "RVVType is invalid");
220  assert(isVector() && "Handle Vector type only");
221 
222  ClangBuiltinStr = "__rvv_";
223  switch (ScalarType) {
225  ClangBuiltinStr += "bool" + utostr(64 / *Scale) + "_t";
226  return;
228  ClangBuiltinStr += "float";
229  break;
231  ClangBuiltinStr += "int";
232  break;
234  ClangBuiltinStr += "uint";
235  break;
236  default:
237  llvm_unreachable("ScalarTypeKind is invalid");
238  }
239  ClangBuiltinStr += utostr(ElementBitwidth) + LMUL.str() + "_t";
240 }
241 
242 void RVVType::initTypeStr() {
243  assert(isValid() && "RVVType is invalid");
244 
245  if (IsConstant)
246  Str += "const ";
247 
248  auto getTypeString = [&](StringRef TypeStr) {
249  if (isScalar())
250  return Twine(TypeStr + Twine(ElementBitwidth) + "_t").str();
251  return Twine("v" + TypeStr + Twine(ElementBitwidth) + LMUL.str() + "_t")
252  .str();
253  };
254 
255  switch (ScalarType) {
256  case ScalarTypeKind::Void:
257  Str = "void";
258  return;
260  Str = "size_t";
261  if (IsPointer)
262  Str += " *";
263  return;
265  Str = "ptrdiff_t";
266  return;
268  Str = "unsigned long";
269  return;
271  Str = "long";
272  return;
274  if (isScalar())
275  Str += "bool";
276  else
277  // Vector bool is special case, the formulate is
278  // `vbool<N>_t = MVT::nxv<64/N>i1` ex. vbool16_t = MVT::4i1
279  Str += "vbool" + utostr(64 / *Scale) + "_t";
280  break;
282  if (isScalar()) {
283  if (ElementBitwidth == 64)
284  Str += "double";
285  else if (ElementBitwidth == 32)
286  Str += "float";
287  else if (ElementBitwidth == 16)
288  Str += "_Float16";
289  else
290  llvm_unreachable("Unhandled floating type.");
291  } else
292  Str += getTypeString("float");
293  break;
295  Str += getTypeString("int");
296  break;
298  Str += getTypeString("uint");
299  break;
300  default:
301  llvm_unreachable("ScalarType is invalid!");
302  }
303  if (IsPointer)
304  Str += " *";
305 }
306 
307 void RVVType::initShortStr() {
308  switch (ScalarType) {
310  assert(isVector());
311  ShortStr = "b" + utostr(64 / *Scale);
312  return;
314  ShortStr = "f" + utostr(ElementBitwidth);
315  break;
317  ShortStr = "i" + utostr(ElementBitwidth);
318  break;
320  ShortStr = "u" + utostr(ElementBitwidth);
321  break;
322  default:
323  llvm_unreachable("Unhandled case!");
324  }
325  if (isVector())
326  ShortStr += LMUL.str();
327 }
328 
329 void RVVType::applyBasicType() {
330  switch (BT) {
331  case BasicType::Int8:
332  ElementBitwidth = 8;
333  ScalarType = ScalarTypeKind::SignedInteger;
334  break;
335  case BasicType::Int16:
336  ElementBitwidth = 16;
337  ScalarType = ScalarTypeKind::SignedInteger;
338  break;
339  case BasicType::Int32:
340  ElementBitwidth = 32;
341  ScalarType = ScalarTypeKind::SignedInteger;
342  break;
343  case BasicType::Int64:
344  ElementBitwidth = 64;
345  ScalarType = ScalarTypeKind::SignedInteger;
346  break;
347  case BasicType::Float16:
348  ElementBitwidth = 16;
349  ScalarType = ScalarTypeKind::Float;
350  break;
351  case BasicType::Float32:
352  ElementBitwidth = 32;
353  ScalarType = ScalarTypeKind::Float;
354  break;
355  case BasicType::Float64:
356  ElementBitwidth = 64;
357  ScalarType = ScalarTypeKind::Float;
358  break;
359  default:
360  llvm_unreachable("Unhandled type code!");
361  }
362  assert(ElementBitwidth != 0 && "Bad element bitwidth!");
363 }
364 
366  llvm::StringRef PrototypeDescriptorStr) {
370 
371  if (PrototypeDescriptorStr.empty())
372  return PD;
373 
374  // Handle base type modifier
375  auto PType = PrototypeDescriptorStr.back();
376  switch (PType) {
377  case 'e':
379  break;
380  case 'v':
382  break;
383  case 'w':
386  break;
387  case 'q':
390  break;
391  case 'o':
394  break;
395  case 'm':
398  break;
399  case '0':
400  PT = BaseTypeModifier::Void;
401  break;
402  case 'z':
404  break;
405  case 't':
407  break;
408  case 'u':
410  break;
411  case 'l':
413  break;
414  default:
415  llvm_unreachable("Illegal primitive type transformers!");
416  }
417  PD.PT = static_cast<uint8_t>(PT);
418  PrototypeDescriptorStr = PrototypeDescriptorStr.drop_back();
419 
420  // Compute the vector type transformers, it can only appear one time.
421  if (PrototypeDescriptorStr.startswith("(")) {
423  "VectorTypeModifier should only have one modifier");
424  size_t Idx = PrototypeDescriptorStr.find(')');
425  assert(Idx != StringRef::npos);
426  StringRef ComplexType = PrototypeDescriptorStr.slice(1, Idx);
427  PrototypeDescriptorStr = PrototypeDescriptorStr.drop_front(Idx + 1);
428  assert(!PrototypeDescriptorStr.contains('(') &&
429  "Only allow one vector type modifier");
430 
431  auto ComplexTT = ComplexType.split(":");
432  if (ComplexTT.first == "Log2EEW") {
433  uint32_t Log2EEW;
434  if (ComplexTT.second.getAsInteger(10, Log2EEW)) {
435  llvm_unreachable("Invalid Log2EEW value!");
436  return None;
437  }
438  switch (Log2EEW) {
439  case 3:
441  break;
442  case 4:
444  break;
445  case 5:
447  break;
448  case 6:
450  break;
451  default:
452  llvm_unreachable("Invalid Log2EEW value, should be [3-6]");
453  return None;
454  }
455  } else if (ComplexTT.first == "FixedSEW") {
456  uint32_t NewSEW;
457  if (ComplexTT.second.getAsInteger(10, NewSEW)) {
458  llvm_unreachable("Invalid FixedSEW value!");
459  return None;
460  }
461  switch (NewSEW) {
462  case 8:
464  break;
465  case 16:
467  break;
468  case 32:
470  break;
471  case 64:
473  break;
474  default:
475  llvm_unreachable("Invalid FixedSEW value, should be 8, 16, 32 or 64");
476  return None;
477  }
478  } else if (ComplexTT.first == "LFixedLog2LMUL") {
479  int32_t Log2LMUL;
480  if (ComplexTT.second.getAsInteger(10, Log2LMUL)) {
481  llvm_unreachable("Invalid LFixedLog2LMUL value!");
482  return None;
483  }
484  switch (Log2LMUL) {
485  case -3:
487  break;
488  case -2:
490  break;
491  case -1:
493  break;
494  case 0:
496  break;
497  case 1:
499  break;
500  case 2:
502  break;
503  case 3:
505  break;
506  default:
507  llvm_unreachable("Invalid LFixedLog2LMUL value, should be [-3, 3]");
508  return None;
509  }
510  } else if (ComplexTT.first == "SFixedLog2LMUL") {
511  int32_t Log2LMUL;
512  if (ComplexTT.second.getAsInteger(10, Log2LMUL)) {
513  llvm_unreachable("Invalid SFixedLog2LMUL value!");
514  return None;
515  }
516  switch (Log2LMUL) {
517  case -3:
519  break;
520  case -2:
522  break;
523  case -1:
525  break;
526  case 0:
528  break;
529  case 1:
531  break;
532  case 2:
534  break;
535  case 3:
537  break;
538  default:
539  llvm_unreachable("Invalid LFixedLog2LMUL value, should be [-3, 3]");
540  return None;
541  }
542 
543  } else {
544  llvm_unreachable("Illegal complex type transformers!");
545  }
546  }
547  PD.VTM = static_cast<uint8_t>(VTM);
548 
549  // Compute the remain type transformers
551  for (char I : PrototypeDescriptorStr) {
552  switch (I) {
553  case 'P':
555  llvm_unreachable("'P' transformer cannot be used after 'C'");
557  llvm_unreachable("'P' transformer cannot be used twice");
559  break;
560  case 'C':
562  break;
563  case 'K':
565  break;
566  case 'U':
568  break;
569  case 'I':
571  break;
572  case 'F':
574  break;
575  case 'S':
577  break;
578  default:
579  llvm_unreachable("Illegal non-primitive type transformer!");
580  }
581  }
582  PD.TM = static_cast<uint8_t>(TM);
583 
584  return PD;
585 }
586 
587 void RVVType::applyModifier(const PrototypeDescriptor &Transformer) {
588  // Handle primitive type transformer
589  switch (static_cast<BaseTypeModifier>(Transformer.PT)) {
591  Scale = 0;
592  break;
594  Scale = LMUL.getScale(ElementBitwidth);
595  break;
596  case BaseTypeModifier::Void:
597  ScalarType = ScalarTypeKind::Void;
598  break;
600  ScalarType = ScalarTypeKind::Size_t;
601  break;
603  ScalarType = ScalarTypeKind::Ptrdiff_t;
604  break;
606  ScalarType = ScalarTypeKind::UnsignedLong;
607  break;
609  ScalarType = ScalarTypeKind::SignedLong;
610  break;
612  ScalarType = ScalarTypeKind::Invalid;
613  return;
614  }
615 
616  switch (static_cast<VectorTypeModifier>(Transformer.VTM)) {
618  ElementBitwidth *= 2;
619  LMUL.MulLog2LMUL(1);
620  Scale = LMUL.getScale(ElementBitwidth);
621  break;
623  ElementBitwidth *= 4;
624  LMUL.MulLog2LMUL(2);
625  Scale = LMUL.getScale(ElementBitwidth);
626  break;
628  ElementBitwidth *= 8;
629  LMUL.MulLog2LMUL(3);
630  Scale = LMUL.getScale(ElementBitwidth);
631  break;
633  ScalarType = ScalarTypeKind::Boolean;
634  Scale = LMUL.getScale(ElementBitwidth);
635  ElementBitwidth = 1;
636  break;
638  applyLog2EEW(3);
639  break;
641  applyLog2EEW(4);
642  break;
644  applyLog2EEW(5);
645  break;
647  applyLog2EEW(6);
648  break;
650  applyFixedSEW(8);
651  break;
653  applyFixedSEW(16);
654  break;
656  applyFixedSEW(32);
657  break;
659  applyFixedSEW(64);
660  break;
662  applyFixedLog2LMUL(-3, FixedLMULType::LargerThan);
663  break;
665  applyFixedLog2LMUL(-2, FixedLMULType::LargerThan);
666  break;
668  applyFixedLog2LMUL(-1, FixedLMULType::LargerThan);
669  break;
671  applyFixedLog2LMUL(0, FixedLMULType::LargerThan);
672  break;
674  applyFixedLog2LMUL(1, FixedLMULType::LargerThan);
675  break;
677  applyFixedLog2LMUL(2, FixedLMULType::LargerThan);
678  break;
680  applyFixedLog2LMUL(3, FixedLMULType::LargerThan);
681  break;
683  applyFixedLog2LMUL(-3, FixedLMULType::SmallerThan);
684  break;
686  applyFixedLog2LMUL(-2, FixedLMULType::SmallerThan);
687  break;
689  applyFixedLog2LMUL(-1, FixedLMULType::SmallerThan);
690  break;
692  applyFixedLog2LMUL(0, FixedLMULType::SmallerThan);
693  break;
695  applyFixedLog2LMUL(1, FixedLMULType::SmallerThan);
696  break;
698  applyFixedLog2LMUL(2, FixedLMULType::SmallerThan);
699  break;
701  applyFixedLog2LMUL(3, FixedLMULType::SmallerThan);
702  break;
704  break;
705  }
706 
707  for (unsigned TypeModifierMaskShift = 0;
708  TypeModifierMaskShift <= static_cast<unsigned>(TypeModifier::MaxOffset);
709  ++TypeModifierMaskShift) {
710  unsigned TypeModifierMask = 1 << TypeModifierMaskShift;
711  if ((static_cast<unsigned>(Transformer.TM) & TypeModifierMask) !=
712  TypeModifierMask)
713  continue;
714  switch (static_cast<TypeModifier>(TypeModifierMask)) {
716  IsPointer = true;
717  break;
718  case TypeModifier::Const:
719  IsConstant = true;
720  break;
722  IsImmediate = true;
723  IsConstant = true;
724  break;
726  ScalarType = ScalarTypeKind::UnsignedInteger;
727  break;
729  ScalarType = ScalarTypeKind::SignedInteger;
730  break;
731  case TypeModifier::Float:
732  ScalarType = ScalarTypeKind::Float;
733  break;
734  case TypeModifier::LMUL1:
735  LMUL = LMULType(0);
736  // Update ElementBitwidth need to update Scale too.
737  Scale = LMUL.getScale(ElementBitwidth);
738  break;
739  default:
740  llvm_unreachable("Unknown type modifier mask!");
741  }
742  }
743 }
744 
745 void RVVType::applyLog2EEW(unsigned Log2EEW) {
746  // update new elmul = (eew/sew) * lmul
747  LMUL.MulLog2LMUL(Log2EEW - Log2_32(ElementBitwidth));
748  // update new eew
749  ElementBitwidth = 1 << Log2EEW;
750  ScalarType = ScalarTypeKind::SignedInteger;
751  Scale = LMUL.getScale(ElementBitwidth);
752 }
753 
754 void RVVType::applyFixedSEW(unsigned NewSEW) {
755  // Set invalid type if src and dst SEW are same.
756  if (ElementBitwidth == NewSEW) {
757  ScalarType = ScalarTypeKind::Invalid;
758  return;
759  }
760  // Update new SEW
761  ElementBitwidth = NewSEW;
762  Scale = LMUL.getScale(ElementBitwidth);
763 }
764 
765 void RVVType::applyFixedLog2LMUL(int Log2LMUL, enum FixedLMULType Type) {
766  switch (Type) {
767  case FixedLMULType::LargerThan:
768  if (Log2LMUL < LMUL.Log2LMUL) {
769  ScalarType = ScalarTypeKind::Invalid;
770  return;
771  }
772  break;
773  case FixedLMULType::SmallerThan:
774  if (Log2LMUL > LMUL.Log2LMUL) {
775  ScalarType = ScalarTypeKind::Invalid;
776  return;
777  }
778  break;
779  }
780 
781  // Update new LMUL
782  LMUL = LMULType(Log2LMUL);
783  Scale = LMUL.getScale(ElementBitwidth);
784 }
785 
787 RVVTypeCache::computeTypes(BasicType BT, int Log2LMUL, unsigned NF,
788  ArrayRef<PrototypeDescriptor> Prototype) {
789  // LMUL x NF must be less than or equal to 8.
790  if ((Log2LMUL >= 1) && (1 << Log2LMUL) * NF > 8)
791  return llvm::None;
792 
793  RVVTypes Types;
794  for (const PrototypeDescriptor &Proto : Prototype) {
795  auto T = computeType(BT, Log2LMUL, Proto);
796  if (!T)
797  return llvm::None;
798  // Record legal type index
799  Types.push_back(T.value());
800  }
801  return Types;
802 }
803 
804 // Compute the hash value of RVVType, used for cache the result of computeType.
806  PrototypeDescriptor Proto) {
807  // Layout of hash value:
808  // 0 8 16 24 32 40
809  // | Log2LMUL + 3 | BT | Proto.PT | Proto.TM | Proto.VTM |
810  assert(Log2LMUL >= -3 && Log2LMUL <= 3);
811  return (Log2LMUL + 3) | (static_cast<uint64_t>(BT) & 0xff) << 8 |
812  ((uint64_t)(Proto.PT & 0xff) << 16) |
813  ((uint64_t)(Proto.TM & 0xff) << 24) |
814  ((uint64_t)(Proto.VTM & 0xff) << 32);
815 }
816 
818  PrototypeDescriptor Proto) {
819  uint64_t Idx = computeRVVTypeHashValue(BT, Log2LMUL, Proto);
820  // Search first
821  auto It = LegalTypes.find(Idx);
822  if (It != LegalTypes.end())
823  return &(It->second);
824 
825  if (IllegalTypes.count(Idx))
826  return llvm::None;
827 
828  // Compute type and record the result.
829  RVVType T(BT, Log2LMUL, Proto);
830  if (T.isValid()) {
831  // Record legal type index and value.
832  std::pair<std::unordered_map<uint64_t, RVVType>::iterator, bool>
833  InsertResult = LegalTypes.insert({Idx, T});
834  return &(InsertResult.first->second);
835  }
836  // Record illegal type index.
837  IllegalTypes.insert(Idx);
838  return llvm::None;
839 }
840 
841 //===----------------------------------------------------------------------===//
842 // RVVIntrinsic implementation
843 //===----------------------------------------------------------------------===//
845  StringRef NewName, StringRef Suffix, StringRef NewOverloadedName,
846  StringRef OverloadedSuffix, StringRef IRName, bool IsMasked,
847  bool HasMaskedOffOperand, bool HasVL, PolicyScheme Scheme,
848  bool SupportOverloading, bool HasBuiltinAlias, StringRef ManualCodegen,
849  const RVVTypes &OutInTypes, const std::vector<int64_t> &NewIntrinsicTypes,
850  const std::vector<StringRef> &RequiredFeatures, unsigned NF,
851  Policy NewDefaultPolicy, bool IsPrototypeDefaultTU)
852  : IRName(IRName), IsMasked(IsMasked),
853  HasMaskedOffOperand(HasMaskedOffOperand), HasVL(HasVL), Scheme(Scheme),
854  SupportOverloading(SupportOverloading), HasBuiltinAlias(HasBuiltinAlias),
855  ManualCodegen(ManualCodegen.str()), NF(NF),
856  DefaultPolicy(NewDefaultPolicy) {
857 
858  // Init BuiltinName, Name and OverloadedName
859  BuiltinName = NewName.str();
860  Name = BuiltinName;
861  if (NewOverloadedName.empty())
862  OverloadedName = NewName.split("_").first.str();
863  else
864  OverloadedName = NewOverloadedName.str();
865  if (!Suffix.empty())
866  Name += "_" + Suffix.str();
867  if (!OverloadedSuffix.empty())
868  OverloadedName += "_" + OverloadedSuffix.str();
869 
870  updateNamesAndPolicy(IsMasked, hasPolicy(), IsPrototypeDefaultTU, Name,
871  BuiltinName, OverloadedName, DefaultPolicy);
872 
873  // Init OutputType and InputTypes
874  OutputType = OutInTypes[0];
875  InputTypes.assign(OutInTypes.begin() + 1, OutInTypes.end());
876 
877  // IntrinsicTypes is unmasked TA version index. Need to update it
878  // if there is merge operand (It is always in first operand).
879  IntrinsicTypes = NewIntrinsicTypes;
880  if ((IsMasked && hasMaskedOffOperand()) ||
881  (!IsMasked && hasPassthruOperand() && !IsPrototypeDefaultTU)) {
882  for (auto &I : IntrinsicTypes) {
883  if (I >= 0)
884  I += NF;
885  }
886  }
887 }
888 
890  std::string S;
891  S += OutputType->getBuiltinStr();
892  for (const auto &T : InputTypes) {
893  S += T->getBuiltinStr();
894  }
895  return S;
896 }
897 
899  RVVTypeCache &TypeCache, BasicType Type, int Log2LMUL,
900  llvm::ArrayRef<PrototypeDescriptor> PrototypeDescriptors) {
901  SmallVector<std::string> SuffixStrs;
902  for (auto PD : PrototypeDescriptors) {
903  auto T = TypeCache.computeType(Type, Log2LMUL, PD);
904  SuffixStrs.push_back((*T)->getShortStr());
905  }
906  return join(SuffixStrs, "_");
907 }
908 
910  llvm::ArrayRef<PrototypeDescriptor> Prototype, bool IsMasked,
911  bool HasMaskedOffOperand, bool HasVL, unsigned NF,
912  bool IsPrototypeDefaultTU, PolicyScheme DefaultScheme,
913  Policy DefaultPolicy) {
914  SmallVector<PrototypeDescriptor> NewPrototype(Prototype.begin(),
915  Prototype.end());
916  // Update DefaultPolicy if need (TA or TAMA) for compute builtin types.
917  switch (DefaultPolicy) {
918  case Policy::MA:
919  DefaultPolicy = Policy::TAMA;
920  break;
921  case Policy::TAM:
922  DefaultPolicy = Policy::TAMA;
923  break;
924  case Policy::PolicyNone:
925  // Masked with no policy would not be TAMA.
926  if (!IsMasked) {
927  if (IsPrototypeDefaultTU)
928  DefaultPolicy = Policy::TU;
929  else
930  DefaultPolicy = Policy::TA;
931  }
932  break;
933  default:
934  break;
935  }
936  bool HasPassthruOp = DefaultScheme == PolicyScheme::HasPassthruOperand;
937  if (IsMasked) {
938  // If HasMaskedOffOperand, insert result type as first input operand if
939  // need.
940  if (HasMaskedOffOperand && DefaultPolicy != Policy::TAMA) {
941  if (NF == 1) {
942  NewPrototype.insert(NewPrototype.begin() + 1, NewPrototype[0]);
943  } else if (NF > 1) {
944  // Convert
945  // (void, op0 address, op1 address, ...)
946  // to
947  // (void, op0 address, op1 address, ..., maskedoff0, maskedoff1, ...)
948  PrototypeDescriptor MaskoffType = NewPrototype[1];
949  MaskoffType.TM &= ~static_cast<uint8_t>(TypeModifier::Pointer);
950  for (unsigned I = 0; I < NF; ++I)
951  NewPrototype.insert(NewPrototype.begin() + NF + 1, MaskoffType);
952  }
953  }
954  // Erase passthru operand for TAM
955  if (NF == 1 && IsPrototypeDefaultTU && DefaultPolicy == Policy::TAMA &&
956  HasPassthruOp && !HasMaskedOffOperand)
957  NewPrototype.erase(NewPrototype.begin() + 1);
958  if (HasMaskedOffOperand && NF > 1) {
959  // Convert
960  // (void, op0 address, op1 address, ..., maskedoff0, maskedoff1, ...)
961  // to
962  // (void, op0 address, op1 address, ..., mask, maskedoff0, maskedoff1,
963  // ...)
964  NewPrototype.insert(NewPrototype.begin() + NF + 1,
966  } else {
967  // If IsMasked, insert PrototypeDescriptor:Mask as first input operand.
968  NewPrototype.insert(NewPrototype.begin() + 1, PrototypeDescriptor::Mask);
969  }
970  } else {
971  if (NF == 1) {
972  if (DefaultPolicy == Policy::TU && HasPassthruOp && !IsPrototypeDefaultTU)
973  NewPrototype.insert(NewPrototype.begin(), NewPrototype[0]);
974  else if (DefaultPolicy == Policy::TA && HasPassthruOp &&
975  IsPrototypeDefaultTU)
976  NewPrototype.erase(NewPrototype.begin() + 1);
977  if (DefaultScheme == PolicyScheme::HasPassthruOperandAtIdx1) {
978  if (DefaultPolicy == Policy::TU && !IsPrototypeDefaultTU) {
979  // Insert undisturbed output to index 1
980  NewPrototype.insert(NewPrototype.begin() + 2, NewPrototype[0]);
981  } else if (DefaultPolicy == Policy::TA && IsPrototypeDefaultTU) {
982  // Erase passthru for TA policy
983  NewPrototype.erase(NewPrototype.begin() + 2);
984  }
985  }
986  } else if (DefaultPolicy == Policy::TU && HasPassthruOp) {
987  // NF > 1 cases for segment load operations.
988  // Convert
989  // (void, op0 address, op1 address, ...)
990  // to
991  // (void, op0 address, op1 address, maskedoff0, maskedoff1, ...)
992  PrototypeDescriptor MaskoffType = Prototype[1];
993  MaskoffType.TM &= ~static_cast<uint8_t>(TypeModifier::Pointer);
994  for (unsigned I = 0; I < NF; ++I)
995  NewPrototype.insert(NewPrototype.begin() + NF + 1, MaskoffType);
996  }
997  }
998 
999  // If HasVL, append PrototypeDescriptor:VL to last operand
1000  if (HasVL)
1001  NewPrototype.push_back(PrototypeDescriptor::VL);
1002  return NewPrototype;
1003 }
1004 
1007  bool HasMaskPolicy) {
1008  if (HasTailPolicy && HasMaskPolicy)
1010  else if (HasTailPolicy)
1011  return {Policy::TUM, Policy::TAM};
1012  return {Policy::MA, Policy::MU};
1013 }
1014 
1015 void RVVIntrinsic::updateNamesAndPolicy(bool IsMasked, bool HasPolicy,
1016  bool IsPrototypeDefaultTU,
1017  std::string &Name,
1018  std::string &BuiltinName,
1019  std::string &OverloadedName,
1020  Policy &DefaultPolicy) {
1021 
1022  auto appendPolicySuffix = [&](const std::string &suffix) {
1023  Name += suffix;
1024  BuiltinName += suffix;
1025  OverloadedName += suffix;
1026  };
1027 
1028  switch (DefaultPolicy) {
1029  case Policy::TU:
1030  appendPolicySuffix("_tu");
1031  break;
1032  case Policy::TA:
1033  appendPolicySuffix("_ta");
1034  break;
1035  case Policy::MU:
1036  appendPolicySuffix("_mu");
1037  DefaultPolicy = Policy::TAMU;
1038  break;
1039  case Policy::MA:
1040  appendPolicySuffix("_ma");
1041  DefaultPolicy = Policy::TAMA;
1042  break;
1043  case Policy::TUM:
1044  appendPolicySuffix("_tum");
1045  DefaultPolicy = Policy::TUMA;
1046  break;
1047  case Policy::TAM:
1048  appendPolicySuffix("_tam");
1049  DefaultPolicy = Policy::TAMA;
1050  break;
1051  case Policy::TUMU:
1052  appendPolicySuffix("_tumu");
1053  break;
1054  case Policy::TAMU:
1055  appendPolicySuffix("_tamu");
1056  break;
1057  case Policy::TUMA:
1058  appendPolicySuffix("_tuma");
1059  break;
1060  case Policy::TAMA:
1061  appendPolicySuffix("_tama");
1062  break;
1063  default:
1064  if (IsMasked) {
1065  Name += "_m";
1066  // FIXME: Currently _m default policy implementation is different with
1067  // RVV intrinsic spec (TUMA)
1068  DefaultPolicy = Policy::TUMU;
1069  if (HasPolicy)
1070  BuiltinName += "_tumu";
1071  else
1072  BuiltinName += "_m";
1073  } else if (IsPrototypeDefaultTU) {
1074  DefaultPolicy = Policy::TU;
1075  if (HasPolicy)
1076  BuiltinName += "_tu";
1077  } else {
1078  DefaultPolicy = Policy::TA;
1079  if (HasPolicy)
1080  BuiltinName += "_ta";
1081  }
1082  }
1083 }
1084 
1086  SmallVector<PrototypeDescriptor> PrototypeDescriptors;
1087  const StringRef Primaries("evwqom0ztul");
1088  while (!Prototypes.empty()) {
1089  size_t Idx = 0;
1090  // Skip over complex prototype because it could contain primitive type
1091  // character.
1092  if (Prototypes[0] == '(')
1093  Idx = Prototypes.find_first_of(')');
1094  Idx = Prototypes.find_first_of(Primaries, Idx);
1095  assert(Idx != StringRef::npos);
1097  Prototypes.slice(0, Idx + 1));
1098  if (!PD)
1099  llvm_unreachable("Error during parsing prototype.");
1100  PrototypeDescriptors.push_back(*PD);
1101  Prototypes = Prototypes.drop_front(Idx + 1);
1102  }
1103  return PrototypeDescriptors;
1104 }
1105 
1106 raw_ostream &operator<<(raw_ostream &OS, const RVVIntrinsicRecord &Record) {
1107  OS << "{";
1108  OS << "\"" << Record.Name << "\",";
1109  if (Record.OverloadedName == nullptr ||
1110  StringRef(Record.OverloadedName).empty())
1111  OS << "nullptr,";
1112  else
1113  OS << "\"" << Record.OverloadedName << "\",";
1114  OS << Record.PrototypeIndex << ",";
1115  OS << Record.SuffixIndex << ",";
1116  OS << Record.OverloadedSuffixIndex << ",";
1117  OS << (int)Record.PrototypeLength << ",";
1118  OS << (int)Record.SuffixLength << ",";
1119  OS << (int)Record.OverloadedSuffixSize << ",";
1120  OS << (int)Record.RequiredExtensions << ",";
1121  OS << (int)Record.TypeRangeMask << ",";
1122  OS << (int)Record.Log2LMULMask << ",";
1123  OS << (int)Record.NF << ",";
1124  OS << (int)Record.HasMasked << ",";
1125  OS << (int)Record.HasVL << ",";
1126  OS << (int)Record.HasMaskedOffOperand << ",";
1127  OS << (int)Record.IsPrototypeDefaultTU << ",";
1128  OS << (int)Record.HasTailPolicy << ",";
1129  OS << (int)Record.HasMaskPolicy << ",";
1130  OS << (int)Record.UnMaskedPolicyScheme << ",";
1131  OS << (int)Record.MaskedPolicyScheme << ",";
1132  OS << "},\n";
1133  return OS;
1134 }
1135 
1136 } // end namespace RISCV
1137 } // end namespace clang
clang::RISCV::TypeModifier::NoModifier
@ NoModifier
clang::RISCV::VectorTypeModifier::SFixedLog2LMUL2
@ SFixedLog2LMUL2
clang::RISCV::PrototypeDescriptor
Definition: RISCVVIntrinsicUtils.h:112
clang::RISCV::Size_t
@ Size_t
Definition: RISCVVIntrinsicUtils.h:163
clang::RISCV::MA
@ MA
Definition: RISCVVIntrinsicUtils.h:104
llvm
YAML serialization mapping.
Definition: Dominators.h:30
clang::RISCV::TypeModifier::LMUL1
@ LMUL1
clang::RISCV::LMULType::str
std::string str() const
Definition: RISCVVIntrinsicUtils.cpp:42
clang::RISCV::LMULType
Definition: RISCVVIntrinsicUtils.h:175
clang::RISCV::RVVType::getBuiltinStr
const std::string & getBuiltinStr() const
Definition: RISCVVIntrinsicUtils.h:217
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::RISCV::VectorTypeModifier::FixedSEW64
@ FixedSEW64
clang::RISCV::TUMU
@ TUMU
Definition: RISCVVIntrinsicUtils.h:101
clang::RISCV::VectorTypeModifier::SFixedLog2LMULN3
@ SFixedLog2LMULN3
clang::RISCV::TypeModifier::Immediate
@ Immediate
clang::RISCV::RVVIntrinsicRecord::OverloadedSuffixSize
uint8_t OverloadedSuffixSize
Definition: RISCVVIntrinsicUtils.h:443
clang::RISCV::MU
@ MU
Definition: RISCVVIntrinsicUtils.h:103
clang::RISCV::Boolean
@ Boolean
Definition: RISCVVIntrinsicUtils.h:167
clang::RISCV::SignedLong
@ SignedLong
Definition: RISCVVIntrinsicUtils.h:166
clang::RISCV::RVVIntrinsicRecord::OverloadedSuffixIndex
uint16_t OverloadedSuffixIndex
Definition: RISCVVIntrinsicUtils.h:434
clang::RISCV::TU
@ TU
Definition: RISCVVIntrinsicUtils.h:97
llvm::SmallVector
Definition: LLVM.h:38
clang::RISCV::VectorTypeModifier::LFixedLog2LMUL1
@ LFixedLog2LMUL1
clang::RISCV::RVVIntrinsicRecord::HasVL
bool HasVL
Definition: RISCVVIntrinsicUtils.h:458
clang::RISCV::UnsignedLong
@ UnsignedLong
clang::RISCV::HasPassthruOperand
@ HasPassthruOperand
Definition: RISCVVIntrinsicUtils.h:306
clang::RISCV::PrototypeDescriptor::VL
static const PrototypeDescriptor VL
Definition: RISCVVIntrinsicUtils.h:138
clang::RISCV::RVVIntrinsicRecord::HasMasked
bool HasMasked
Definition: RISCVVIntrinsicUtils.h:457
clang::RISCV::BasicType::Float16
@ Float16
clang::RISCV::RVVIntrinsicRecord::PrototypeLength
uint8_t PrototypeLength
Definition: RISCVVIntrinsicUtils.h:437
clang::RISCV::RVVIntrinsic::updateNamesAndPolicy
static void updateNamesAndPolicy(bool IsMasked, bool HasPolicy, bool IsPrototypeDefaultTU, std::string &Name, std::string &BuiltinName, std::string &OverloadedName, Policy &DefaultPolicy)
Definition: RISCVVIntrinsicUtils.cpp:1015
clang::RISCV::RVVIntrinsic::getSuffixStr
static std::string getSuffixStr(RVVTypeCache &TypeCache, BasicType Type, int Log2LMUL, llvm::ArrayRef< PrototypeDescriptor > PrototypeDescriptors)
Definition: RISCVVIntrinsicUtils.cpp:898
clang::RISCV::HasPassthruOperandAtIdx1
@ HasPassthruOperandAtIdx1
Definition: RISCVVIntrinsicUtils.h:310
clang::RISCV::BaseTypeModifier::Ptrdiff
@ Ptrdiff
int
__device__ int
Definition: __clang_hip_libdevice_declares.h:63
clang::RISCV::PolicyScheme
PolicyScheme
Definition: RISCVVIntrinsicUtils.h:303
clang::RISCV::SignedInteger
@ SignedInteger
Definition: RISCVVIntrinsicUtils.h:168
clang::RISCV::VectorTypeModifier::SFixedLog2LMULN1
@ SFixedLog2LMULN1
llvm::Optional< unsigned >
clang::RISCV::VectorTypeModifier::LFixedLog2LMULN1
@ LFixedLog2LMULN1
clang::RISCV::RVVIntrinsic::getBuiltinTypeStr
std::string getBuiltinTypeStr() const
Definition: RISCVVIntrinsicUtils.cpp:889
clang::RISCV::RVVType::isScalar
bool isScalar() const
Definition: RISCVVIntrinsicUtils.h:237
clang::RISCV::VectorTypeModifier::LFixedLog2LMULN2
@ LFixedLog2LMULN2
clang::RISCV::RVVIntrinsicRecord::SuffixLength
uint8_t SuffixLength
Definition: RISCVVIntrinsicUtils.h:440
clang::RISCV::BasicType::Float32
@ Float32
clang::RISCV::VectorTypeModifier::LFixedLog2LMUL2
@ LFixedLog2LMUL2
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1565
clang::RISCV::VectorTypeModifier::Widening8XVector
@ Widening8XVector
clang::RISCV::RVVIntrinsicRecord::SuffixIndex
uint16_t SuffixIndex
Definition: RISCVVIntrinsicUtils.h:431
V
#define V(N, I)
Definition: ASTContext.h:3237
clang::RISCV::TypeModifier::Const
@ Const
clang::RISCV::BaseTypeModifier::SizeT
@ SizeT
clang::RISCV::RVVIntrinsicRecord::RequiredExtensions
uint8_t RequiredExtensions
Definition: RISCVVIntrinsicUtils.h:446
clang::RISCV::VectorTypeModifier::FixedSEW8
@ FixedSEW8
clang::RISCV::UnsignedLong
@ UnsignedLong
Definition: RISCVVIntrinsicUtils.h:165
clang::RISCV::LMULType::MulLog2LMUL
void MulLog2LMUL(int Log2LMUL)
Definition: RISCVVIntrinsicUtils.cpp:72
clang::RISCV::VectorTypeModifier::Widening2XVector
@ Widening2XVector
clang::RISCV::VectorTypeModifier::Log2EEW4
@ Log2EEW4
clang::RISCV::TAM
@ TAM
Definition: RISCVVIntrinsicUtils.h:106
hlsl::uint64_t
unsigned long uint64_t
Definition: hlsl_basic_types.h:25
clang::RISCV::RVVIntrinsicRecord::HasMaskPolicy
bool HasMaskPolicy
Definition: RISCVVIntrinsicUtils.h:462
clang::RISCV::Invalid
@ Invalid
clang::RISCV::Ptrdiff_t
@ Ptrdiff_t
Definition: RISCVVIntrinsicUtils.h:164
clang::RISCV::VectorTypeModifier::SFixedLog2LMUL3
@ SFixedLog2LMUL3
clang::RISCV::VectorTypeModifier::SFixedLog2LMULN2
@ SFixedLog2LMULN2
clang::RISCV::RVVIntrinsicRecord::NF
uint8_t NF
Definition: RISCVVIntrinsicUtils.h:455
clang::RISCV::VectorTypeModifier::Log2EEW6
@ Log2EEW6
clang::RISCV::PrototypeDescriptor::PT
uint8_t PT
Definition: RISCVVIntrinsicUtils.h:123
clang::RISCV::Policy
Policy
Definition: RISCVVIntrinsicUtils.h:96
clang::RISCV::PolicyNone
@ PolicyNone
Definition: RISCVVIntrinsicUtils.h:107
clang::RISCV::computeRVVTypeHashValue
static uint64_t computeRVVTypeHashValue(BasicType BT, int Log2LMUL, PrototypeDescriptor Proto)
Definition: RISCVVIntrinsicUtils.cpp:805
clang::RISCV::RVVType
Definition: RISCVVIntrinsicUtils.h:190
RISCVVIntrinsicUtils.h
clang::RISCV::BaseTypeModifier
BaseTypeModifier
Definition: RISCVVIntrinsicUtils.h:65
clang::RISCV::RVVType::isFloat
bool isFloat() const
Definition: RISCVVIntrinsicUtils.h:242
clang::RISCV::BasicType::Int8
@ Int8
clang::RISCV::TypeModifier
TypeModifier
Definition: RISCVVIntrinsicUtils.h:77
clang::RISCV::PrototypeDescriptor::parsePrototypeDescriptor
static llvm::Optional< PrototypeDescriptor > parsePrototypeDescriptor(llvm::StringRef PrototypeStr)
Definition: RISCVVIntrinsicUtils.cpp:365
clang::RISCV::BaseTypeModifier::Scalar
@ Scalar
clang::RISCV::RVVIntrinsic::hasPolicy
bool hasPolicy() const
Definition: RISCVVIntrinsicUtils.h:357
clang::RISCV::PrototypeDescriptor::Mask
static const PrototypeDescriptor Mask
Definition: RISCVVIntrinsicUtils.h:136
clang::RISCV::BaseTypeModifier::Vector
@ Vector
clang::RISCV::SignedLong
@ SignedLong
clang::RISCV::RVVIntrinsicRecord::MaskedPolicyScheme
uint8_t MaskedPolicyScheme
Definition: RISCVVIntrinsicUtils.h:464
clang::RISCV::PrototypeDescriptor::VTM
uint8_t VTM
Definition: RISCVVIntrinsicUtils.h:124
clang::RISCV::RVVIntrinsicRecord::TypeRangeMask
uint8_t TypeRangeMask
Definition: RISCVVIntrinsicUtils.h:449
clang::RISCV::operator<<
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const RVVIntrinsicRecord &RVVInstrRecord)
clang::RISCV::RVVIntrinsicRecord
Definition: RISCVVIntrinsicUtils.h:419
clang::RISCV::VectorTypeModifier::NoModifier
@ NoModifier
clang::RISCV::TA
@ TA
Definition: RISCVVIntrinsicUtils.h:98
clang::RISCV::RVVTypeCache::computeType
llvm::Optional< RVVTypePtr > computeType(BasicType BT, int Log2LMUL, PrototypeDescriptor Proto)
Definition: RISCVVIntrinsicUtils.cpp:817
clang::RISCV::VectorTypeModifier::Widening4XVector
@ Widening4XVector
clang::RISCV::RVVTypes
std::vector< RVVTypePtr > RVVTypes
Definition: RISCVVIntrinsicUtils.h:186
clang::ComplexType
Complex values, per C99 6.2.5p11.
Definition: Type.h:2716
clang::RISCV::RVVType::isSignedInteger
bool isSignedInteger() const
Definition: RISCVVIntrinsicUtils.h:243
clang::RISCV::RVVIntrinsic::hasMaskedOffOperand
bool hasMaskedOffOperand() const
Definition: RISCVVIntrinsicUtils.h:355
llvm::ArrayRef
Definition: LLVM.h:34
clang::RISCV::RVVIntrinsicRecord::HasMaskedOffOperand
bool HasMaskedOffOperand
Definition: RISCVVIntrinsicUtils.h:459
clang::RISCV::Float
@ Float
Definition: RISCVVIntrinsicUtils.h:170
clang::RISCV::TUMA
@ TUMA
Definition: RISCVVIntrinsicUtils.h:99
clang::RISCV::BasicType::Int16
@ Int16
clang::RISCV::VectorTypeModifier::SFixedLog2LMUL0
@ SFixedLog2LMUL0
clang::RISCV::RVVTypeCache::computeTypes
llvm::Optional< RVVTypes > computeTypes(BasicType BT, int Log2LMUL, unsigned NF, llvm::ArrayRef< PrototypeDescriptor > Prototype)
Compute output and input types by applying different config (basic type and LMUL with type transforme...
Definition: RISCVVIntrinsicUtils.cpp:787
clang::RISCV::RVVIntrinsic::computeBuiltinTypes
static llvm::SmallVector< PrototypeDescriptor > computeBuiltinTypes(llvm::ArrayRef< PrototypeDescriptor > Prototype, bool IsMasked, bool HasMaskedOffOperand, bool HasVL, unsigned NF, bool IsPrototypeDefaultTU, PolicyScheme DefaultScheme, Policy DefaultPolicy=Policy::PolicyNone)
Definition: RISCVVIntrinsicUtils.cpp:909
clang::RISCV::RVVIntrinsicRecord::Name
const char * Name
Definition: RISCVVIntrinsicUtils.h:421
clang::DeclaratorContext::Prototype
@ Prototype
clang::RISCV::UnsignedInteger
@ UnsignedInteger
Definition: RISCVVIntrinsicUtils.h:169
clang::RISCV::VectorTypeModifier::LFixedLog2LMULN3
@ LFixedLog2LMULN3
clang::RISCV::RVVIntrinsicRecord::UnMaskedPolicyScheme
uint8_t UnMaskedPolicyScheme
Definition: RISCVVIntrinsicUtils.h:463
clang::RISCV::RVVType::isValid
bool isValid() const
Definition: RISCVVIntrinsicUtils.h:236
clang::RISCV::TAMA
@ TAMA
Definition: RISCVVIntrinsicUtils.h:100
clang::RISCV::RVVTypeCache
Definition: RISCVVIntrinsicUtils.h:286
clang::RISCV::RVVIntrinsic::getSupportedMaskedPolicies
static llvm::SmallVector< Policy > getSupportedMaskedPolicies(bool HasTailPolicy, bool HasMaskPolicy)
Definition: RISCVVIntrinsicUtils.cpp:1006
clang::RISCV::VectorTypeModifier::LFixedLog2LMUL0
@ LFixedLog2LMUL0
clang::RISCV::VectorTypeModifier::Log2EEW3
@ Log2EEW3
clang::RISCV::BasicType::Float64
@ Float64
clang::RISCV::RVVType::isVector
bool isVector() const
Definition: RISCVVIntrinsicUtils.h:238
clang::RISCV::VectorTypeModifier::SFixedLog2LMUL1
@ SFixedLog2LMUL1
clang
Definition: CalledOnceCheck.h:17
getTypeString
static bool getTypeString(SmallStringEnc &Enc, const Decl *D, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)
The XCore ABI includes a type information section that communicates symbol type information to the li...
Definition: TargetInfo.cpp:10816
clang::RISCV::VectorTypeModifier::LFixedLog2LMUL3
@ LFixedLog2LMUL3
clang::RISCV::TAMU
@ TAMU
Definition: RISCVVIntrinsicUtils.h:102
clang::RISCV::VectorTypeModifier::Log2EEW5
@ Log2EEW5
clang::RISCV::BasicType::Int64
@ Int64
clang::RISCV::TUM
@ TUM
Definition: RISCVVIntrinsicUtils.h:105
clang::RISCV::RVVIntrinsic::hasPassthruOperand
bool hasPassthruOperand() const
Definition: RISCVVIntrinsicUtils.h:358
clang::RISCV::RVVIntrinsic::RVVIntrinsic
RVVIntrinsic(llvm::StringRef Name, llvm::StringRef Suffix, llvm::StringRef OverloadedName, llvm::StringRef OverloadedSuffix, llvm::StringRef IRName, bool IsMasked, bool HasMaskedOffOperand, bool HasVL, PolicyScheme Scheme, bool SupportOverloading, bool HasBuiltinAlias, llvm::StringRef ManualCodegen, const RVVTypes &Types, const std::vector< int64_t > &IntrinsicTypes, const std::vector< llvm::StringRef > &RequiredFeatures, unsigned NF, Policy DefaultPolicy, bool IsPrototypeDefaultTU)
Definition: RISCVVIntrinsicUtils.cpp:844
clang::RISCV::BasicType
BasicType
Definition: RISCVVIntrinsicUtils.h:147
clang::RISCV::Float
@ Float
clang::RISCV::TypeModifier::Pointer
@ Pointer
clang::RISCV::PrototypeDescriptor::TM
uint8_t TM
Definition: RISCVVIntrinsicUtils.h:125
clang::RISCV::VectorTypeModifier::MaskVector
@ MaskVector
isVector
static bool isVector(QualType QT, QualType ElementType)
This helper function returns true if QT is a vector type that has element type ElementType.
Definition: SemaExpr.cpp:9493
clang::RISCV::parsePrototypes
llvm::SmallVector< PrototypeDescriptor > parsePrototypes(llvm::StringRef Prototypes)
clang::RISCV::RVVIntrinsicRecord::IsPrototypeDefaultTU
bool IsPrototypeDefaultTU
Definition: RISCVVIntrinsicUtils.h:460
clang::RISCV::RVVIntrinsicRecord::Log2LMULMask
uint8_t Log2LMULMask
Definition: RISCVVIntrinsicUtils.h:452
clang::RISCV::VectorTypeModifier
VectorTypeModifier
Definition: RISCVVIntrinsicUtils.h:33
clang::RISCV::RVVIntrinsicRecord::PrototypeIndex
uint16_t PrototypeIndex
Definition: RISCVVIntrinsicUtils.h:428
clang::RISCV::Invalid
@ Invalid
Definition: RISCVVIntrinsicUtils.h:171
clang::RISCV::VectorTypeModifier::FixedSEW32
@ FixedSEW32
clang::RISCV::VectorTypeModifier::FixedSEW16
@ FixedSEW16
clang::RISCV::RVVIntrinsicRecord::HasTailPolicy
bool HasTailPolicy
Definition: RISCVVIntrinsicUtils.h:461
clang::RISCV::LMULType::getScale
llvm::Optional< unsigned > getScale(unsigned ElementBitwidth) const
Definition: RISCVVIntrinsicUtils.cpp:48
clang::RISCV::TypeModifier::MaxOffset
@ MaxOffset
clang::RISCV::LMULType::Log2LMUL
int Log2LMUL
Definition: RISCVVIntrinsicUtils.h:176
clang::RISCV::BasicType::Int32
@ Int32
clang::RISCV::RVVIntrinsicRecord::OverloadedName
const char * OverloadedName
Definition: RISCVVIntrinsicUtils.h:425