[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