================ @@ -2478,3 +2479,76 @@ PreservedAnalyses LowerTypeTestsPass::run(Module &M, return PreservedAnalyses::all(); return PreservedAnalyses::none(); } + +PreservedAnalyses SimplifyTypeTestsPass::run(Module &M, + ModuleAnalysisManager &AM) { + bool Changed = false; + // Figure out whether inlining has exposed a constant address to a lowered + // type test, and remove the test if so and the address is known to pass the + // test. Unfortunately this pass ends up needing to reverse engineer what + // LowerTypeTests did; this is currently inherent to the design of ThinLTO + // importing where LowerTypeTests needs to run at the start. + for (auto &GV : M.globals()) { + if (!GV.getName().starts_with("__typeid_") || + !GV.getName().ends_with("_global_addr")) + continue; + auto *MD = MDString::get(M.getContext(), + GV.getName().substr(9, GV.getName().size() - 21)); + auto MaySimplifyPtr = [&](Value *Ptr) { + if (auto *GV = dyn_cast<GlobalValue>(Ptr)) + if (auto *CFIGV = M.getNamedValue((GV->getName() + ".cfi").str())) + Ptr = CFIGV; + return isKnownTypeIdMember(MD, M.getDataLayout(), Ptr, 0); + }; + auto MaySimplifyInt = [&](Value *Op) { + auto *PtrAsInt = dyn_cast<ConstantExpr>(Op); + if (!PtrAsInt || PtrAsInt->getOpcode() != Instruction::PtrToInt) + return false; + return MaySimplifyPtr(PtrAsInt->getOperand(0)); + }; + for (User *U : make_early_inc_range(GV.users())) { + if (auto *CI = dyn_cast<ICmpInst>(U)) { + if (CI->getPredicate() == CmpInst::ICMP_EQ && + MaySimplifyPtr(CI->getOperand(0))) { + // This is an equality comparison (TypeTestResolution::Single case in + // lowerTypeTestCall). In this case we just replace the comparison + // with true. + CI->replaceAllUsesWith(ConstantInt::getTrue(M.getContext())); + CI->eraseFromParent(); + Changed = true; + } + } + auto *CE = dyn_cast<ConstantExpr>(U); + if (!CE || CE->getOpcode() != Instruction::PtrToInt) + continue; + for (Use &U : make_early_inc_range(CE->uses())) { + auto *CE = dyn_cast<ConstantExpr>(U.getUser()); + if (U.getOperandNo() == 1 && CE && + CE->getOpcode() == Instruction::Sub && + MaySimplifyInt(CE->getOperand(0))) { + // This is a computation of PtrOffset as generated by + // LowerTypeTestsModule::lowerTypeTestCall above. If + // isKnownTypeIdMember passes we just pretend it evaluated to 0. This + // should cause later passes to remove the range and alignment checks. + // The bitset checks won't be removed but those are uncommon. + CE->replaceAllUsesWith(ConstantInt::get(CE->getType(), 0)); + Changed = true; + } + auto *CI = dyn_cast<ICmpInst>(U.getUser()); + if (U.getOperandNo() == 1 && CI && + CI->getPredicate() == CmpInst::ICMP_EQ && + MaySimplifyInt(CI->getOperand(0))) { + // This is an equality comparison. Unlike in the case above it + // remained as an integer compare. + CI->replaceAllUsesWith(ConstantInt::getTrue(M.getContext())); + CI->eraseFromParent(); + Changed = true; + } + } + } + } + + if (!Changed) + return PreservedAnalyses::all(); + return PreservedAnalyses::none(); ---------------- pcc wrote:
Okay, I updated this to preserve the CFG related analyses. https://github.com/llvm/llvm-project/pull/141327 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits