clang: lib/CodeGen/TargetBuiltins/RISCV.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
15#include "llvm/IR/IntrinsicsRISCV.h"
16#include "llvm/TargetParser/RISCVISAInfo.h"
17#include "llvm/TargetParser/RISCVTargetParser.h"
18
19using namespace clang;
21using namespace llvm;
22
23
24
25static constexpr unsigned RVV_VTA = 0x1;
26static constexpr unsigned RVV_VMA = 0x2;
27
28
29
30
31static LLVM_ATTRIBUTE_NOINLINE Value *
35 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
36 auto &Builder = CGF->Builder;
37 auto &CGM = CGF->CGM;
39 if (IsMasked) {
40
41 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
42 if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
43 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
44 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
45 IntrinsicTypes = {ResultType, Ops[4]->getType(), Ops[2]->getType()};
46 } else {
47 if (PolicyAttrs & RVV_VTA)
48 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
49 IntrinsicTypes = {ResultType, Ops[3]->getType(), Ops[1]->getType()};
50 }
51 Value *NewVL = Ops[2];
52 Ops.erase(Ops.begin() + 2);
53 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
54 llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
55 llvm::Value *V = Builder.CreateExtractValue(LoadValue, {0});
56
58 if (IsMasked)
59 Align = CGM.getNaturalPointeeTypeAlignment(
61 else
62 Align = CGM.getNaturalPointeeTypeAlignment(E->getArg(1)->getType());
63 llvm::Value *Val = Builder.CreateExtractValue(LoadValue, {1});
64 Builder.CreateStore(Val, Address(NewVL, Val->getType(), Align));
65 return V;
66}
67
68static LLVM_ATTRIBUTE_NOINLINE Value *
72 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
73 auto &Builder = CGF->Builder;
74 auto &CGM = CGF->CGM;
76 if (IsMasked) {
77
78
79 std::swap(Ops[0], Ops[3]);
80 } else {
81
82 std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
83 }
84 if (IsMasked)
85 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[4]->getType()};
86 else
87 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[3]->getType()};
88 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
89 return Builder.CreateCall(F, Ops, "");
90}
91
95 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
96 auto &Builder = CGF->Builder;
97 auto &CGM = CGF->CGM;
99 if (IsMasked) {
100
101
102 std::swap(Ops[0], Ops[3]);
103 } else {
104
105
106 std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
107 }
108 if (IsMasked)
109 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(),
110 Ops[4]->getType()};
111 else
112 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(),
113 Ops[3]->getType()};
114 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
115 return Builder.CreateCall(F, Ops, "");
116}
117
118static LLVM_ATTRIBUTE_NOINLINE Value *
122 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
123 auto &Builder = CGF->Builder;
124 auto &CGM = CGF->CGM;
126 if (IsMasked) {
127 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
128 if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
129 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
130 } else {
131 if (PolicyAttrs & RVV_VTA)
132 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
133 }
135 Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(ElemTy));
136 if (IsMasked) {
137 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
138
139 IntrinsicTypes = {ResultType, ElemTy, Ops[4]->getType()};
140 } else {
141
142 IntrinsicTypes = {ResultType, ElemTy, Ops[3]->getType()};
143 }
144 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
145 return Builder.CreateCall(F, Ops, "");
146}
147
148static LLVM_ATTRIBUTE_NOINLINE Value *
152 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
153 auto &Builder = CGF->Builder;
154 auto &CGM = CGF->CGM;
156 if (IsMasked) {
157 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
158 if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
159 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
160 } else {
161 if (PolicyAttrs & RVV_VTA)
162 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
163 }
165 Ops.insert(Ops.begin() + 2, llvm::Constant::getAllOnesValue(ElemTy));
166 if (IsMasked) {
167 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
168
169 IntrinsicTypes = {ResultType, ElemTy, Ops[4]->getType()};
170 } else {
171
172 IntrinsicTypes = {ResultType, ElemTy, Ops[3]->getType()};
173 }
174 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
175 return Builder.CreateCall(F, Ops, "");
176}
177
178static LLVM_ATTRIBUTE_NOINLINE Value *
182 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
183 auto &Builder = CGF->Builder;
184 auto &CGM = CGF->CGM;
186
187 IntrinsicTypes = {ResultType, Ops[1]->getType()};
188 Ops.insert(Ops.begin() + 1, Ops[0]);
189 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
190 return Builder.CreateCall(F, Ops, "");
191}
192
196 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
197 auto &Builder = CGF->Builder;
198 auto &CGM = CGF->CGM;
200 if (IsMasked) {
201 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
202 if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
203 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
204 Ops.insert(Ops.begin() + 2, Ops[1]);
205 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
206
207 IntrinsicTypes = {ResultType, Ops[2]->getType(), Ops.back()->getType()};
208 } else {
209 if (PolicyAttrs & RVV_VTA)
210 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
211
212 IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[2]->getType()};
213 Ops.insert(Ops.begin() + 2, Ops[1]);
214 }
215 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
216 return Builder.CreateCall(F, Ops, "");
217}
218
219static LLVM_ATTRIBUTE_NOINLINE Value *
223 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
224 auto &Builder = CGF->Builder;
225 auto &CGM = CGF->CGM;
227 if (IsMasked) {
228 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
229 if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
230 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
231 } else {
232 if (PolicyAttrs & RVV_VTA)
233 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
234 }
236 Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(ElemTy));
237 if (IsMasked) {
238 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
239
240 IntrinsicTypes = {ResultType, Ops[1]->getType(), ElemTy, Ops[4]->getType()};
241 } else {
242
243 IntrinsicTypes = {ResultType, Ops[1]->getType(), ElemTy, Ops[3]->getType()};
244 }
245 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
246 return Builder.CreateCall(F, Ops, "");
247}
248
249static LLVM_ATTRIBUTE_NOINLINE Value *
253 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
254 auto &Builder = CGF->Builder;
255 auto &CGM = CGF->CGM;
257 if (IsMasked) {
258 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
259 if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
260 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
261 } else {
262 if (PolicyAttrs & RVV_VTA)
263 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
264 }
265 Ops.insert(Ops.begin() + 2,
266 llvm::Constant::getNullValue(Ops.back()->getType()));
267 if (IsMasked) {
268 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
269
270 IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[4]->getType(),
271 Ops[4]->getType()};
272 } else {
273
274 IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[3]->getType(),
275 Ops[3]->getType()};
276 }
277 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
278 return Builder.CreateCall(F, Ops, "");
279}
280
281static LLVM_ATTRIBUTE_NOINLINE Value *
285 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
286 auto &Builder = CGF->Builder;
287 auto &CGM = CGF->CGM;
289 llvm::MDBuilder MDHelper(Context);
290 llvm::Metadata *OpsMD[] = {llvm::MDString::get(Context, "vlenb")};
291 llvm::MDNode *RegName = llvm::MDNode::get(Context, OpsMD);
292 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
293 llvm::Function *F =
294 CGM.getIntrinsic(llvm::Intrinsic::read_register, {CGF->SizeTy});
295 return Builder.CreateCall(F, Metadata);
296}
297
298static LLVM_ATTRIBUTE_NOINLINE Value *
302 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
303 auto &Builder = CGF->Builder;
304 auto &CGM = CGF->CGM;
305 llvm::Function *F = CGM.getIntrinsic(ID, {ResultType});
306 return Builder.CreateCall(F, Ops, "");
307}
308
309static LLVM_ATTRIBUTE_NOINLINE Value *
313 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
314 auto &Builder = CGF->Builder;
315 auto &CGM = CGF->CGM;
317 if (IsMasked) {
318
319
320 std::swap(Ops[0], Ops[2]);
321 } else {
322
323
324 std::swap(Ops[0], Ops[1]);
325 }
326 if (IsMasked)
327 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[3]->getType()};
328 else
329 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType()};
330 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
331 return Builder.CreateCall(F, Ops, "");
332}
333
337 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
338 auto &Builder = CGF->Builder;
339 auto &CGM = CGF->CGM;
341 bool NoPassthru =
342 (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |
343 (!IsMasked && (PolicyAttrs & RVV_VTA));
344 unsigned Offset = IsMasked ? NoPassthru ? 1 : 2 : NoPassthru ? 0 : 1;
345 if (IsMasked)
346 IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Ops[0]->getType(),
347 Ops.back()->getType()};
348 else
349 IntrinsicTypes = {ResultType, Ops[Offset]->getType(),
350 Ops.back()->getType()};
351 if (IsMasked)
352 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
353 if (NoPassthru)
354 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
355 if (IsMasked)
356 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
357 Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
358 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
359 llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
360 if (ReturnValue.isNull())
361 return LoadValue;
362 return Builder.CreateStore(LoadValue, ReturnValue.getValue());
363}
364
368 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
369 auto &Builder = CGF->Builder;
370 auto &CGM = CGF->CGM;
372
373
374
375
376
377
378 if (IsMasked)
379 std::swap(Ops[0], Ops[2]);
380 else
381 std::swap(Ops[0], Ops[1]);
382 Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
383 if (IsMasked)
384 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(),
385 Ops[3]->getType()};
386 else
387 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType()};
388 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
389 return Builder.CreateCall(F, Ops, "");
390}
391
395 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
396 auto &Builder = CGF->Builder;
397 auto &CGM = CGF->CGM;
399 bool NoPassthru =
400 (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |
401 (!IsMasked && (PolicyAttrs & RVV_VTA));
402 unsigned Offset = IsMasked ? NoPassthru ? 1 : 2 : NoPassthru ? 0 : 1;
403 if (IsMasked)
404 IntrinsicTypes = {ResultType, Ops.back()->getType(), Ops[Offset]->getType(),
405 Ops[0]->getType()};
406 else
407 IntrinsicTypes = {ResultType, Ops.back()->getType(),
408 Ops[Offset]->getType()};
409 if (IsMasked)
410 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
411 if (NoPassthru)
412 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
413 if (IsMasked)
414 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
415 Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
416 Value *NewVL = Ops[2];
417 Ops.erase(Ops.begin() + 2);
418 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
419 llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
420
422 CGM.getNaturalPointeeTypeAlignment(E->getArg(Offset + 1)->getType());
423 llvm::Value *ReturnTuple = Builder.CreateExtractValue(LoadValue, 0);
424
425 llvm::Value *V = Builder.CreateExtractValue(LoadValue, 1);
426 Builder.CreateStore(V, Address(NewVL, V->getType(), Align));
427 if (ReturnValue.isNull())
428 return ReturnTuple;
429 return Builder.CreateStore(ReturnTuple, ReturnValue.getValue());
430}
431
435 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
436 auto &Builder = CGF->Builder;
437 auto &CGM = CGF->CGM;
439 bool NoPassthru =
440 (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |
441 (!IsMasked && (PolicyAttrs & RVV_VTA));
442 unsigned Offset = IsMasked ? NoPassthru ? 1 : 2 : NoPassthru ? 0 : 1;
443 if (IsMasked)
444 IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Ops.back()->getType(),
445 Ops[0]->getType()};
446 else
447 IntrinsicTypes = {ResultType, Ops[Offset]->getType(),
448 Ops.back()->getType()};
449 if (IsMasked)
450 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
451 if (NoPassthru)
452 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
453 if (IsMasked)
454 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
455 Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
456 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
457 llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
458 if (ReturnValue.isNull())
459 return LoadValue;
460 return Builder.CreateStore(LoadValue, ReturnValue.getValue());
461}
462
466 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
467 auto &Builder = CGF->Builder;
468 auto &CGM = CGF->CGM;
470
471
472
473
474
475
476 if (IsMasked)
477 std::swap(Ops[0], Ops[3]);
478 else
479 std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
480 Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
481 if (IsMasked)
482 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[4]->getType(),
483 Ops[3]->getType()};
484 else
485 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[3]->getType()};
486 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
487 return Builder.CreateCall(F, Ops, "");
488}
489
490static LLVM_ATTRIBUTE_NOINLINE Value *
494 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
495 auto &Builder = CGF->Builder;
496 auto &CGM = CGF->CGM;
497
498
499
500
501
502 bool HasMaskedOff =
503 !((IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
504 (!IsMasked && PolicyAttrs & RVV_VTA));
505
506 if (IsMasked)
507 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);
508
509 if (!HasMaskedOff)
510 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
511
512 if (IsMasked)
513 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
514
515 llvm::Function *F = CGM.getIntrinsic(
516 ID, {ResultType, Ops[2]->getType(), Ops.back()->getType()});
517 return Builder.CreateCall(F, Ops, "");
518}
519
523 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
524 auto &Builder = CGF->Builder;
525 auto &CGM = CGF->CGM;
526
527
528
529
530
531 bool HasMaskedOff =
532 !((IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
533 (!IsMasked && PolicyAttrs & RVV_VTA));
534
535 if (IsMasked)
536 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);
537
538 if (!HasMaskedOff)
539 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
540
541 if (IsMasked)
542 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
543
544 llvm::Function *F =
545 CGM.getIntrinsic(ID, {ResultType, Ops[1]->getType(), Ops[2]->getType(),
546 Ops.back()->getType()});
547 return Builder.CreateCall(F, Ops, "");
548}
549
553 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
554 auto &Builder = CGF->Builder;
555 auto &CGM = CGF->CGM;
556
557
558
559
560 bool HasMaskedOff =
561 !((IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
562 (!IsMasked && PolicyAttrs & RVV_VTA));
563 bool HasRoundModeOp =
564 IsMasked ? (HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5)
565 : (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4);
566
567 if (!HasRoundModeOp)
568 Ops.insert(Ops.end() - 1,
569 ConstantInt::get(Ops.back()->getType(), 7));
570
571 if (IsMasked)
572 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);
573
574 if (!HasMaskedOff)
575 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
576
577 if (IsMasked)
578 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
579
580 llvm::Function *F = CGM.getIntrinsic(
581 ID, {ResultType, Ops[2]->getType(), Ops.back()->getType()});
582 return Builder.CreateCall(F, Ops, "");
583}
584
588 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
589 auto &Builder = CGF->Builder;
590 auto &CGM = CGF->CGM;
591
592
593
594
595 bool HasMaskedOff =
596 !((IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
597 (!IsMasked && PolicyAttrs & RVV_VTA));
598 bool HasRoundModeOp =
599 IsMasked ? (HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5)
600 : (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4);
601
602 if (!HasRoundModeOp)
603 Ops.insert(Ops.end() - 1,
604 ConstantInt::get(Ops.back()->getType(), 7));
605
606 if (IsMasked)
607 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);
608
609 if (!HasMaskedOff)
610 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
611
612 if (IsMasked)
613 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
614
615 llvm::Function *F =
616 CGM.getIntrinsic(ID, {ResultType, Ops[1]->getType(), Ops[2]->getType(),
617 Ops.back()->getType()});
618 return Builder.CreateCall(F, Ops, "");
619}
620
624 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
625 auto &Builder = CGF->Builder;
626 auto &CGM = CGF->CGM;
628
629 bool NoPassthru =
630 (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |
631 (!IsMasked && (PolicyAttrs & RVV_VTA));
632
633 if (IsMasked)
634 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
635 if (NoPassthru)
636 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
637
638 if (IsMasked)
639 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
640 Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
641
642 if (IsMasked)
643 IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[2]->getType(),
644 Ops[3]->getType(), Ops[4]->getType()};
645 else
646 IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[2]->getType(),
647 Ops[3]->getType()};
648 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
649 llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
650
651 if (ReturnValue.isNull())
652 return LoadValue;
653 return Builder.CreateStore(LoadValue, ReturnValue.getValue());
654}
655
659 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
660 auto &Builder = CGF->Builder;
661 auto &CGM = CGF->CGM;
663
664
665
666
667
668
669
670 if (IsMasked)
671 std::swap(Ops[0], Ops[3]);
672 else
673 std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
674
675 Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
676
677 if (IsMasked)
678 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(),
679 Ops[3]->getType(), Ops[4]->getType()};
680 else
681 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(),
682 Ops[3]->getType()};
683 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
684 return Builder.CreateCall(F, Ops, "");
685}
686
687static LLVM_ATTRIBUTE_NOINLINE Value *
691 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
692 auto &Builder = CGF->Builder;
693 auto &CGM = CGF->CGM;
694
695
696
697
698
699
700 bool HasRoundModeOp = IsMasked ? Ops.size() == 6 : Ops.size() == 5;
701
702 if (!HasRoundModeOp)
703 Ops.insert(Ops.end() - 1,
704 ConstantInt::get(Ops.back()->getType(), 7));
705
706 if (IsMasked)
707 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);
708
709 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
710
711 llvm::Function *F = CGM.getIntrinsic(
712 ID, {ResultType, Ops[1]->getType(), Ops.back()->getType()});
713 return Builder.CreateCall(F, Ops, "");
714}
715
716static LLVM_ATTRIBUTE_NOINLINE Value *
720 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
721 auto &Builder = CGF->Builder;
722 auto &CGM = CGF->CGM;
723
724
725
726
727
728 bool HasRoundModeOp = IsMasked ? Ops.size() == 6 : Ops.size() == 5;
729
730 if (!HasRoundModeOp)
731 Ops.insert(Ops.end() - 1,
732 ConstantInt::get(Ops.back()->getType(), 7));
733
734 if (IsMasked)
735 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.begin() + 4);
736
737 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
738
739 llvm::Function *F =
740 CGM.getIntrinsic(ID, {ResultType, Ops[1]->getType(), Ops[2]->getType(),
741 Ops.back()->getType()});
742 return Builder.CreateCall(F, Ops, "");
743}
744
748 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
749 auto &Builder = CGF->Builder;
750 auto &CGM = CGF->CGM;
752
753
754
755
756 bool HasMaskedOff =
757 !((IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
758 (!IsMasked && PolicyAttrs & RVV_VTA));
759 bool HasRoundModeOp =
760 IsMasked ? (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4)
761 : (HasMaskedOff ? Ops.size() == 4 : Ops.size() == 3);
762
763 if (!HasRoundModeOp)
764 Ops.insert(Ops.end() - 1,
765 ConstantInt::get(Ops.back()->getType(), 7));
766
767 if (IsMasked)
768 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);
769
770 if (!HasMaskedOff)
771 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
772
773 if (IsMasked)
774 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
775
776 IntrinsicTypes = {ResultType, Ops.back()->getType()};
777 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
778 return Builder.CreateCall(F, Ops, "");
779}
780
784 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
785 auto &Builder = CGF->Builder;
786 auto &CGM = CGF->CGM;
787
788
789
790 bool HasMaskedOff =
791 !((IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
792 (!IsMasked && PolicyAttrs & RVV_VTA));
793 bool HasRoundModeOp =
794 IsMasked ? (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4)
795 : (HasMaskedOff ? Ops.size() == 4 : Ops.size() == 3);
796
797 if (!HasRoundModeOp)
798 Ops.insert(Ops.end() - 1,
799 ConstantInt::get(Ops.back()->getType(), 7));
800
801 if (IsMasked)
802 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);
803
804 if (!HasMaskedOff)
805 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
806
807 if (IsMasked)
808 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
809
810 llvm::Function *F = CGM.getIntrinsic(
811 ID, {ResultType, Ops[1]->getType(), Ops.back()->getType()});
812 return Builder.CreateCall(F, Ops, "");
813}
814
818 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
819 auto &Builder = CGF->Builder;
820 auto &CGM = CGF->CGM;
821
822
823
824
825 bool HasMaskedOff =
826 !((IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
827 (!IsMasked && PolicyAttrs & RVV_VTA));
828 bool HasRoundModeOp =
829 IsMasked ? (HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5)
830 : (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4);
831
832 if (!HasRoundModeOp)
833 Ops.insert(Ops.end() - 1,
834 ConstantInt::get(Ops.back()->getType(), 7));
835
836 if (IsMasked)
837 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);
838
839 if (!HasMaskedOff)
840 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
841
842 llvm::Function *F = CGM.getIntrinsic(
843 ID, {ResultType, Ops[1]->getType(), Ops.back()->getType()});
844 return Builder.CreateCall(F, Ops, "");
845}
846
847static LLVM_ATTRIBUTE_NOINLINE Value *
851 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
852 auto &Builder = CGF->Builder;
853 auto &CGM = CGF->CGM;
854
855 if (ResultType->isIntOrIntVectorTy(1) ||
856 Ops[0]->getType()->isIntOrIntVectorTy(1)) {
859
860 LLVMContext &Context = CGM.getLLVMContext();
861 ScalableVectorType *Boolean64Ty =
862 ScalableVectorType::get(llvm::Type::getInt1Ty(Context), 64);
863
864 if (ResultType->isIntOrIntVectorTy(1)) {
865
866
867
868
869 llvm::Value *BitCast = Builder.CreateBitCast(Ops[0], Boolean64Ty);
870 return Builder.CreateExtractVector(ResultType, BitCast,
871 ConstantInt::get(CGF->Int64Ty, 0));
872 } else {
873
874
875
876
877 llvm::Value *Boolean64Val = Builder.CreateInsertVector(
878 Boolean64Ty, llvm::PoisonValue::get(Boolean64Ty), Ops[0],
879 ConstantInt::get(CGF->Int64Ty, 0));
880 return Builder.CreateBitCast(Boolean64Val, ResultType);
881 }
882 }
883 return Builder.CreateBitCast(Ops[0], ResultType);
884}
885
886static LLVM_ATTRIBUTE_NOINLINE Value *
890 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
891 auto &Builder = CGF->Builder;
893 if (auto *OpVecTy = dyn_cast(Ops[0]->getType())) {
894 unsigned MaxIndex =
895 OpVecTy->getMinNumElements() / VecTy->getMinNumElements();
896 assert(isPowerOf2_32(MaxIndex));
897
898 Ops[1] = Builder.CreateZExt(Ops[1], Builder.getInt64Ty());
899 Ops[1] = Builder.CreateAnd(Ops[1], MaxIndex - 1);
900 Ops[1] =
901 Builder.CreateMul(Ops[1], ConstantInt::get(Ops[1]->getType(),
902 VecTy->getMinNumElements()));
903 return Builder.CreateExtractVector(ResultType, Ops[0], Ops[1]);
904 }
905
906 return Builder.CreateIntrinsic(
907 Intrinsic::riscv_tuple_extract, {ResultType, Ops[0]->getType()},
908 {Ops[0], Builder.CreateTrunc(Ops[1], Builder.getInt32Ty())});
909}
910
911static LLVM_ATTRIBUTE_NOINLINE Value *
915 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
916 auto &Builder = CGF->Builder;
917 if (auto *ResVecTy = dyn_cast(ResultType)) {
919 unsigned MaxIndex =
920 ResVecTy->getMinNumElements() / VecTy->getMinNumElements();
921 assert(isPowerOf2_32(MaxIndex));
922
923 Ops[1] = Builder.CreateZExt(Ops[1], Builder.getInt64Ty());
924 Ops[1] = Builder.CreateAnd(Ops[1], MaxIndex - 1);
925 Ops[1] =
926 Builder.CreateMul(Ops[1], ConstantInt::get(Ops[1]->getType(),
927 VecTy->getMinNumElements()));
928 return Builder.CreateInsertVector(ResultType, Ops[0], Ops[2], Ops[1]);
929 }
930
931 return Builder.CreateIntrinsic(
932 Intrinsic::riscv_tuple_insert, {ResultType, Ops[2]->getType()},
933 {Ops[0], Ops[2], Builder.CreateTrunc(Ops[1], Builder.getInt32Ty())});
934}
935
936static LLVM_ATTRIBUTE_NOINLINE Value *
940 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {
941 auto &Builder = CGF->Builder;
942 llvm::Value *ReturnVector = llvm::PoisonValue::get(ResultType);
944 for (unsigned I = 0, N = Ops.size(); I < N; ++I) {
946 llvm::Value *Idx = ConstantInt::get(Builder.getInt64Ty(),
947 VecTy->getMinNumElements() * I);
948 ReturnVector =
949 Builder.CreateInsertVector(ResultType, ReturnVector, Ops[I], Idx);
950 } else {
951 llvm::Value *Idx = ConstantInt::get(Builder.getInt32Ty(), I);
952 ReturnVector = Builder.CreateIntrinsic(Intrinsic::riscv_tuple_insert,
953 {ResultType, Ops[I]->getType()},
954 {ReturnVector, Ops[I], Idx});
955 }
956 }
957 return ReturnVector;
958}
959
961 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, {VoidPtrTy}, false);
962 llvm::FunctionCallee Func =
963 CGM.CreateRuntimeFunction(FTy, "__init_riscv_feature_bits");
965 CalleeGV->setDSOLocal(true);
966 CalleeGV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
967 return Builder.CreateCall(Func, {llvm::ConstantPointerNull::get(VoidPtrTy)});
968}
969
971
974 if (().getTargetInfo().validateCpuSupports(FeatureStr))
975 return Builder.getFalse();
976
978}
979
982 llvm::Type *Int32Ty = Builder.getInt32Ty();
983 llvm::Type *Int64Ty = Builder.getInt64Ty();
984 llvm::ArrayType *ArrayOfInt64Ty =
985 llvm::ArrayType::get(Int64Ty, llvm::RISCVISAInfo::FeatureBitSize);
986 llvm::Type *StructTy = llvm::StructType::get(Int32Ty, ArrayOfInt64Ty);
987 llvm::Constant *RISCVFeaturesBits =
990 Value *IndexVal = llvm::ConstantInt::get(Int32Ty, Index);
991 llvm::Value *GEPIndices[] = {Builder.getInt32(0), Builder.getInt32(1),
992 IndexVal};
994 Builder.CreateInBoundsGEP(StructTy, RISCVFeaturesBits, GEPIndices);
995 Value *FeaturesBit =
997 return FeaturesBit;
998}
999
1001 const unsigned RISCVFeatureLength = llvm::RISCVISAInfo::FeatureBitSize;
1002 uint64_t RequireBitMasks[RISCVFeatureLength] = {0};
1003
1004 for (auto Feat : FeaturesStrs) {
1005 auto [GroupID, BitPos] = RISCVISAInfo::getRISCVFeaturesBitsInfo(Feat);
1006
1007
1008
1009 if (BitPos == -1)
1010 return Builder.getFalse();
1011
1012 RequireBitMasks[GroupID] |= (1ULL << BitPos);
1013 }
1014
1016 for (unsigned Idx = 0; Idx < RISCVFeatureLength; Idx++) {
1017 if (RequireBitMasks[Idx] == 0)
1018 continue;
1019
1020 Value *Mask = Builder.getInt64(RequireBitMasks[Idx]);
1023 Value *CmpV = Builder.CreateICmpEQ(Bitset, Mask);
1025 }
1026
1027 assert(Result && "Should have value here.");
1028
1030}
1031
1037
1042 llvm::Constant *RISCVCPUModel =
1043 CGM.CreateRuntimeVariable(StructTy, "__riscv_cpu_model");
1045
1046 auto loadRISCVCPUID = [&](unsigned Index) {
1047 Value *Ptr = Builder.CreateStructGEP(StructTy, RISCVCPUModel, Index);
1048 Value *CPUID = Builder.CreateAlignedLoad(StructTy->getTypeAtIndex(Index),
1049 Ptr, llvm::MaybeAlign());
1050 return CPUID;
1051 };
1052
1053 const llvm::RISCV::CPUModel Model = llvm::RISCV::getCPUModel(CPUStr);
1054
1055
1056 Value *VendorID = loadRISCVCPUID(0);
1058 Builder.CreateICmpEQ(VendorID, Builder.getInt32(Model.MVendorID));
1059
1060
1061 Value *ArchID = loadRISCVCPUID(1);
1064
1065
1066 Value *ImpID = loadRISCVCPUID(2);
1069
1071}
1072
1076
1077 if (BuiltinID == Builtin::BI__builtin_cpu_supports)
1079 if (BuiltinID == Builtin::BI__builtin_cpu_init)
1081 if (BuiltinID == Builtin::BI__builtin_cpu_is)
1083
1086
1087
1088 unsigned ICEArguments = 0;
1092
1095 ICEArguments = 0;
1096 if (BuiltinID == RISCVVector::BI__builtin_rvv_vget_v ||
1097 BuiltinID == RISCVVector::BI__builtin_rvv_vset_v)
1098 ICEArguments = 1 << 1;
1099 } else {
1101 }
1102
1103 if (BuiltinID == RISCV::BI__builtin_riscv_ntl_load)
1104 ICEArguments |= (1 << 1);
1105 if (BuiltinID == RISCV::BI__builtin_riscv_ntl_store)
1106 ICEArguments |= (1 << 2);
1107
1108 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) {
1109
1113 Ops.push_back(AggValue);
1114 continue;
1115 }
1117 }
1118
1119 Intrinsic::ID ID = Intrinsic::not_intrinsic;
1120 int PolicyAttrs = 0;
1121 bool IsMasked = false;
1122
1123 unsigned SegInstSEW = 8;
1124
1125 unsigned TWiden = 0;
1126
1127
1129 switch (BuiltinID) {
1130 default: llvm_unreachable("unexpected builtin ID");
1131 case RISCV::BI__builtin_riscv_orc_b_32:
1132 case RISCV::BI__builtin_riscv_orc_b_64:
1133 case RISCV::BI__builtin_riscv_clmul_32:
1134 case RISCV::BI__builtin_riscv_clmul_64:
1135 case RISCV::BI__builtin_riscv_clmulh_32:
1136 case RISCV::BI__builtin_riscv_clmulh_64:
1137 case RISCV::BI__builtin_riscv_clmulr_32:
1138 case RISCV::BI__builtin_riscv_clmulr_64:
1139 case RISCV::BI__builtin_riscv_xperm4_32:
1140 case RISCV::BI__builtin_riscv_xperm4_64:
1141 case RISCV::BI__builtin_riscv_xperm8_32:
1142 case RISCV::BI__builtin_riscv_xperm8_64:
1143 case RISCV::BI__builtin_riscv_brev8_32:
1144 case RISCV::BI__builtin_riscv_brev8_64:
1145 case RISCV::BI__builtin_riscv_zip_32:
1146 case RISCV::BI__builtin_riscv_unzip_32: {
1147 switch (BuiltinID) {
1148 default: llvm_unreachable("unexpected builtin ID");
1149
1150 case RISCV::BI__builtin_riscv_orc_b_32:
1151 case RISCV::BI__builtin_riscv_orc_b_64:
1152 ID = Intrinsic::riscv_orc_b;
1153 break;
1154
1155
1156 case RISCV::BI__builtin_riscv_clmul_32:
1157 case RISCV::BI__builtin_riscv_clmul_64:
1158 ID = Intrinsic::riscv_clmul;
1159 break;
1160 case RISCV::BI__builtin_riscv_clmulh_32:
1161 case RISCV::BI__builtin_riscv_clmulh_64:
1162 ID = Intrinsic::riscv_clmulh;
1163 break;
1164 case RISCV::BI__builtin_riscv_clmulr_32:
1165 case RISCV::BI__builtin_riscv_clmulr_64:
1166 ID = Intrinsic::riscv_clmulr;
1167 break;
1168
1169
1170 case RISCV::BI__builtin_riscv_xperm8_32:
1171 case RISCV::BI__builtin_riscv_xperm8_64:
1172 ID = Intrinsic::riscv_xperm8;
1173 break;
1174 case RISCV::BI__builtin_riscv_xperm4_32:
1175 case RISCV::BI__builtin_riscv_xperm4_64:
1176 ID = Intrinsic::riscv_xperm4;
1177 break;
1178
1179
1180 case RISCV::BI__builtin_riscv_brev8_32:
1181 case RISCV::BI__builtin_riscv_brev8_64:
1182 ID = Intrinsic::riscv_brev8;
1183 break;
1184 case RISCV::BI__builtin_riscv_zip_32:
1185 ID = Intrinsic::riscv_zip;
1186 break;
1187 case RISCV::BI__builtin_riscv_unzip_32:
1188 ID = Intrinsic::riscv_unzip;
1189 break;
1190 }
1191
1192 IntrinsicTypes = {ResultType};
1193 break;
1194 }
1195
1196
1197
1198
1199 case RISCV::BI__builtin_riscv_sha256sig0:
1200 ID = Intrinsic::riscv_sha256sig0;
1201 break;
1202 case RISCV::BI__builtin_riscv_sha256sig1:
1203 ID = Intrinsic::riscv_sha256sig1;
1204 break;
1205 case RISCV::BI__builtin_riscv_sha256sum0:
1206 ID = Intrinsic::riscv_sha256sum0;
1207 break;
1208 case RISCV::BI__builtin_riscv_sha256sum1:
1209 ID = Intrinsic::riscv_sha256sum1;
1210 break;
1211
1212
1213 case RISCV::BI__builtin_riscv_sm4ks:
1214 ID = Intrinsic::riscv_sm4ks;
1215 break;
1216 case RISCV::BI__builtin_riscv_sm4ed:
1217 ID = Intrinsic::riscv_sm4ed;
1218 break;
1219
1220
1221 case RISCV::BI__builtin_riscv_sm3p0:
1222 ID = Intrinsic::riscv_sm3p0;
1223 break;
1224 case RISCV::BI__builtin_riscv_sm3p1:
1225 ID = Intrinsic::riscv_sm3p1;
1226 break;
1227
1228 case RISCV::BI__builtin_riscv_clz_32:
1229 case RISCV::BI__builtin_riscv_clz_64: {
1232 if (Result->getType() != ResultType)
1234 Builder.CreateIntCast(Result, ResultType, false, "cast");
1236 }
1237 case RISCV::BI__builtin_riscv_ctz_32:
1238 case RISCV::BI__builtin_riscv_ctz_64: {
1241 if (Result->getType() != ResultType)
1243 Builder.CreateIntCast(Result, ResultType, false, "cast");
1245 }
1246
1247
1248 case RISCV::BI__builtin_riscv_ntl_load: {
1250 unsigned DomainVal = 5;
1251 if (Ops.size() == 2)
1253
1254 llvm::MDNode *RISCVDomainNode = llvm::MDNode::get(
1256 llvm::ConstantAsMetadata::get(Builder.getInt32(DomainVal)));
1257 llvm::MDNode *NontemporalNode = llvm::MDNode::get(
1259
1260 int Width;
1261 if(ResTy->isScalableTy()) {
1263 llvm::Type *ScalarTy = ResTy->getScalarType();
1264 Width = ScalarTy->getPrimitiveSizeInBits() *
1265 SVTy->getElementCount().getKnownMinValue();
1266 } else
1267 Width = ResTy->getPrimitiveSizeInBits();
1268 LoadInst *Load = Builder.CreateLoad(
1270
1271 Load->setMetadata(llvm::LLVMContext::MD_nontemporal, NontemporalNode);
1272 Load->setMetadata(CGM.getModule().getMDKindID("riscv-nontemporal-domain"),
1273 RISCVDomainNode);
1274
1275 return Load;
1276 }
1277 case RISCV::BI__builtin_riscv_ntl_store: {
1278 unsigned DomainVal = 5;
1279 if (Ops.size() == 3)
1281
1282 llvm::MDNode *RISCVDomainNode = llvm::MDNode::get(
1284 llvm::ConstantAsMetadata::get(Builder.getInt32(DomainVal)));
1285 llvm::MDNode *NontemporalNode = llvm::MDNode::get(
1287
1288 StoreInst *Store = Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
1289 Store->setMetadata(llvm::LLVMContext::MD_nontemporal, NontemporalNode);
1290 Store->setMetadata(CGM.getModule().getMDKindID("riscv-nontemporal-domain"),
1291 RISCVDomainNode);
1292
1293 return Store;
1294 }
1295
1296 case RISCV::BI__builtin_riscv_pause: {
1297 llvm::Function *Fn = CGM.getIntrinsic(llvm::Intrinsic::riscv_pause);
1298 return Builder.CreateCall(Fn, {});
1299 }
1300
1301
1302 case RISCV::BI__builtin_riscv_cv_alu_addN:
1303 ID = Intrinsic::riscv_cv_alu_addN;
1304 break;
1305 case RISCV::BI__builtin_riscv_cv_alu_addRN:
1306 ID = Intrinsic::riscv_cv_alu_addRN;
1307 break;
1308 case RISCV::BI__builtin_riscv_cv_alu_adduN:
1309 ID = Intrinsic::riscv_cv_alu_adduN;
1310 break;
1311 case RISCV::BI__builtin_riscv_cv_alu_adduRN:
1312 ID = Intrinsic::riscv_cv_alu_adduRN;
1313 break;
1314 case RISCV::BI__builtin_riscv_cv_alu_clip:
1315 ID = Intrinsic::riscv_cv_alu_clip;
1316 break;
1317 case RISCV::BI__builtin_riscv_cv_alu_clipu:
1318 ID = Intrinsic::riscv_cv_alu_clipu;
1319 break;
1320 case RISCV::BI__builtin_riscv_cv_alu_extbs:
1322 "extbs");
1323 case RISCV::BI__builtin_riscv_cv_alu_extbz:
1325 "extbz");
1326 case RISCV::BI__builtin_riscv_cv_alu_exths:
1328 "exths");
1329 case RISCV::BI__builtin_riscv_cv_alu_exthz:
1331 "exthz");
1332 case RISCV::BI__builtin_riscv_cv_alu_sle:
1334 "sle");
1335 case RISCV::BI__builtin_riscv_cv_alu_sleu:
1337 "sleu");
1338 case RISCV::BI__builtin_riscv_cv_alu_subN:
1339 ID = Intrinsic::riscv_cv_alu_subN;
1340 break;
1341 case RISCV::BI__builtin_riscv_cv_alu_subRN:
1342 ID = Intrinsic::riscv_cv_alu_subRN;
1343 break;
1344 case RISCV::BI__builtin_riscv_cv_alu_subuN:
1345 ID = Intrinsic::riscv_cv_alu_subuN;
1346 break;
1347 case RISCV::BI__builtin_riscv_cv_alu_subuRN:
1348 ID = Intrinsic::riscv_cv_alu_subuRN;
1349 break;
1350
1351
1352 case RISCV::BI__builtin_riscv_nds_fcvt_s_bf16:
1354 case RISCV::BI__builtin_riscv_nds_fcvt_bf16_s:
1356
1357
1358#include "clang/Basic/riscv_vector_builtin_cg.inc"
1359
1360
1361#include "clang/Basic/riscv_sifive_vector_builtin_cg.inc"
1362
1363
1364#include "clang/Basic/riscv_andes_vector_builtin_cg.inc"
1365 }
1366
1367 assert(ID != Intrinsic::not_intrinsic);
1368
1369 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
1370 return Builder.CreateCall(F, Ops, "");
1371}
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVGetBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:887
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVStridedSegLoadTupleBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:432
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVFMABuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:688
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVPseudoVWCVTBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:220
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVPseudoVNCVTBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:250
static constexpr unsigned RVV_VMA
Definition RISCV.cpp:26
static Value * loadRISCVFeatureBits(unsigned Index, CGBuilderTy &Builder, CodeGenModule &CGM)
Definition RISCV.cpp:980
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVFloatingPointBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:550
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVVlenbBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:282
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVFloatingConvBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:781
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVStridedSegStoreTupleBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:463
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVIndexedSegLoadTupleBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:621
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVReinterpretBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:848
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVVSEMaskBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:310
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVAveragingBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:491
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVWideningFMABuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:717
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVUnitStridedSegLoadFFTupleBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:392
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVUnitStridedSegStoreTupleBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:365
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVVLEFFBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:32
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVIndexedStoreBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:92
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVPseudoMaskBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:179
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVFloatingReductionBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:815
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVIndexedSegStoreTupleBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:656
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVPseudoUnaryBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:119
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVFloatingUnaryBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:745
static constexpr unsigned RVV_VTA
Definition RISCV.cpp:25
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVWideningFloatingPointBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:585
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVPseudoVFUnaryBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:193
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVVSSEBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:69
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVVsetvliBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:299
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVSetBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:912
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVNarrowingClipBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:520
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVPseudoVNotBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:149
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVCreateBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:937
static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVUnitStridedSegLoadTupleBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)
Definition RISCV.cpp:334
TokenType getType() const
Returns the token's type, e.g.
Enumerates target-specific builtins in their own namespaces within namespace clang.
QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error, unsigned *IntegerConstantArgs=nullptr) const
Return the type for the specified builtin.
@ GE_Missing_type
Missing a type.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
CharUnits - This is an opaque type for sizes expressed in character units.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitScalarOrConstFoldImmArg(unsigned ICEArguments, unsigned Idx, const CallExpr *E)
llvm::Value * EmitRISCVCpuSupports(const CallExpr *E)
Definition RISCV.cpp:970
llvm::Value * EmitRISCVCpuInit()
Definition RISCV.cpp:960
llvm::Type * ConvertType(QualType T)
llvm::Value * EmitRISCVBuiltinExpr(unsigned BuiltinID, const CallExpr *E, ReturnValueSlot ReturnValue)
Definition RISCV.cpp:1073
llvm::Value * EmitRISCVCpuIs(const CallExpr *E)
Definition RISCV.cpp:1032
LValue EmitAggExprToLValue(const Expr *E)
EmitAggExprToLValue - Emit the computation of the specified expression of aggregate type into a tempo...
ASTContext & getContext() const
static bool hasAggregateEvaluationKind(QualType T)
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::LLVMContext & getLLVMContext()
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
llvm::LLVMContext & getLLVMContext()
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
LValue - This represents an lvalue references.
Address getAddress() const
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
This represents one expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Result
The result type of a method or function.
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * Int16Ty