[llvm] [GlobalISel] Add `G_FSHL` and `G_FSHR` to computeKnownBits (PR #191260)

via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 9 11:01:47 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-globalisel

Author: Ayaan (def3r)

<details>
<summary>Changes</summary>

Ported impl from `SelectionDAG::computeKnownBits`.

Tests are based on `AArch64/GlobalISel/knownbits-shl.mir`

Ref: #<!-- -->150515 

---
Full diff: https://github.com/llvm/llvm-project/pull/191260.diff


2 Files Affected:

- (modified) llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp (+34) 
- (added) llvm/test/CodeGen/AArch64/GlobalISel/knownbits-fshl-fshr.mir (+295) 


``````````diff
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index f0b455fbdc7d0..cb1a46abdd086 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -560,6 +560,40 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
     Known.One = Known.One.rotr(Amt);
     break;
   }
+  case TargetOpcode::G_FSHL:
+  case TargetOpcode::G_FSHR: {
+    MachineInstr *AmtOpMI = MRI.getVRegDef(MI.getOperand(3).getReg());
+    auto MaybeAmtOp = isConstantOrConstantSplatVector(*AmtOpMI, MRI);
+    if (!MaybeAmtOp)
+      break;
+
+    unsigned Amt = MaybeAmtOp->urem(BitWidth);
+
+    // For fshl, 0-shift returns the 1st arg.
+    // For fshr, 0-shift returns the 2nd arg.
+    if (Amt == 0) {
+      computeKnownBitsImpl(
+          MI.getOperand(Opcode == TargetOpcode::G_FSHL ? 1 : 2).getReg(), Known,
+          DemandedElts, Depth + 1);
+      break;
+    }
+
+    // fshl: (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
+    // fshr: (X << (BW - (Z % BW))) | (Y >> (Z % BW))
+    computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts,
+                         Depth + 1);
+    computeKnownBitsImpl(MI.getOperand(2).getReg(), Known2, DemandedElts,
+                         Depth + 1);
+    if (Opcode == TargetOpcode::G_FSHL) {
+      Known <<= Amt;
+      Known2 >>= BitWidth - Amt;
+    } else {
+      Known <<= BitWidth - Amt;
+      Known2 >>= Amt;
+    }
+    Known = Known.unionWith(Known2);
+    break;
+  }
   case TargetOpcode::G_INTTOPTR:
   case TargetOpcode::G_PTRTOINT:
     if (DstTy.isVector())
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-fshl-fshr.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-fshl-fshr.mir
new file mode 100644
index 0000000000000..202a40831145e
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-fshl-fshr.mir
@@ -0,0 +1,295 @@
+# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple aarch64 -passes="print<gisel-value-tracking>" %s -o - 2>&1 | FileCheck %s
+
+---
+name:            Cst
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @Cst
+  ; CHECK-NEXT: %0:_ KnownBits:11100000 SignBits:3
+  ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4
+  ; CHECK-NEXT: %2:_ KnownBits:00000010 SignBits:6
+  ; CHECK-NEXT: %3:_ KnownBits:10000000 SignBits:1
+    %0:_(s8) = G_CONSTANT i8 224
+    %1:_(s8) = G_CONSTANT i8 15
+    %2:_(s8) = G_CONSTANT i8 2
+    %3:_(s8) = G_FSHL %0, %1, %2
+...
+---
+name:            CstBig
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @CstBig
+  ; CHECK-NEXT: %0:_ KnownBits:11111001 SignBits:5
+  ; CHECK-NEXT: %1:_ KnownBits:11100000 SignBits:3
+  ; CHECK-NEXT: %2:_ KnownBits:00000110 SignBits:5
+  ; CHECK-NEXT: %3:_ KnownBits:01111000 SignBits:1
+    %0:_(s8) = G_CONSTANT i8 249
+    %1:_(s8) = G_CONSTANT i8 224
+    %2:_(s8) = G_CONSTANT i8 6
+    %3:_(s8) = G_FSHL %0, %1, %2
+...
+---
+name:            CstSext
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @CstSext
+  ; CHECK-NEXT: %0:_ KnownBits:10000001 SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:00000100 SignBits:5
+  ; CHECK-NEXT: %2:_ KnownBits:11111000 SignBits:5
+  ; CHECK-NEXT: %3:_ KnownBits:11100000 SignBits:3
+  ; CHECK-NEXT: %4:_ KnownBits:00000011 SignBits:6
+  ; CHECK-NEXT: %5:_ KnownBits:11000111 SignBits:2
+    %0:_(s8) = G_CONSTANT i8 129
+    %1:_(s8) = G_CONSTANT i8 4
+    %2:_(s8) = G_ASHR %0, %1
+    %3:_(s8) = G_CONSTANT i8 224
+    %4:_(s8) = G_CONSTANT i8 3
+    %5:_(s8) = G_FSHL %2, %3, %4
+...
+---
+name:            CstSextBig
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @CstSextBig
+  ; CHECK-NEXT: %0:_ KnownBits:10000001 SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:00000100 SignBits:5
+  ; CHECK-NEXT: %2:_ KnownBits:11111000 SignBits:5
+  ; CHECK-NEXT: %3:_ KnownBits:11100000 SignBits:3
+  ; CHECK-NEXT: %4:_ KnownBits:00000110 SignBits:5
+  ; CHECK-NEXT: %5:_ KnownBits:00111000 SignBits:2
+    %0:_(s8) = G_CONSTANT i8 129
+    %1:_(s8) = G_CONSTANT i8 4
+    %2:_(s8) = G_ASHR %0, %1
+    %3:_(s8) = G_CONSTANT i8 224
+    %4:_(s8) = G_CONSTANT i8 6
+    %5:_(s8) = G_FSHL %2, %3, %4
+...
+---
+name:            ScalarVar
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @ScalarVar
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1
+    %0:_(s8) = COPY $b0
+    %1:_(s8) = COPY $b1
+    %2:_(s8) = G_FSHL %0, %0, %1
+...
+---
+name:            ScalarCst
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @ScalarCst
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:00000011 SignBits:6
+  ; CHECK-NEXT: %3:_ KnownBits:???????? SignBits:1
+    %0:_(s8) = COPY $b0
+    %1:_(s8) = COPY $b1
+    %2:_(s8) = G_CONSTANT i8 3
+    %3:_(s8) = G_FSHL %0, %1, %2
+...
+---
+name:            VectorSimple
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @VectorSimple
+  ; CHECK-NEXT: %0:_ KnownBits:0000000000010011 SignBits:11
+  ; CHECK-NEXT: %1:_ KnownBits:1111111100000000 SignBits:8
+  ; CHECK-NEXT: %2:_ KnownBits:0000000000000011 SignBits:14
+  ; CHECK-NEXT: %3:_ KnownBits:0000000000010011 SignBits:11
+  ; CHECK-NEXT: %4:_ KnownBits:1111111100000000 SignBits:8
+  ; CHECK-NEXT: %5:_ KnownBits:0000000000000011 SignBits:14
+  ; CHECK-NEXT: %6:_ KnownBits:0000000010011111 SignBits:8
+    %0:_(s16) = G_CONSTANT i16 19
+    %1:_(s16) = G_CONSTANT i16 65280
+    %2:_(s16) = G_CONSTANT i16 3
+    %3:_(<4 x s16>) = G_BUILD_VECTOR %0, %0, %0, %0
+    %4:_(<4 x s16>) = G_BUILD_VECTOR %1, %1, %1, %1
+    %5:_(<4 x s16>) = G_BUILD_VECTOR %2, %2, %2, %2
+    %6:_(<4 x s16>) = G_FSHL %3, %4, %5
+...
+---
+name:            VectorCst
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @VectorCst
+  ; CHECK-NEXT: %0:_ KnownBits:???????????????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????????????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:0000000000000011 SignBits:14
+  ; CHECK-NEXT: %3:_ KnownBits:0000000000000011 SignBits:14
+  ; CHECK-NEXT: %4:_ KnownBits:???????????????? SignBits:1
+    %0:_(<4 x s16>) = COPY $d0
+    %1:_(<4 x s16>) = COPY $d1
+    %2:_(s16) = G_CONSTANT i16 3
+    %3:_(<4 x s16>) = G_BUILD_VECTOR %2, %2, %2, %2
+    %4:_(<4 x s16>) = G_FSHL %0, %1, %3
+...
+---
+name:            VectorCst36
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @VectorCst36
+  ; CHECK-NEXT: %0:_ KnownBits:0000000000000011 SignBits:14
+  ; CHECK-NEXT: %1:_ KnownBits:0000000000000110 SignBits:13
+  ; CHECK-NEXT: %2:_ KnownBits:0000000000000?1? SignBits:13
+  ; CHECK-NEXT: %3:_ KnownBits:0000000000000?1? SignBits:13
+  ; CHECK-NEXT: %4:_ KnownBits:???????????????? SignBits:1
+    %0:_(s16) = G_CONSTANT i16 3
+    %1:_(s16) = G_CONSTANT i16 6
+    %2:_(<4 x s16>) = G_BUILD_VECTOR %0, %1, %1, %0
+    %3:_(<4 x s16>) = G_BUILD_VECTOR %0, %1, %1, %0
+    %4:_(<4 x s16>) = G_FSHL %2, %2, %3
+...
+---
+name:            VectorCst3unknown
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @VectorCst3unknown
+  ; CHECK-NEXT: %0:_ KnownBits:???????????????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????????????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????? SignBits:1
+  ; CHECK-NEXT: %3:_ KnownBits:0000000000000011 SignBits:14
+  ; CHECK-NEXT: %4:_ KnownBits:???????????????? SignBits:1
+  ; CHECK-NEXT: %5:_ KnownBits:???????????????? SignBits:1
+    %0:_(<4 x s16>) = COPY $d0
+    %1:_(<4 x s16>) = COPY $d1
+    %2:_(s16) = COPY $h0
+    %3:_(s16) = G_CONSTANT i16 3
+    %4:_(<4 x s16>) = G_BUILD_VECTOR %2, %3, %3, %2
+    %5:_(<4 x s16>) = G_FSHL %0, %1, %4
+...
+---
+name:            VectorSext
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @VectorSext
+  ; CHECK-NEXT: %0:_ KnownBits:11101110 SignBits:3
+  ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4
+  ; CHECK-NEXT: %2:_ KnownBits:1111111111101110 SignBits:11
+  ; CHECK-NEXT: %3:_ KnownBits:0000000000001111 SignBits:12
+  ; CHECK-NEXT: %4:_ KnownBits:1111111111101110 SignBits:11
+  ; CHECK-NEXT: %5:_ KnownBits:0000000000001111 SignBits:12
+  ; CHECK-NEXT: %6:_ KnownBits:0000000000000011 SignBits:14
+  ; CHECK-NEXT: %7:_ KnownBits:0000000000000110 SignBits:13
+  ; CHECK-NEXT: %8:_ KnownBits:0000000000000?1? SignBits:13
+  ; CHECK-NEXT: %9:_ KnownBits:???????????????? SignBits:1
+    %0:_(s8) = G_CONSTANT i8 238
+    %1:_(s8) = G_CONSTANT i8 15
+    %2:_(s16) = G_SEXT %0(s8)
+    %3:_(s16) = G_SEXT %1(s8)
+    %4:_(<4 x s16>) = G_BUILD_VECTOR %2, %2, %2, %2
+    %5:_(<4 x s16>) = G_BUILD_VECTOR %3, %3, %3, %3
+    %6:_(s16) = G_CONSTANT i16 3
+    %7:_(s16) = G_CONSTANT i16 6
+    %8:_(<4 x s16>) = G_BUILD_VECTOR %6, %7, %7, %6
+    %9:_(<4 x s16>) = G_FSHL %4, %5, %8
+...
+---
+name:            FSHLless
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @FSHLless
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????? SignBits:9
+  ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:9
+  ; CHECK-NEXT: %4:_ KnownBits:0000000000000011 SignBits:14
+  ; CHECK-NEXT: %5:_ KnownBits:???????????????? SignBits:1
+    %0:_(s8) = COPY $b0
+    %1:_(s8) = COPY $b1
+    %2:_(s16) = G_SEXT %0(s8)
+    %3:_(s16) = G_SEXT %1(s8)
+    %4:_(s16) = G_CONSTANT i16 3
+    %5:_(s16) = G_FSHL %2, %3, %4
+...
+---
+name:            FSHLeq
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @FSHLeq
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????? SignBits:9
+  ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:9
+  ; CHECK-NEXT: %4:_ KnownBits:0000000000001000 SignBits:12
+  ; CHECK-NEXT: %5:_ KnownBits:???????????????? SignBits:1
+    %0:_(s8) = COPY $b0
+    %1:_(s8) = COPY $b1
+    %2:_(s16) = G_SEXT %0(s8)
+    %3:_(s16) = G_SEXT %1(s8)
+    %4:_(s16) = G_CONSTANT i16 8
+    %5:_(s16) = G_FSHL %2, %3, %4
+...
+---
+name:            FSHLmore
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @FSHLmore
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????? SignBits:9
+  ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:9
+  ; CHECK-NEXT: %4:_ KnownBits:0000000000001101 SignBits:12
+  ; CHECK-NEXT: %5:_ KnownBits:???????????????? SignBits:1
+    %0:_(s8) = COPY $b0
+    %1:_(s8) = COPY $b1
+    %2:_(s16) = G_SEXT %0(s8)
+    %3:_(s16) = G_SEXT %1(s8)
+    %4:_(s16) = G_CONSTANT i16 13
+    %5:_(s16) = G_FSHL %2, %3, %4
+...
+---
+name:            SignBitsThroughZext
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @SignBitsThroughZext
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:0000000000000011 SignBits:14
+  ; CHECK-NEXT: %3:_ KnownBits:???????? SignBits:4
+  ; CHECK-NEXT: %4:_ KnownBits:???????? SignBits:4
+  ; CHECK-NEXT: %5:_ KnownBits:00000000???????? SignBits:8
+  ; CHECK-NEXT: %6:_ KnownBits:00000000???????? SignBits:8
+  ; CHECK-NEXT: %7:_ KnownBits:0000000000001000 SignBits:12
+  ; CHECK-NEXT: %8:_ KnownBits:????????00000000 SignBits:1
+    %0:_(s8) = COPY $b0
+    %1:_(s8) = COPY $b1
+    %2:_(s16) = G_CONSTANT i16 3
+    %3:_(s8) = G_ASHR %0, %2
+    %4:_(s8) = G_ASHR %1, %2
+    %5:_(s16) = G_ZEXT %3
+    %6:_(s16) = G_ZEXT %4
+    %7:_(s16) = G_CONSTANT i16 8
+    %8:_(s16) = G_FSHL %5, %6, %7
+...
+---
+name:            FSHLZeroAmt
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @FSHLZeroAmt
+  ; CHECK-NEXT: %0:_ KnownBits:11100010 SignBits:3
+  ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4
+  ; CHECK-NEXT: %2:_ KnownBits:00000000 SignBits:8
+  ; CHECK-NEXT: %3:_ KnownBits:11100010 SignBits:3
+    %0:_(s8) = G_CONSTANT i8 226
+    %1:_(s8) = G_CONSTANT i8 15
+    %2:_(s8) = G_CONSTANT i8 0
+    %3:_(s8) = G_FSHL %0, %1, %2
+...
+---
+name:            FSHRZeroAmt
+body:             |
+  bb.1:
+  ; CHECK-LABEL: name: @FSHRZeroAmt
+  ; CHECK-NEXT: %0:_ KnownBits:11100010 SignBits:3
+  ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4
+  ; CHECK-NEXT: %2:_ KnownBits:00000000 SignBits:8
+  ; CHECK-NEXT: %3:_ KnownBits:00001111 SignBits:4
+    %0:_(s8) = G_CONSTANT i8 226
+    %1:_(s8) = G_CONSTANT i8 15
+    %2:_(s8) = G_CONSTANT i8 0
+    %3:_(s8) = G_FSHR %0, %1, %2
+...

``````````

</details>


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


More information about the llvm-commits mailing list