[llvm] [SeparateConstOffsetFromGEP] Decompose constant xor operand if possible (PR #135788)
Juan Manuel Martinez CaamaƱo via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 23 02:50:49 PDT 2025
================
@@ -1162,6 +1167,179 @@ bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *GEP) {
return true;
}
+bool SeparateConstOffsetFromGEP::decomposeXor(Function &F) {
+ bool FunctionChanged = false;
+ SmallVector<std::pair<Instruction *, Value *>, 16> ReplacementsToMake;
+
+ for (BasicBlock &BB : F) {
+ for (Instruction &I : BB) {
+ if (I.getOpcode() == Instruction::Xor) {
+ if (Value *Replacement = tryFoldXorToOrDisjoint(I)) {
+ ReplacementsToMake.push_back({&I, Replacement});
+ FunctionChanged = true;
+ }
+ }
+ }
+ }
+
+ if (!ReplacementsToMake.empty()) {
+ LLVM_DEBUG(dbgs() << "Applying " << ReplacementsToMake.size()
+ << " XOR->OR Disjoint replacements in " << F.getName()
+ << "\n");
+ for (auto &Pair : ReplacementsToMake)
+ Pair.first->replaceAllUsesWith(Pair.second);
+
+ for (auto &Pair : ReplacementsToMake)
+ Pair.first->eraseFromParent();
+ }
+
+ return FunctionChanged;
+}
+
+static llvm::Instruction *findClosestSequentialXor(Value *A, Instruction &I) {
+ llvm::Instruction *ClosestUser = nullptr;
+ for (llvm::User *User : A->users()) {
+ if (auto *UserInst = llvm::dyn_cast<llvm::Instruction>(User)) {
+ if (UserInst->getOpcode() != Instruction::Xor || UserInst == &I)
+ continue;
+ if (!ClosestUser)
+ ClosestUser = UserInst;
+ else {
+ // Compare instruction positions.
+ if (UserInst->comesBefore(ClosestUser)) {
----------------
jmmartinez wrote:
I don't understand what does "Closest" mean. It's the `xor` that is the nearest to `A` (and that is not `&I`) ? Or the nearest to `&I` ? Should it dominate `&I` or not ?
I think that what you're really looking for is a `xor` that has `A` and a constant as operands and that dominate `&I`.
https://github.com/llvm/llvm-project/pull/135788
More information about the llvm-commits
mailing list