[PATCH] D101103: [InstSimplify] Treat invariant group insts as bitcasts for load operands
Piotr Padlewski via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 27 01:47:23 PDT 2021
Prazek added a comment.
In D101103#2718848 <https://reviews.llvm.org/D101103#2718848>, @lebedev.ri wrote:
> I think the recursion is unfortunate there. How about something like
>
> static Constant *ConstructLoadOperandConstant(Value *Op) {
> SmallVector<Value*, 16> Worklist;
>
> OpStack.emplace_back(Op);
> for(int I = 0; I != OpStack.size(); ++I) {
> Value* Op = OpStack.back();
>
> if (isa<Constant>(Op))
> break; // YAY!
>
> if (auto *BC = dyn_cast<BitCastOperator>(Op))
> OpStack.emplace_back(BC->getOperand(0)); // Recurse.
>
> if (auto *GEP = dyn_cast<GEPOperator>(Op)) {
> if (all_of(ArrayRef<Value*>(GEP->operands()).drop_front(),
> [](Value*Op) { return isa<Constant>(Op); }))
> OpStack.emplace_back(GEP->getOperand(0)); // Recurse.
> }
>
> if (auto *II = dyn_cast<IntrinsicInst>(Op)) {
> if (II->getIntrinsicID() == Intrinsic::strip_invariant_group ||
> II->getIntrinsicID() == Intrinsic::launder_invariant_group)
> OpStack.emplace_back(II->getOperand(0)); // Recurse.
> }
>
> return nullptr; // Can't look past this instruction. Give up.
> }
>
> // Alright! Reconstruct this chain as constant expressions.
> Constant* NewOp = cast<Constant>(Worklist.pop_back_val());
> while(!OpStack.empty()) {
> Value* Op = OpStack.pop_back_val();
>
> if (isa<BitCastOperator>(Op))
> NewOp = ConstantExpr::getBitCast(NewOp, Op->getType());
>
> if (auto *GEP = dyn_cast<GEPOperator>(Op)) {
> SmallVector<Constant *> Idxs;
> Idxs.reserve(GEP->getNumOperands() - 1);
> for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I)
> Idxs.push_back(cast<Constant>(GEP->getOperand(I));
> return ConstantExpr::getGetElementPtr(GEP->getSourceElementType(), NewOp,
> Idxs, GEP->isInBounds(),
> GEP->getInRangeIndex());
> }
>
> if (auto *II = dyn_cast<IntrinsicInst>(Op)) {
> if (II->getIntrinsicID() == Intrinsic::strip_invariant_group ||
> II->getIntrinsicID() == Intrinsic::launder_invariant_group)
> NewOp = ConstantExpr::getBitCast(NewOp, Op->getType());
> }
>
> llvm_unreachable("Instruction handled in first loop but not here?");
> }
> }
>
> return NewOp;
Also if you want to traverse bitcasts and invariant.group intrinsics, you could perhaps use ```stripPointerCastsAndOffsets<PSK_ForAliasAnalysis>```
================
Comment at: llvm/test/Transforms/InstSimplify/invariant.group-load.ll:13
+ %p = bitcast { i64, i64 }* @A to i8*
+ %a = call i8* @llvm.strip.invariant.group.p0i8(i8* %p)
+ %b = getelementptr i8, i8* %a, i32 8
----------------
Could you add similar test for launder.invariant.group as well?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D101103/new/
https://reviews.llvm.org/D101103
More information about the llvm-commits
mailing list