[llvm] [SeparateConstOffsetFromGEP] Decompose constant xor operand if possible (PR #150438)

Jeffrey Byrnes via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 24 13:23:58 PDT 2025


================
@@ -780,6 +807,80 @@ Value *ConstantOffsetExtractor::removeConstOffset(unsigned ChainIndex) {
   return NewBO;
 }
 
+// Find the most dominating Xor with the same base operand.
+BinaryOperator *
+ConstantOffsetExtractor::findDominatingXor(Value *BaseOperand,
+                                           BinaryOperator *CurrentXor) {
+  BinaryOperator *MostDominatingXor = nullptr;
+  // Iterate over all instructions that use the BaseOperand.
+  for (User *U : BaseOperand->users()) {
+    auto *CandidateXor = dyn_cast<BinaryOperator>(U);
+
+    // Simple checks.
+    if (!CandidateXor || CandidateXor == CurrentXor)
+      continue;
+
+    // Check if the binary operator is a Xor with constant.
+    if (!match(CandidateXor, m_Xor(m_Specific(BaseOperand), m_ConstantInt())))
+      continue;
+
+    // After confirming the structure, check the dominance relationship.
+    if (DT->dominates(CandidateXor, CurrentXor))
+      // If we find a dominating Xor, keep it if it's the first one,
+      // or if it dominates the best candidate we've found so far.
+      if (!MostDominatingXor || DT->dominates(CandidateXor, MostDominatingXor))
+        MostDominatingXor = CandidateXor;
+  }
+
+  return MostDominatingXor;
+}
+
+// Check if Xor should be considered.
+// Only the following idiom is considered.
+// Example:
+// %3 = xor i32 %2, 32
+// %4 = xor i32 %2, 8224
+// %6 = getelementptr half, ptr addrspace(3) %1, i32 %3
+// %7 = getelementptr half, ptr addrspace(3) %1, i32 %4
+// GEP that corresponds to %7, looks at the binary operator %4.
+// In order for %4 to be considered, it should have a dominating xor with
+// constant offset that is disjoint with an adjusted offset.
+// If disjoint, %4 = xor i32 %2, 8224 can be treated as %4 = add i32 %3, 8192
+bool ConstantOffsetExtractor::shouldConsiderXor(BinaryOperator *XorInst) {
+
+  Value *BaseOperand = nullptr;
+  ConstantInt *CurrentConst = nullptr;
+  if (!match(XorInst, m_Xor(m_Value(BaseOperand), m_ConstantInt(CurrentConst))))
+    return false;
+
+  // Find the most dominating Xor with the same base operand.
+  BinaryOperator *DominatingXor = findDominatingXor(BaseOperand, XorInst);
+  if (!DominatingXor)
----------------
jrbyrnes wrote:

There are cases where we can extract a constant offset even if there is no dominating xor. 

https://github.com/llvm/llvm-project/pull/150438


More information about the llvm-commits mailing list