[llvm] [LLVM][AArch64] Correctly lower funnel shifts by zero. (PR #140058)

Jay Foad via llvm-commits llvm-commits at lists.llvm.org
Thu May 15 08:48:06 PDT 2025


================
@@ -7259,21 +7259,30 @@ static SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) {
 // FSHL is converted to FSHR before deciding what to do with it
 static SDValue LowerFunnelShift(SDValue Op, SelectionDAG &DAG) {
   SDValue Shifts = Op.getOperand(2);
-  // Check if the shift amount is a constant
+  // Check if the shift amount is a constant and normalise to [0, SrcBitLen)
   // If opcode is FSHL, convert it to FSHR
   if (auto *ShiftNo = dyn_cast<ConstantSDNode>(Shifts)) {
     SDLoc DL(Op);
     MVT VT = Op.getSimpleValueType();
+    unsigned int NewShiftNo = ShiftNo->getZExtValue() % VT.getFixedSizeInBits();
 
     if (Op.getOpcode() == ISD::FSHL) {
-      unsigned int NewShiftNo =
-          VT.getFixedSizeInBits() - ShiftNo->getZExtValue();
+      if (NewShiftNo == 0)
+        return Op.getOperand(0);
+
+      NewShiftNo = VT.getFixedSizeInBits() - NewShiftNo;
+    } else if (Op.getOpcode() == ISD::FSHR) {
+      if (NewShiftNo == 0)
+        return Op.getOperand(1);
+
+      if (ShiftNo->getZExtValue() == NewShiftNo)
+        return Op;
+    }
+
+    if (ShiftNo->getZExtValue() != NewShiftNo)
----------------
jayfoad wrote:

I find the code flow pretty hard to follow, but isn't this going to mishandle an i32 fshl by constant 16? The new and original shift amounts will be the same, so this will _not_ convert it to fshr.

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


More information about the llvm-commits mailing list