@@ -14410,12 +14410,57 @@ performFirstTrueTestVectorCombine(SDNode *N,
14410
14410
return getPTest(DAG, N->getValueType(0), Pg, SetCC, AArch64CC::FIRST_ACTIVE);
14411
14411
}
14412
14412
14413
+ // Materialize : Idx = (add (mul vscale, NumEls), -1)
14414
+ // i1 = extract_vector_elt t37, Constant:i64<Idx>
14415
+ // ... into: "ptrue p, all" + PTEST
14416
+ static SDValue
14417
+ performLastTrueTestVectorCombine(SDNode *N,
14418
+ TargetLowering::DAGCombinerInfo &DCI,
14419
+ const AArch64Subtarget *Subtarget) {
14420
+ assert(N->getOpcode() == ISD::EXTRACT_VECTOR_ELT);
14421
+ // Make sure PTEST is legal types.
14422
+ if (!Subtarget->hasSVE() || DCI.isBeforeLegalize())
14423
+ return SDValue();
14424
+
14425
+ SDValue SetCC = N->getOperand(0);
14426
+ EVT OpVT = SetCC.getValueType();
14427
+
14428
+ if (!OpVT.isScalableVector() || OpVT.getVectorElementType() != MVT::i1)
14429
+ return SDValue();
14430
+
14431
+ // Idx == (add (mul vscale, NumEls), -1)
14432
+ SDValue Idx = N->getOperand(1);
14433
+ if (Idx.getOpcode() != ISD::ADD)
14434
+ return SDValue();
14435
+
14436
+ SDValue VS = Idx.getOperand(0);
14437
+ if (VS.getOpcode() != ISD::VSCALE)
14438
+ return SDValue();
14439
+
14440
+ unsigned NumEls = OpVT.getVectorElementCount().getKnownMinValue();
14441
+ if (VS.getConstantOperandVal(0) != NumEls)
14442
+ return SDValue();
14443
+
14444
+ // Restricted the DAG combine to only cases where we're extracting from a
14445
+ // flag-setting operation
14446
+ auto *CI = dyn_cast<ConstantSDNode>(Idx.getOperand(1));
14447
+ if (!CI || !CI->isAllOnes() || SetCC.getOpcode() != ISD::SETCC)
14448
+ return SDValue();
14449
+
14450
+ // Extracts of lane EC-1 for SVE can be expressed as PTEST(Op, LAST) ? 1 : 0
14451
+ SelectionDAG &DAG = DCI.DAG;
14452
+ SDValue Pg = getPTrue(DAG, SDLoc(N), OpVT, AArch64SVEPredPattern::all);
14453
+ return getPTest(DAG, N->getValueType(0), Pg, SetCC, AArch64CC::LAST_ACTIVE);
14454
+ }
14455
+
14413
14456
static SDValue
14414
14457
performExtractVectorEltCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
14415
14458
const AArch64Subtarget *Subtarget) {
14416
14459
assert(N->getOpcode() == ISD::EXTRACT_VECTOR_ELT);
14417
14460
if (SDValue Res = performFirstTrueTestVectorCombine(N, DCI, Subtarget))
14418
14461
return Res;
14462
+ if (SDValue Res = performLastTrueTestVectorCombine(N, DCI, Subtarget))
14463
+ return Res;
14419
14464
14420
14465
SelectionDAG &DAG = DCI.DAG;
14421
14466
SDValue N0 = N->getOperand(0), N1 = N->getOperand(1);
0 commit comments