@@ -167,33 +167,75 @@ std::optional<InstTy*> getSingleUserAs(llvm::Instruction* value) {
167167using MallocGeps = SmallPtrSet<GetElementPtrInst*, 2 >;
168168using MallocBcasts = SmallPtrSet<BitCastInst*, 4 >;
169169
170- std::pair<MallocGeps, MallocBcasts> collectRelevantMallocUsers (llvm::CallBase& ci) {
171- auto geps = MallocGeps{};
172- auto bcasts = MallocBcasts{};
173- for (auto user : ci.users ()) {
174- // Simple case: Pointer is immediately casted
175- if (auto inst = dyn_cast<BitCastInst>(user)) {
176- bcasts.insert (inst);
177- }
178- // Pointer is first stored, then loaded and subsequently casted
179- if (auto storeInst = dyn_cast<StoreInst>(user)) {
180- auto storeAddr = storeInst->getPointerOperand ();
181- for (auto storeUser : storeAddr->users ()) { // TODO: Ensure that load occurs after store?
182- if (auto loadInst = dyn_cast<LoadInst>(storeUser)) {
183- for (auto loadUser : loadInst->users ()) {
184- if (auto bcastInst = dyn_cast<BitCastInst>(loadUser)) {
185- // LOG_MSG(*bcastInst)
186- bcasts.insert (bcastInst);
187- }
188- }
170+ // std::pair<MallocGeps, MallocBcasts> collectRelevantMallocUsers(llvm::CallBase& ci) {
171+ // auto geps = MallocGeps{};
172+ // auto bcasts = MallocBcasts{};
173+ // for (auto user : ci.users()) {
174+ // // Simple case: Pointer is immediately casted
175+ // if (auto inst = dyn_cast<BitCastInst>(user)) {
176+ // bcasts.insert(inst);
177+ // }
178+ // // Pointer is first stored, then loaded and subsequently casted
179+ // if (auto storeInst = dyn_cast<StoreInst>(user)) {
180+ // auto storeAddr = storeInst->getPointerOperand();
181+ // if (!(storeAddr == nullptr || llvm::isa<llvm::ConstantPointerNull>(storeAddr))) {
182+ // for (auto storeUser : storeAddr->users()) { // TODO: Ensure that load occurs after store?
183+ // if (auto loadInst = dyn_cast<LoadInst>(storeUser)) {
184+ // for (auto loadUser : loadInst->users()) {
185+ // if (auto bcastInst = dyn_cast<BitCastInst>(loadUser)) {
186+ // // LOG_MSG(*bcastInst)
187+ // bcasts.insert(bcastInst);
188+ // }
189+ // }
190+ // }
191+ // }
192+ // } else {
193+ // LOG_DEBUG("Null, must skip")
194+ // }
195+ // }
196+ // // GEP indicates that an array cookie is added to the allocation. (Fixes #13)
197+ // if (auto gep = dyn_cast<GetElementPtrInst>(user)) {
198+ // geps.insert(gep);
199+ // }
200+ // }
201+ // return {geps, bcasts};
202+ // }
203+
204+ void collect_casts_from_stack (llvm::StoreInst* store_inst, MallocBcasts& out_bcasts) {
205+ auto * slot = store_inst->getPointerOperand ();
206+
207+ // Guard: Skip invalid or null storage locations
208+ if (llvm::isa<llvm::ConstantPointerNull>(slot)) {
209+ LOG_DEBUG (" Skipping null storage" );
210+ return ;
211+ }
212+
213+ for (auto * slot_user : slot->users ()) {
214+ // TODO: Ensure that load occurs after store?
215+ if (auto * load_inst = llvm::dyn_cast<llvm::LoadInst>(slot_user)) {
216+ for (auto * load_user : load_inst->users ()) {
217+ if (auto * bit_cast = llvm::dyn_cast<llvm::BitCastInst>(load_user)) {
218+ out_bcasts.insert (bit_cast);
189219 }
190220 }
191221 }
192- // GEP indicates that an array cookie is added to the allocation. (Fixes #13)
193- if (auto gep = dyn_cast<GetElementPtrInst>(user)) {
194- geps.insert (gep);
222+ }
223+ }
224+
225+ std::pair<MallocGeps, MallocBcasts> collectRelevantMallocUsers (llvm::CallBase& call_inst) {
226+ auto geps = MallocGeps{};
227+ auto bcasts = MallocBcasts{};
228+
229+ for (auto * user : call_inst.users ()) {
230+ if (auto * bit_cast = llvm::dyn_cast<llvm::BitCastInst>(user)) {
231+ bcasts.insert (bit_cast);
232+ } else if (auto * gep_inst = llvm::dyn_cast<llvm::GetElementPtrInst>(user)) {
233+ geps.insert (gep_inst);
234+ } else if (auto * store_inst = llvm::dyn_cast<llvm::StoreInst>(user)) {
235+ collect_casts_from_stack (store_inst, bcasts);
195236 }
196237 }
238+
197239 return {geps, bcasts};
198240}
199241
0 commit comments