[llvm] [AArch64] Simplify some masked integer comparisons. (PR #153783)

Paul Walker via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 12 04:59:09 PDT 2025


================
@@ -25037,6 +25037,32 @@ SDValue performCONDCombine(SDNode *N,
                                              CmpIndex, CC))
     return Val;
 
+  // X & M ?= C --> (C << clz(M)) ?= (X << clz(M)) where M is a non-empty
+  // sequence of ones starting at the least significant bit with the remainder
+  // zero and C is a constant s.t. (C & ~M) == 0 that cannot be materialised
+  // into a SUBS (immediate). The transformed form can be matched into a SUBS
+  // (shifted register).
+  if ((CC == AArch64CC::EQ || CC == AArch64CC::NE) && AndNode->hasOneUse() &&
+      isa<ConstantSDNode>(AndNode->getOperand(1)) &&
+      isa<ConstantSDNode>(SubsNode->getOperand(1))) {
+    SDValue X = AndNode->getOperand(0);
+    APInt M = AndNode->getConstantOperandAPInt(1);
+    APInt C = SubsNode->getConstantOperandAPInt(1);
+
+    if (M.isMask() && !(C & ~M) && (C & 0xfff) != C && (C & 0xfff000) != C) {
----------------
paulwalker-arm wrote:

```suggestion
    if (M.isMask() && C.isSubsetOf(M) && (C & 0xfff) != C && (C & 0xfff000) != C) {
```
Perhaps it's worth moving `(C & 0xfff) != C && (C & 0xfff000)` into a `AArch64AddressingModes.h` helper function? There's likely other places where this is done that others can clean up once you start the ball rolling.

https://github.com/llvm/llvm-project/pull/153783


More information about the llvm-commits mailing list