Skip to content

Commit 939352b

Browse files
author
Yeting Kuo
committed
[RISCV][Clang] Teach RISCVEmitter to generate BitCast for pointer operands.
RVV C intrinsics use pointers to scalar for base address and their corresponding IR intrinsics but use pointers to vector. It makes some vector load intrinsics need specific ManualCodegen and MaskedManualCodegen to just add bitcast for transforming to IR. For simplifying riscv_vector.td, the patch make RISCVEmitter detect pointer operands and bitcast them. Reviewed By: kito-cheng Differential Revision: https://reviews.llvm.org/D129043
1 parent 85318d3 commit 939352b

File tree

3 files changed

+40
-71
lines changed

3 files changed

+40
-71
lines changed

clang/include/clang/Basic/riscv_vector.td

Lines changed: 28 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -582,45 +582,24 @@ class IsFloat<string type> {
582582
}
583583

584584
let HasUnMaskedOverloaded = false,
585-
MaskedPolicy = NonePolicy,
586-
ManualCodegen = [{
587-
IntrinsicTypes = {ResultType, Ops[1]->getType()};
588-
Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
589-
}],
590-
MaskedManualCodegen= [{
591-
// Move mask to right before vl.
592-
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
593-
IntrinsicTypes = {ResultType, Ops[3]->getType()};
594-
Ops[1] = Builder.CreateBitCast(Ops[1], ResultType->getPointerTo());
595-
}] in {
596-
class RVVVLEMaskBuiltin : RVVBuiltin<"m", "mPCUe", "c"> {
585+
MaskedPolicy = NonePolicy in {
586+
class RVVVLEMaskBuiltin : RVVOutBuiltin<"m", "mPCUe", "c"> {
597587
let Name = "vlm_v";
598588
let IRName = "vlm";
599589
let HasMasked = false;
600590
}
601591
}
602592

603593
let HasUnMaskedOverloaded = false,
604-
ManualCodegen = [{
605-
IntrinsicTypes = {ResultType, Ops[1]->getType()};
606-
Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
607-
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
608-
}],
609-
MaskedManualCodegen= [{
610-
// Move mask to right before vl.
611-
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
612-
Ops.push_back(ConstantInt::get(Ops.back()->getType(), TAIL_UNDISTURBED));
613-
IntrinsicTypes = {ResultType, Ops[3]->getType()};
614-
Ops[1] = Builder.CreateBitCast(Ops[1], ResultType->getPointerTo());
615-
}] in {
594+
UnMaskedPolicy = HasPassthruOperand in {
616595
multiclass RVVVLEBuiltin<list<string> types> {
617596
let Name = NAME # "_v",
618597
IRName = "vle",
619598
MaskedIRName ="vle_mask" in {
620599
foreach type = types in {
621-
def : RVVBuiltin<"v", "vPCe", type>;
600+
def : RVVOutBuiltin<"v", "vPCe", type>;
622601
if !not(IsFloat<type>.val) then {
623-
def : RVVBuiltin<"Uv", "UvPCUe", type>;
602+
def : RVVOutBuiltin<"Uv", "UvPCUe", type>;
624603
}
625604
}
626605
}
@@ -685,61 +664,39 @@ multiclass RVVVLSEBuiltin<list<string> types> {
685664
IRName = "vlse",
686665
MaskedIRName ="vlse_mask",
687666
HasUnMaskedOverloaded = false,
688-
ManualCodegen = [{
689-
IntrinsicTypes = {ResultType, Ops[2]->getType()};
690-
Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
691-
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
692-
}],
693-
MaskedManualCodegen= [{
694-
// Move mask to right before vl.
695-
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
696-
Ops.push_back(ConstantInt::get(Ops.back()->getType(), TAIL_UNDISTURBED));
697-
IntrinsicTypes = {ResultType, Ops[4]->getType()};
698-
Ops[1] = Builder.CreateBitCast(Ops[1], ResultType->getPointerTo());
699-
}] in {
667+
UnMaskedPolicy = HasPassthruOperand in {
700668
foreach type = types in {
701-
def : RVVBuiltin<"v", "vPCet", type>;
669+
def : RVVOutBuiltin<"v", "vPCet", type>;
702670
if !not(IsFloat<type>.val) then {
703-
def : RVVBuiltin<"Uv", "UvPCUet", type>;
671+
def : RVVOutBuiltin<"Uv", "UvPCUet", type>;
704672
}
705673
}
706674
}
707675
}
708676

709677
multiclass RVVIndexedLoad<string op> {
710-
let ManualCodegen = [{
711-
IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[2]->getType()};
712-
Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
713-
Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType));
714-
}],
715-
MaskedManualCodegen = [{
716-
// Move mask to right before vl.
717-
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
718-
Ops.push_back(ConstantInt::get(Ops.back()->getType(), TAIL_UNDISTURBED));
719-
IntrinsicTypes = {ResultType, Ops[2]->getType(), Ops[4]->getType()};
720-
Ops[1] = Builder.CreateBitCast(Ops[1], ResultType->getPointerTo());
721-
}] in {
722-
foreach type = TypeList in {
723-
foreach eew_list = EEWList[0-2] in {
724-
defvar eew = eew_list[0];
725-
defvar eew_type = eew_list[1];
726-
let Name = op # eew # "_v", IRName = op, MaskedIRName = op # "_mask" in {
727-
def: RVVBuiltin<"v", "vPCe" # eew_type # "Uv", type>;
728-
if !not(IsFloat<type>.val) then {
729-
def: RVVBuiltin<"Uv", "UvPCUe" # eew_type # "Uv", type>;
730-
}
731-
}
678+
let UnMaskedPolicy = HasPassthruOperand in {
679+
foreach type = TypeList in {
680+
foreach eew_list = EEWList[0-2] in {
681+
defvar eew = eew_list[0];
682+
defvar eew_type = eew_list[1];
683+
let Name = op # eew # "_v", IRName = op, MaskedIRName = op # "_mask" in {
684+
def: RVVOutOp1Builtin<"v", "vPCe" # eew_type # "Uv", type>;
685+
if !not(IsFloat<type>.val) then {
686+
def: RVVOutOp1Builtin<"Uv", "UvPCUe" # eew_type # "Uv", type>;
687+
}
732688
}
733-
defvar eew64 = "64";
734-
defvar eew64_type = "(Log2EEW:6)";
735-
let Name = op # eew64 # "_v", IRName = op, MaskedIRName = op # "_mask",
736-
RequiredFeatures = ["RV64"] in {
737-
def: RVVBuiltin<"v", "vPCe" # eew64_type # "Uv", type>;
738-
if !not(IsFloat<type>.val) then {
739-
def: RVVBuiltin<"Uv", "UvPCUe" # eew64_type # "Uv", type>;
740-
}
741-
}
742689
}
690+
defvar eew64 = "64";
691+
defvar eew64_type = "(Log2EEW:6)";
692+
let Name = op # eew64 # "_v", IRName = op, MaskedIRName = op # "_mask",
693+
RequiredFeatures = ["RV64"] in {
694+
def: RVVOutOp1Builtin<"v", "vPCe" # eew64_type # "Uv", type>;
695+
if !not(IsFloat<type>.val) then {
696+
def: RVVOutOp1Builtin<"Uv", "UvPCUe" # eew64_type # "Uv", type>;
697+
}
698+
}
699+
}
743700
}
744701
}
745702

clang/include/clang/Support/RISCVVIntrinsicUtils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ class RVVType {
225225
return isFloat() && ElementBitwidth == Width;
226226
}
227227

228+
bool isPointer() const { return IsPointer; }
229+
228230
private:
229231
// Verify RVV vector type and set Valid.
230232
bool verifyType() const;

clang/utils/TableGen/RISCVVEmitter.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ void emitCodeGenSwitchBody(const RVVIntrinsic *RVVI, raw_ostream &OS) {
105105
return;
106106
}
107107

108+
// Cast pointer operand of vector load intrinsic.
109+
for (const auto &I : enumerate(RVVI->getInputTypes())) {
110+
if (I.value()->isPointer()) {
111+
assert(RVVI->getIntrinsicTypes().front() == -1 &&
112+
"RVVI should be vector load intrinsic.");
113+
OS << " Ops[" << I.index() << "] = Builder.CreateBitCast(Ops[";
114+
OS << I.index() << "], ResultType->getPointerTo());\n";
115+
}
116+
}
117+
108118
if (RVVI->isMasked()) {
109119
if (RVVI->hasVL()) {
110120
OS << " std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);\n";

0 commit comments

Comments
 (0)