[llvm] [AArch64] Avoid selecting XAR for reverse operations. (PR #178706)
Ricardo Jesus via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 9 05:57:38 PST 2026
================
@@ -20771,6 +20771,97 @@ static SDValue performANDORCSELCombine(SDNode *N, SelectionDAG &DAG) {
CSel0.getOperand(1), getCondCode(DAG, CC1), CCmp);
}
+// Attempt to use REVs for half-rotations of vectors of i32 and i64.
+// Patterns for i32:
+//
+// (OR (SHL_PRED all-true, X, (splat 16)),
+// (SRL_PRED all-true, X, (splat 16)))
+// =>
+// REVH all-true, X, poison
+//
+// (OR (VSHL X, 16), (VLSHR X, 16))
+// =>
+// NVCAST (REV32 X)
+static SDValue tryCombineToREV(SDNode *N, SelectionDAG &DAG) {
+ assert(N->getOpcode() == ISD::OR && "Expected OR instruction");
+
+ EVT VT = N->getValueType(0);
+ if (!VT.isVector())
+ return SDValue();
+
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ unsigned EltSize = VT.getScalarSizeInBits();
+
+ // Half rotations of i16 vectors should be lowered to a bswap, so we shouldn't
+ // need custom code for them here.
+ if (EltSize != 32 && EltSize != 64)
+ return SDValue();
+
+ if (VT.isScalableVector()) {
+ if (N0.getOpcode() != AArch64ISD::SHL_PRED ||
+ N1.getOpcode() != AArch64ISD::SRL_PRED)
+ return SDValue();
+
+ // Ensure we have common inputs.
+ if (N0.getOperand(0) != N1.getOperand(0) ||
+ N0.getOperand(1) != N1.getOperand(1) ||
+ N0.getOperand(2) != N1.getOperand(2))
+ return SDValue();
+
+ // Check for all-true predicate.
+ // NOTE: Since SHL_PRED and SRL_PRED are defined ``with the result of
+ // inactive lanes being unspecified'', this shouldn't be required.
+ SDValue Pg = N0.getOperand(0);
+ if (!isAllActivePredicate(DAG, Pg))
+ return SDValue();
----------------
rj-jesus wrote:
I was being paranoid - I've now removed this and added a few tests with predicated shifts to show the new behaviour. :)
https://github.com/llvm/llvm-project/pull/178706
More information about the llvm-commits
mailing list