[llvm] [InstCombine][AArch64] Lower NEON shift intrinsics when possible (PR #172465)

Nathan Corbyn via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 16 08:39:25 PST 2025


================
@@ -1807,6 +1807,55 @@ foldIntrinsicUsingDistributiveLaws(IntrinsicInst *II,
   return NewBinop;
 }
 
+static Instruction *foldNeonShift(IntrinsicInst *II, InstCombinerImpl &IC) {
+  Value *Arg0 = II->getArgOperand(0);
+  auto *ShiftConst = dyn_cast<Constant>(II->getArgOperand(1));
+  if (!ShiftConst)
+    return nullptr;
+
+  int ElemBits = Arg0->getType()->getScalarSizeInBits();
+  bool Valid = true;
+  bool AllPositive = true;
+  bool AllNegative = true;
+
+  auto Check = [&](Constant *C) -> bool {
+    if (auto *CI = dyn_cast_or_null<ConstantInt>(C)) {
+      const APInt &V = CI->getValue();
+      if (V.isNonNegative()) {
+        AllNegative = false;
+        Valid = AllPositive & V.ult(ElemBits);
+      } else {
+        AllPositive = false;
+        Valid = AllNegative & V.sgt(-ElemBits);
+      }
+    } else {
+      Valid = false;
+    }
+    return Valid;
----------------
cofibrant wrote:

In subsequent code, once `Valid` is set to `false`, we return `nullptr` immediately, so I think this extra state isn't needed. In particular, I think we can get away with:

```suggestion
    if (auto *CI = dyn_cast_or_null<ConstantInt>(C)) {
      const APInt &V = CI->getValue();
      if (V.isNonNegative()) {
        AllNegative = false;
        return AllPositive && V.ult(ElemBits);
      } else {
        AllPositive = false;
        return AllNegative && V.sgt(-ElemBits);
      }
    }
    
    return false;
```

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


More information about the llvm-commits mailing list