[llvm] [GlobalISel] Add computeNumSignBits for SHL (PR #152067)

David Green via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 5 00:02:18 PDT 2025


================
@@ -1892,6 +1892,38 @@ unsigned GISelValueTracking::computeNumSignBits(Register R,
       FirstAnswer = std::min<uint64_t>(FirstAnswer + *C, TyBits);
     break;
   }
+  case TargetOpcode::G_SHL: {
+    Register Src1 = MI.getOperand(1).getReg();
+    Register Src2 = MI.getOperand(2).getReg();
+    if (std::optional<ConstantRange> ShAmtRange =
+            getValidShiftAmountRange(Src2, DemandedElts, Depth + 1)) {
+      uint64_t MaxShAmt = ShAmtRange->getUnsignedMax().getZExtValue();
+      uint64_t MinShAmt = ShAmtRange->getUnsignedMin().getZExtValue();
+
+      MachineInstr &ExtMI = *MRI.getVRegDef(Src1);
+      unsigned ExtOpc = ExtMI.getOpcode();
+
+      if (ExtOpc == TargetOpcode::G_SEXT || ExtOpc == TargetOpcode::G_ZEXT ||
+          ExtOpc == TargetOpcode::G_ANYEXT) {
+        LLT ExtTy = MRI.getType(Src1);
+        Register Extendee = ExtMI.getOperand(1).getReg();
+        LLT ExtendeeTy = MRI.getType(Extendee);
+        uint64_t SizeDiff =
+            ExtTy.getScalarSizeInBits() - ExtendeeTy.getScalarSizeInBits();
+
+        if (SizeDiff <= MinShAmt) {
+          unsigned Tmp =
+              SizeDiff + computeNumSignBits(Extendee, DemandedElts, Depth + 1);
+          if (MaxShAmt < Tmp)
+            return Tmp - MaxShAmt;
+        }
+      }
+      unsigned Tmp = computeNumSignBits(Src1, DemandedElts, Depth + 1);
----------------
davemgreen wrote:

Same about keeping the comment for "// shl destroys sign bits, ensure it doesn't shift out all sign bits."

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


More information about the llvm-commits mailing list