[llvm] [AMDGPU] Fix wrong truth table in BitOp3_Op for shared sub-expressions. (PR #198556)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 1 07:52:09 PDT 2026
================
@@ -4401,16 +4401,103 @@ static std::pair<unsigned, uint8_t> BitOp3_Op(SDValue In,
}
// Recursion is naturally limited by the size of the operand vector.
- auto Op = BitOp3_Op(LHS, Src);
- if (Op.first) {
- NumOpcodes += Op.first;
- LHSBits = Op.second;
+ //
+ // When LHS and RHS share a common sub-expression, one side's recursion
+ // may decompose that sub-expression and replace the Src slot the other
+ // side occupies with sub-operands via the "replace parent" path in
+ // getOperandBits. The other side's cached bit-pattern then refers to a
+ // slot whose contents changed, producing a wrong truth table.
+ //
+ // We detect this in three ways:
+ // (A) If LHS recursed, its truth table is valid against the Src state
+ // when LHS recursion completed (SrcAfterLHS). If RHS recursion
+ // then mutates a Src slot that LHSBits depends on, LHSBits is
+ // stale.
+ // (B) If RHS did not recurse, RHSBits came from getOperandBits and
+ // refers to a specific Src slot. If that slot's contents changed
+ // (by either recursion), RHSBits is stale.
+ // (C) Symmetrically for LHS if it did not recurse.
+ SmallVector<SDValue, 3> SrcBeforeRecurse(Src.begin(), Src.end());
----------------
carlobertolli wrote:
I agree with the aesthetic bit, but not allowing multiple uses of a slot is going to make the algorithm miss out on important cases where there is sharing between LHS and RHS. Example:
%t = and i32 %a, %b ; used twice
%x = xor i32 %t, %c
%r = or i32 %x, %t
With the current patch, %t decomposes into %a and %b, everything fits in 3 Src slots [%a, %b, %c]. We end up with a single v_bitop3 instruction.
With a hasOneUse guard, %t has 2 uses, so we refuse to decompose it, and we end up with a v_and and v_or.
It's only by doing a full LHS and RHS recursion that we can check whether we ended up in a pathological case.
https://github.com/llvm/llvm-project/pull/198556
More information about the llvm-commits
mailing list