[RISCV] Reduce ManualCodeGen for segment load/store intrinsics. NFC

Operate directly on the existing Ops vector instead of copying to
a new vector. This is similar to what the autogenerated codegen
does for other intrinsics.

This reduced the clang binary size by ~96kb on my local Release+Asserts
build.
This commit is contained in:
Craig Topper 2025-08-20 10:42:40 -07:00
parent 46343ca374
commit ac8f0bb070

View File

@ -721,8 +721,6 @@ multiclass RVVUnitStridedSegLoadTuple<string op> {
NF = nf,
ManualCodegen = [{
{
SmallVector<llvm::Value*, 6> Operands;
bool NoPassthru =
(IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |
(!IsMasked && (PolicyAttrs & RVV_VTA));
@ -733,24 +731,18 @@ multiclass RVVUnitStridedSegLoadTuple<string op> {
else
IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Ops.back()->getType()};
if (NoPassthru) { // Push poison into passthru
Operands.push_back(llvm::PoisonValue::get(ResultType));
} else { // Push intrinsics operands into passthru
llvm::Value *PassthruOperand = IsMasked ? Ops[1] : Ops[0];
Operands.push_back(PassthruOperand);
}
if (IsMasked)
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
if (NoPassthru)
Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
Operands.push_back(Ops[Offset]); // Ptr
if (IsMasked)
Operands.push_back(Ops[0]);
Operands.push_back(Ops[Offset + 1]); // VL
if (IsMasked)
Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
Operands.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
if (ReturnValue.isNull())
return LoadValue;
else
@ -787,26 +779,24 @@ multiclass RVVUnitStridedSegStoreTuple<string op> {
{
// Masked
// Builtin: (mask, ptr, v_tuple, vl)
// Intrinsic: (tuple, ptr, mask, vl)
// Intrinsic: (tuple, ptr, mask, vl, SegInstSEW)
// Unmasked
// Builtin: (ptr, v_tuple, vl)
// Intrinsic: (tuple, ptr, vl)
unsigned Offset = IsMasked ? 1 : 0;
SmallVector<llvm::Value*, 5> Operands;
Operands.push_back(Ops[Offset + 1]); // tuple
Operands.push_back(Ops[Offset]); // Ptr
if (IsMasked)
Operands.push_back(Ops[0]);
Operands.push_back(Ops[Offset + 2]); // VL
Operands.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
// Intrinsic: (tuple, ptr, vl, SegInstSEW)
if (IsMasked)
IntrinsicTypes = {Operands[0]->getType(), Ops[Offset]->getType(), Ops[0]->getType(), Operands.back()->getType()};
std::swap(Ops[0], Ops[2]);
else
IntrinsicTypes = {Operands[0]->getType(), Ops[Offset]->getType(), Operands.back()->getType()};
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
return Builder.CreateCall(F, Operands, "");
std::swap(Ops[0], Ops[1]);
Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
if (IsMasked)
IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(), Ops[3]->getType()};
else
IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType()};
break;
}
}] in {
defvar T = "(Tuple:" # nf # ")";
@ -836,8 +826,6 @@ multiclass RVVUnitStridedSegLoadFFTuple<string op> {
NF = nf,
ManualCodegen = [{
{
SmallVector<llvm::Value*, 6> Operands;
bool NoPassthru =
(IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |
(!IsMasked && (PolicyAttrs & RVV_VTA));
@ -848,24 +836,21 @@ multiclass RVVUnitStridedSegLoadFFTuple<string op> {
else
IntrinsicTypes = {ResultType, Ops.back()->getType(), Ops[Offset]->getType()};
if (NoPassthru) { // Push poison into passthru
Operands.push_back(llvm::PoisonValue::get(ResultType));
} else { // Push intrinsics operands into passthru
llvm::Value *PassthruOperand = IsMasked ? Ops[1] : Ops[0];
Operands.push_back(PassthruOperand);
}
if (IsMasked)
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
if (NoPassthru)
Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
Operands.push_back(Ops[Offset]); // Ptr
if (IsMasked)
Operands.push_back(Ops[0]);
Operands.push_back(Ops[Offset + 2]); // vl
if (IsMasked)
Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
Operands.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
Value *NewVL = Ops[2];
Ops.erase(Ops.begin() + 2);
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
// Get alignment from the new vl operand
clang::CharUnits Align =
CGM.getNaturalPointeeTypeAlignment(E->getArg(Offset + 1)->getType());
@ -874,7 +859,7 @@ multiclass RVVUnitStridedSegLoadFFTuple<string op> {
// Store new_vl
llvm::Value *V = Builder.CreateExtractValue(LoadValue, 1);
Builder.CreateStore(V, Address(Ops[Offset + 1], V->getType(), Align));
Builder.CreateStore(V, Address(NewVL, V->getType(), Align));
if (ReturnValue.isNull())
return ReturnTuple;
@ -909,8 +894,6 @@ multiclass RVVStridedSegLoadTuple<string op> {
NF = nf,
ManualCodegen = [{
{
SmallVector<llvm::Value*, 7> Operands;
bool NoPassthru =
(IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |
(!IsMasked && (PolicyAttrs & RVV_VTA));
@ -921,24 +904,17 @@ multiclass RVVStridedSegLoadTuple<string op> {
else
IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Ops.back()->getType()};
if (NoPassthru) { // Push poison into passthru
Operands.push_back(llvm::PoisonValue::get(ResultType));
} else { // Push intrinsics operands into passthru
llvm::Value *PassthruOperand = IsMasked ? Ops[1] : Ops[0];
Operands.push_back(PassthruOperand);
}
if (IsMasked)
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
if (NoPassthru)
Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
Operands.push_back(Ops[Offset]); // Ptr
Operands.push_back(Ops[Offset + 1]); // Stride
if (IsMasked)
Operands.push_back(Ops[0]);
Operands.push_back(Ops[Offset + 2]); // VL
if (IsMasked)
Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
Operands.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
if (ReturnValue.isNull())
return LoadValue;
@ -977,27 +953,23 @@ multiclass RVVStridedSegStoreTuple<string op> {
{
// Masked
// Builtin: (mask, ptr, stride, v_tuple, vl)
// Intrinsic: (tuple, ptr, stride, mask, vl)
// Intrinsic: (tuple, ptr, stride, mask, vl, SegInstSEW)
// Unmasked
// Builtin: (ptr, stride, v_tuple, vl)
// Intrinsic: (tuple, ptr, stride, vl)
unsigned Offset = IsMasked ? 1 : 0;
SmallVector<llvm::Value*, 6> Operands;
Operands.push_back(Ops[Offset + 2]); // tuple
Operands.push_back(Ops[Offset]); // Ptr
Operands.push_back(Ops[Offset + 1]); // Stride
if (IsMasked)
Operands.push_back(Ops[0]);
Operands.push_back(Ops[Offset + 3]); // VL
Operands.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
// Intrinsic: (tuple, ptr, stride, vl, SegInstSEW)
if (IsMasked)
IntrinsicTypes = {Operands[0]->getType(), Operands[1]->getType(), Operands.back()->getType(), Ops[0]->getType()};
std::swap(Ops[0], Ops[3]);
else
IntrinsicTypes = {Operands[0]->getType(), Operands[1]->getType(), Operands.back()->getType()};
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
return Builder.CreateCall(F, Operands, "");
std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
if (IsMasked)
IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[4]->getType(), Ops[3]->getType()};
else
IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[3]->getType()};
break;
}
}] in {
defvar T = "(Tuple:" # nf # ")";
@ -1022,40 +994,30 @@ multiclass RVVIndexedSegLoadTuple<string op> {
NF = nf,
ManualCodegen = [{
{
SmallVector<llvm::Value*, 7> Operands;
bool NoPassthru =
(IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |
(!IsMasked && (PolicyAttrs & RVV_VTA));
unsigned Offset = IsMasked ? NoPassthru ? 1 : 2 : NoPassthru ? 0 : 1;
if (NoPassthru) { // Push poison into passthru
Operands.push_back(llvm::PoisonValue::get(ResultType));
} else { // Push intrinsics operands into passthru
llvm::Value *PassthruOperand = IsMasked ? Ops[1] : Ops[0];
Operands.push_back(PassthruOperand);
}
Operands.push_back(Ops[Offset]); // Ptr
Operands.push_back(Ops[Offset + 1]); // Idx
if (IsMasked)
Operands.push_back(Ops[0]);
Operands.push_back(Ops[Offset + 2]); // VL
if (IsMasked)
Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
Operands.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
if (IsMasked)
IntrinsicTypes = {ResultType, Ops[Offset]->getType(),
Ops[Offset + 1]->getType(),
Ops[0]->getType(),
Ops.back()->getType()};
std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
if (NoPassthru)
Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
if (IsMasked)
Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
if (IsMasked)
IntrinsicTypes = {ResultType, Ops[1]->getType(),
Ops[2]->getType(),
Ops[3]->getType(),
Ops[4]->getType()};
else
IntrinsicTypes = {ResultType, Ops[Offset]->getType(),
Ops[Offset + 1]->getType(),
Ops.back()->getType()};
IntrinsicTypes = {ResultType, Ops[1]->getType(),
Ops[2]->getType(),
Ops[3]->getType()};
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
if (ReturnValue.isNull())
return LoadValue;
@ -1090,30 +1052,25 @@ multiclass RVVIndexedSegStoreTuple<string op> {
{
// Masked
// Builtin: (mask, ptr, index, v_tuple, vl)
// Intrinsic: (tuple, ptr, index, mask, vl)
// Intrinsic: (tuple, ptr, index, mask, vl, SegInstSEW)
// Unmasked
// Builtin: (ptr, index, v_tuple, vl)
// Intrinsic: (tuple, ptr, index, vl)
unsigned Offset = IsMasked ? 1 : 0;
SmallVector<llvm::Value*, 6> Operands;
Operands.push_back(Ops[Offset + 2]); // tuple
Operands.push_back(Ops[Offset]); // Ptr
Operands.push_back(Ops[Offset + 1]); // Idx
if (IsMasked)
Operands.push_back(Ops[0]);
Operands.push_back(Ops[Offset + 3]); // VL
Operands.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
// Intrinsic: (tuple, ptr, index, vl, SegInstSEW)
if (IsMasked)
IntrinsicTypes = {Operands[0]->getType(), Ops[Offset]->getType(), Ops[Offset + 1]->getType(),
Ops[0]->getType(),
Operands.back()->getType()};
std::swap(Ops[0], Ops[3]);
else
IntrinsicTypes = {Operands[0]->getType(), Ops[Offset]->getType(), Ops[Offset + 1]->getType(),
Operands.back()->getType()};
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
return Builder.CreateCall(F, Operands, "");
std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));
if (IsMasked)
IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(),
Ops[3]->getType(), Ops[4]->getType()};
else
IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(),
Ops[3]->getType()};
break;
}
}] in {
defvar T = "(Tuple:" # nf # ")";