[PATCH] D149903: [VPlan] Replace IR based truncateToMinimalBitwidths with VPlan version.
Florian Hahn via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun May 14 08:51:56 PDT 2023
fhahn marked 15 inline comments as done.
fhahn added inline comments.
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:749
+ VPlan &Plan, const MapVector<Instruction *, uint64_t> &MinBWs) {
+ auto GetSizeInBits = [](VPValue *Op) {
+ auto *UV = Op->getUnderlyingValue();
----------------
Ayal wrote:
> nit: `VPValue *Op` >> `VPValue *VPV`?
Updated, thanks!
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:757
+ llvm_unreachable("trying to get type of a VPValue without type info");
+ };
+ for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
----------------
Ayal wrote:
> nit: worth an empty line?
added, thanks!
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:764-765
+
+ auto *UI =
+ cast_or_null<Instruction>(R.getVPSingleValue()->getUnderlyingValue());
+ auto I = MinBWs.find(UI);
----------------
Ayal wrote:
>
Updated, thanks!
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:766
+ cast_or_null<Instruction>(R.getVPSingleValue()->getUnderlyingValue());
+ auto I = MinBWs.find(UI);
+ if (!UI || I == MinBWs.end())
----------------
Ayal wrote:
> nit: is find() ok given a null UI?
Yes I think so, the keys are pointers and they shouldn't be dereferenced.
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:769
+ continue;
+
+ unsigned NewResSizeInBits = I->second;
----------------
Ayal wrote:
>
Adjusted, thanks!
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:772-773
+ Type *ResTy = UI->getType();
+ if (!ResTy->isIntegerTy() ||
+ ResTy->getScalarSizeInBits() == NewResSizeInBits)
+ continue;
----------------
Ayal wrote:
>
Done, thanks!
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:787-788
+ case Instruction::ZExt: {
+ assert(ResTy->getScalarSizeInBits() > NewResSizeInBits &&
+ "Nothing to shrink?");
+ if (GetSizeInBits(R.getOperand(0)) >= NewResSizeInBits)
----------------
Ayal wrote:
>
Updated, thanks!
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:790
+ if (GetSizeInBits(R.getOperand(0)) >= NewResSizeInBits)
+ break;
+ auto *C = new VPWidenCastRecipe(cast<CastInst>(UI)->getOpcode(),
----------------
Ayal wrote:
> OK, operand < ResTy due to SExt/ZExt,
> and NewResTy < ResTy due to MinBW.
> NewResTy == ResTy cases should arguably be excluded from MinBWs? (independent of this patch)
> Now if operand < NewResTy (< ResTy) then we SExt/ZExt the operand directly to NewResTy instead, and `continue` - why is the "Extend result to original width" part skipped in this case?
> If OTOH operand > NewResTy a Trunc is needed rather than an Extend, and provided by subsequent code which is reached by `break`, followed by ZExt back to ResTy.
> Otherwise if operand == NewResTy, the SExt/ZExt could be dropped, but we keep it and end up generating a redundant ZExt from R to ResTy - which have same sizes? It's probably ok because the knowledge that NewResTy bits suffice is already there, but would be good to clarify/clean up.
> Now if operand < NewResTy (< ResTy) then we SExt/ZExt the operand directly to NewResTy instead, and continue - why is the "Extend result to original width" part skipped in this case?
In that case, the original (wider) cast is replaced by a new (narrower) cast and there's no need to truncate.
> If OTOH operand > NewResTy a Trunc is needed rather than an Extend, and provided by subsequent code which is reached by break, followed by ZExt back to ResTy.
Yep.
> Otherwise if operand == NewResTy, the SExt/ZExt could be dropped, but we keep it and end up generating a redundant ZExt from R to ResTy - which have same sizes? It's probably ok because the knowledge that NewResTy bits suffice is already there, but would be good to clarify/clean up.
Yes we would at the moment generate redundant extend/trunc chains, which would indeed be good to clean up. I think we could fold those as follow-up.
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:791
+ break;
+ auto *C = new VPWidenCastRecipe(cast<CastInst>(UI)->getOpcode(),
+ R.getOperand(0), NewResTy);
----------------
Ayal wrote:
> nit: may look better to take R's opcode than UI's, but that requires casting it to VPWidenCastRecipe, so above isa maybe worth dyn_cast after all...
Updated, thanks!
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:804
+ if (GetSizeInBits(Op) == NewResSizeInBits)
+ continue;
+ auto *Shrunk = new VPWidenCastRecipe(
----------------
Ayal wrote:
> assert Op > NewRes? What about the condition operand of select?
Added assert, thanks!
Hmm, select would indeed be handled incorrectly, but I wasn't able to find a suitable test case. Removed VPWidenSelect for now, but will try to come up with a test case. Alternatively could leave select-handling in + assert to surface a test case, if one exists.
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:805-806
+ continue;
+ auto *Shrunk = new VPWidenCastRecipe(
+ Instruction::Trunc, Op, IntegerType::get(Ctx, NewResSizeInBits));
+ R.setOperand(Idx, Shrunk);
----------------
Ayal wrote:
>
Updated, thanks!
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:814-815
+ // Extend result to original width.
+ auto *Ext =
+ new VPWidenCastRecipe(Instruction::ZExt, R.getVPSingleValue(), ResTy);
+ ResultVPV->replaceAllUsesWith(Ext);
----------------
Ayal wrote:
>
Done, thanks!
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:817
+ ResultVPV->replaceAllUsesWith(Ext);
+ Ext->setOperand(0, R.getVPSingleValue());
+ Ext->insertAfter(&R);
----------------
Ayal wrote:
>
Updated, thanks!
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:792
+ if (auto *VPW = dyn_cast<VPWidenCastRecipe>(&R)) {
+ Instruction *UI = VPW->getUnderlyingInstr();
+ switch (UI->getOpcode()) {
----------------
Ayal wrote:
> UI is aka UV. Better call it UI from the start, as it's an Instruction* rather than Value*.
Renamed, thanks
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D149903/new/
https://reviews.llvm.org/D149903
More information about the llvm-commits
mailing list