[llvm] [AArch64][SVE2] Lower OR to SLI/SRI (PR #77555)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 10 07:24:52 PST 2024
================
@@ -12569,32 +12623,52 @@ static SDValue tryLowerToSLI(SDNode *N, SelectionDAG &DAG) {
// Is one of the operands an AND or a BICi? The AND may have been optimised to
// a BICi in order to use an immediate instead of a register.
// Is the other operand an shl or lshr? This will have been turned into:
- // AArch64ISD::VSHL vector, #shift or AArch64ISD::VLSHR vector, #shift.
+ // AArch64ISD::VSHL vector, #shift or AArch64ISD::VLSHR vector, #shift
+ // or (AArch64ISD::SHL_PRED || AArch64ISD::SRL_PRED) mask, vector, #shiftVec.
if ((FirstOpc == ISD::AND || FirstOpc == AArch64ISD::BICi) &&
- (SecondOpc == AArch64ISD::VSHL || SecondOpc == AArch64ISD::VLSHR)) {
+ (SecondOpc == AArch64ISD::VSHL || SecondOpc == AArch64ISD::VLSHR ||
+ SecondOpc == AArch64ISD::SHL_PRED ||
+ SecondOpc == AArch64ISD::SRL_PRED)) {
And = FirstOp;
Shift = SecondOp;
} else if ((SecondOpc == ISD::AND || SecondOpc == AArch64ISD::BICi) &&
- (FirstOpc == AArch64ISD::VSHL || FirstOpc == AArch64ISD::VLSHR)) {
+ (FirstOpc == AArch64ISD::VSHL || FirstOpc == AArch64ISD::VLSHR ||
+ FirstOpc == AArch64ISD::SHL_PRED ||
+ FirstOpc == AArch64ISD::SRL_PRED)) {
And = SecondOp;
Shift = FirstOp;
} else
return SDValue();
bool IsAnd = And.getOpcode() == ISD::AND;
- bool IsShiftRight = Shift.getOpcode() == AArch64ISD::VLSHR;
-
- // Is the shift amount constant?
- ConstantSDNode *C2node = dyn_cast<ConstantSDNode>(Shift.getOperand(1));
- if (!C2node)
+ bool IsShiftRight = Shift.getOpcode() == AArch64ISD::VLSHR ||
+ Shift.getOpcode() == AArch64ISD::SRL_PRED;
+ bool ShiftHasPredOp = Shift.getOpcode() == AArch64ISD::SHL_PRED ||
+ Shift.getOpcode() == AArch64ISD::SRL_PRED;
+
+ // Is the shift amount constant and are all lanes active?
+ uint64_t C2;
+ if (ShiftHasPredOp) {
+ if (!isAllActivePredicate(DAG, Shift.getOperand(0)))
+ return SDValue();
+ APInt C;
+ if (!ISD::isConstantSplatVector(Shift.getOperand(2).getNode(), C))
+ return SDValue();
+ C2 = C.getZExtValue();
+ } else if (ConstantSDNode *C2node =
+ dyn_cast<ConstantSDNode>(Shift.getOperand(1)))
+ C2 = C2node->getZExtValue();
+ else
return SDValue();
uint64_t C1;
if (IsAnd) {
// Is the and mask vector all constant?
- if (!isAllConstantBuildVector(And.getOperand(1), C1))
+ APInt C;
+ if (!ISD::isConstantSplatVector(And.getOperand(1).getNode(), C))
----------------
davemgreen wrote:
We use C1AsAPInt below. Can we just grab that directly?
https://github.com/llvm/llvm-project/pull/77555
More information about the llvm-commits
mailing list