[llvm] [AVX-512] make vpternlogq more aggressive for longer chains of bitmanipulations (PR #189971)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 9 03:56:53 PDT 2026
================
@@ -4829,118 +4848,170 @@ bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *N) {
if (!(Subtarget->hasVLX() || NVT.is512BitVector()))
return false;
- auto getFoldableLogicOp = [](SDValue Op) {
- // Peek through single use bitcast.
- if (Op.getOpcode() == ISD::BITCAST && Op.hasOneUse())
- Op = Op.getOperand(0);
-
- if (!Op.hasOneUse())
- return SDValue();
-
- unsigned Opc = Op.getOpcode();
- if (Opc == ISD::AND || Opc == ISD::OR || Opc == ISD::XOR ||
- Opc == X86ISD::ANDNP)
- return Op;
-
- return SDValue();
+ auto IsLogic = [](unsigned Opc) {
+ return Opc == ISD::AND || Opc == ISD::OR || Opc == ISD::XOR ||
+ Opc == X86ISD::ANDNP;
+ };
+ auto IsNot = [](SDValue V) {
+ return V.getOpcode() == ISD::XOR &&
+ ISD::isBuildVectorAllOnes(V.getOperand(1).getNode());
+ };
+ auto PeelBitcast = [](SDValue V) {
+ if (V.getOpcode() == ISD::BITCAST && V.hasOneUse())
+ return V.getOperand(0);
+ return V;
+ };
+ auto IsLoadLike = [](SDValue V) {
+ return isa<LoadSDNode>(V.getNode()) ||
+ V.getOpcode() == X86ISD::VBROADCAST_LOAD;
};
- SDValue N0, N1, A, FoldableOp;
-
- // Identify and (optionally) peel an outer NOT that wraps a pure logic tree
- auto tryPeelOuterNotWrappingLogic = [&](SDNode *Op) {
- if (Op->getOpcode() == ISD::XOR && Op->hasOneUse() &&
- ISD::isBuildVectorAllOnes(Op->getOperand(1).getNode())) {
- SDValue InnerOp = getFoldableLogicOp(Op->getOperand(0));
-
- if (!InnerOp)
- return SDValue();
+ struct Leaf {
+ SDValue V;
+ SDNode *Parent;
+ };
- N0 = InnerOp.getOperand(0);
- N1 = InnerOp.getOperand(1);
- if ((FoldableOp = getFoldableLogicOp(N1))) {
- A = N0;
- return InnerOp;
- }
- if ((FoldableOp = getFoldableLogicOp(N0))) {
- A = N1;
- return InnerOp;
+ // Symbolically evaluate the tree rooted at Root. Opaque, if non-null, is
+ // treated as a leaf even when it is a logic op (used for cascading). On
+ // success fills Leaves (the distinct inputs in seed order, at most three),
+ // Imm and NumOps (the number of logic/NOT nodes folded - a profitability
+ // signal), and returns true. Returns false when more than three distinct
+ // leaves are required. Single-use is required to fold a node; bitcasts are
+ // peeled.
+ auto Evaluate = [&](SDValue Root, SDNode *Opaque,
+ SmallVectorImpl<Leaf> &Leaves, uint8_t &Imm,
+ unsigned &NumOps) -> bool {
+ static constexpr uint8_t Seeds[] = {0xF0, 0xCC, 0xAA};
+ NumOps = 0;
+ std::function<int(SDValue, SDNode *, bool)> Eval =
----------------
RKSimon wrote:
(style) `auto Eval = [&](SDValue Op, SDNode *Parent, bool IsRoot) -> int {`
https://github.com/llvm/llvm-project/pull/189971
More information about the llvm-commits
mailing list