|
15 | 15 | #include "llvm/CodeGen/TargetLowering.h"
|
16 | 16 | #include "llvm/CodeGen/ValueTypes.h"
|
17 | 17 | #include "llvm/IR/Instructions.h"
|
| 18 | +#include "llvm/IR/IntrinsicsRISCV.h" |
18 | 19 | #include "llvm/IR/PatternMatch.h"
|
19 | 20 | #include <cmath>
|
20 | 21 | #include <optional>
|
@@ -2701,6 +2702,82 @@ void RISCVTTIImpl::getPeelingPreferences(Loop *L, ScalarEvolution &SE,
|
2701 | 2702 | BaseT::getPeelingPreferences(L, SE, PP);
|
2702 | 2703 | }
|
2703 | 2704 |
|
| 2705 | +bool RISCVTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst, |
| 2706 | + MemIntrinsicInfo &Info) const { |
| 2707 | + const DataLayout &DL = getDataLayout(); |
| 2708 | + Intrinsic::ID IID = Inst->getIntrinsicID(); |
| 2709 | + LLVMContext &C = Inst->getContext(); |
| 2710 | + bool HasMask = false; |
| 2711 | + switch (IID) { |
| 2712 | + case Intrinsic::riscv_vle_mask: |
| 2713 | + case Intrinsic::riscv_vse_mask: |
| 2714 | + HasMask = true; |
| 2715 | + [[fallthrough]]; |
| 2716 | + case Intrinsic::riscv_vle: |
| 2717 | + case Intrinsic::riscv_vse: { |
| 2718 | + // Intrinsic interface: |
| 2719 | + // riscv_vle(merge, ptr, vl) |
| 2720 | + // riscv_vle_mask(merge, ptr, mask, vl, policy) |
| 2721 | + // riscv_vse(val, ptr, vl) |
| 2722 | + // riscv_vse_mask(val, ptr, mask, vl, policy) |
| 2723 | + bool IsWrite = Inst->getType()->isVoidTy(); |
| 2724 | + Type *Ty = IsWrite ? Inst->getArgOperand(0)->getType() : Inst->getType(); |
| 2725 | + const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID); |
| 2726 | + unsigned VLIndex = RVVIInfo->VLOperand; |
| 2727 | + unsigned PtrOperandNo = VLIndex - 1 - HasMask; |
| 2728 | + MaybeAlign Alignment = |
| 2729 | + Inst->getArgOperand(PtrOperandNo)->getPointerAlignment(DL); |
| 2730 | + Type *MaskType = Ty->getWithNewType(Type::getInt1Ty(C)); |
| 2731 | + Value *Mask = ConstantInt::getTrue(MaskType); |
| 2732 | + if (HasMask) |
| 2733 | + Mask = Inst->getArgOperand(VLIndex - 1); |
| 2734 | + Value *EVL = Inst->getArgOperand(VLIndex); |
| 2735 | + Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty, |
| 2736 | + Alignment, Mask, EVL); |
| 2737 | + return true; |
| 2738 | + } |
| 2739 | + case Intrinsic::riscv_vlse_mask: |
| 2740 | + case Intrinsic::riscv_vsse_mask: |
| 2741 | + HasMask = true; |
| 2742 | + [[fallthrough]]; |
| 2743 | + case Intrinsic::riscv_vlse: |
| 2744 | + case Intrinsic::riscv_vsse: { |
| 2745 | + // Intrinsic interface: |
| 2746 | + // riscv_vlse(merge, ptr, stride, vl) |
| 2747 | + // riscv_vlse_mask(merge, ptr, stride, mask, vl, policy) |
| 2748 | + // riscv_vsse(val, ptr, stride, vl) |
| 2749 | + // riscv_vsse_mask(val, ptr, stride, mask, vl, policy) |
| 2750 | + bool IsWrite = Inst->getType()->isVoidTy(); |
| 2751 | + Type *Ty = IsWrite ? Inst->getArgOperand(0)->getType() : Inst->getType(); |
| 2752 | + const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID); |
| 2753 | + unsigned VLIndex = RVVIInfo->VLOperand; |
| 2754 | + unsigned PtrOperandNo = VLIndex - 2 - HasMask; |
| 2755 | + MaybeAlign Alignment = |
| 2756 | + Inst->getArgOperand(PtrOperandNo)->getPointerAlignment(DL); |
| 2757 | + |
| 2758 | + Value *Stride = Inst->getArgOperand(PtrOperandNo + 1); |
| 2759 | + // Use the pointer alignment as the element alignment if the stride is a |
| 2760 | + // multiple of the pointer alignment. Otherwise, the element alignment |
| 2761 | + // should be the greatest common divisor of pointer alignment and stride. |
| 2762 | + // For simplicity, just consider unalignment for elements. |
| 2763 | + unsigned PointerAlign = Alignment.valueOrOne().value(); |
| 2764 | + if (!isa<ConstantInt>(Stride) || |
| 2765 | + cast<ConstantInt>(Stride)->getZExtValue() % PointerAlign != 0) |
| 2766 | + Alignment = Align(1); |
| 2767 | + |
| 2768 | + Type *MaskType = Ty->getWithNewType(Type::getInt1Ty(C)); |
| 2769 | + Value *Mask = ConstantInt::getTrue(MaskType); |
| 2770 | + if (HasMask) |
| 2771 | + Mask = Inst->getArgOperand(VLIndex - 1); |
| 2772 | + Value *EVL = Inst->getArgOperand(VLIndex); |
| 2773 | + Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty, |
| 2774 | + Alignment, Mask, EVL, Stride); |
| 2775 | + return true; |
| 2776 | + } |
| 2777 | + } |
| 2778 | + return false; |
| 2779 | +} |
| 2780 | + |
2704 | 2781 | unsigned RISCVTTIImpl::getRegUsageForType(Type *Ty) const {
|
2705 | 2782 | if (Ty->isVectorTy()) {
|
2706 | 2783 | // f16 with only zvfhmin and bf16 will be promoted to f32
|
|
0 commit comments