[llvm] [GlobalISel] Add G_BITCAST to computeKnownBits (PR #216287)

Xaver Fabian via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 08:58:58 PDT 2026


https://github.com/XFabian updated https://github.com/llvm/llvm-project/pull/216287

>From 08eb90c8e8366d1a13e589e276d05e521cdfd57e Mon Sep 17 00:00:00 2001
From: Xaver Fabian <xaver.fabian at gmail.com>
Date: Fri, 14 Aug 2026 10:30:00 +0200
Subject: [PATCH 1/4] [GlobalISel] Pre-commit tests for G_BITCAST in
 computeKnownBits.

---
 .../AArch64/GlobalISel/knownbits-bitcast.mir  | 148 ++++++++++++++++++
 1 file changed, 148 insertions(+)
 create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir
new file mode 100644
index 0000000000000..9d9db9eb3841f
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir
@@ -0,0 +1,148 @@
+# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple aarch64 -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s --check-prefixes=CHECK,LE
+# RUN: llc -mtriple aarch64_be -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s --check-prefixes=CHECK,BE
+
+---
+name: bitcast_splat_constant
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @bitcast_splat_constant
+  ; CHECK-NEXT: %c:_ KnownBits:00001111 SignBits:4 IsKnownNeverZero:1
+  ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4 IsKnownNeverZero:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????? SignBits:1 IsKnownNeverZero:0
+    %c:_(i8) = G_CONSTANT i8 15
+    %1:_(<4 x i8>) = G_BUILD_VECTOR %c(i8), %c(i8), %c(i8), %c(i8)
+    %2:_(<2 x i16>) = G_BITCAST %1(<4 x i8>)
+...
+---
+name: bitcast_small_large_vector
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @bitcast_small_large_vector
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %zext0:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:1 IsKnownNeverZero:0
+    %0:_(<4 x i8>) = COPY $s0
+    %zext0:_(<4 x i16>) = G_ZEXT %0
+    %2:_(<2 x i32>) = G_BITCAST %zext0(<4 x i16>)
+...
+---
+name: bitcast_large_small_vector
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @bitcast_large_small_vector
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %m:_ KnownBits:0000111100001111 SignBits:4 IsKnownNeverZero:1
+  ; CHECK-NEXT: %mv:_ KnownBits:0000111100001111 SignBits:4 IsKnownNeverZero:1
+  ; CHECK-NEXT: %zext0:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
+  ; CHECK-NEXT: %masked:_ KnownBits:000000000000???? SignBits:12 IsKnownNeverZero:0
+  ; CHECK-NEXT: %5:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+    %0:_(<4 x i8>) = COPY $s0
+    %m:_(i16) = G_CONSTANT i16 3855                       ; 0x0F0F
+    %mv:_(<4 x i16>) = G_BUILD_VECTOR %m(i16), %m(i16), %m(i16), %m(i16)
+    %zext0:_(<4 x i16>) = G_ZEXT %0
+    %masked:_(<4 x i16>) = G_AND %zext0, %mv
+    %5:_(<8 x i8>) = G_BITCAST %masked(<4 x i16>)
+...
+---
+name: bitcast_small_large_scalar
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @bitcast_small_large_scalar
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %zext0:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+    %0:_(<4 x i8>) = COPY $s0
+    %zext0:_(<4 x i16>) = G_ZEXT %0
+    %2:_(i64) = G_BITCAST %zext0(<4 x i16>)
+...
+---
+name: bitcast_large_small_scalar
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @bitcast_large_small_scalar
+  ; CHECK-NEXT: %m:_ KnownBits:0000111100001111 SignBits:4 IsKnownNeverZero:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+    %m:_(i16) = G_CONSTANT i16 3855                       ; 0x0F0F
+    %1:_(<2 x i8>) = G_BITCAST %m(i16)
+...
+---
+name: bitcast_int_float_vector
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @bitcast_int_float_vector
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %zext0:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????? SignBits:1 IsKnownNeverZero:0
+    %0:_(<4 x i8>) = COPY $s0
+    %zext0:_(<4 x i16>) = G_ZEXT %0
+    %2:_(<4 x f16>) = G_BITCAST %zext0(<4 x i16>)
+...
+---
+name: bitcast_int_float
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @bitcast_int_float
+  ; CHECK-NEXT: %m:_ KnownBits:0000111100001111 SignBits:4 IsKnownNeverZero:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????????????? SignBits:1 IsKnownNeverZero:0
+    %m:_(i16) = G_CONSTANT i16 3855
+    %1:_(f16) = G_BITCAST %m(i16)
+...
+---
+name: bitcast_address_space
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @bitcast_address_space
+  ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+    %0:_(p0) = COPY $x0
+    %1:_(p1) = G_BITCAST %0(p0)
+...
+---
+name: bitcast_small_large_alternating
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @bitcast_small_large_alternating
+  ; CHECK-NEXT: %c:_ KnownBits:11111111 SignBits:8 IsKnownNeverZero:1
+  ; CHECK-NEXT: %d:_ KnownBits:00000000 SignBits:8 IsKnownNeverZero:0
+  ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:8 IsKnownNeverZero:0
+  ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:1 IsKnownNeverZero:0
+    %c:_(i8) = G_CONSTANT i8 255
+    %d:_(i8) = G_CONSTANT i8 0
+    %1:_(<4 x i8>) = G_BUILD_VECTOR %c(i8), %d(i8), %c(i8), %d(i8)
+    %2:_(<2 x i16>) = G_BITCAST %1(<4 x i8>)
+...
+---
+name: bitcast_small_large_partial
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @bitcast_small_large_partial
+  ; CHECK-NEXT: %a:_ KnownBits:0000000011111111 SignBits:8 IsKnownNeverZero:1
+  ; CHECK-NEXT: %b:_ KnownBits:0000111111110000 SignBits:4 IsKnownNeverZero:1
+  ; CHECK-NEXT: %c:_ KnownBits:0000111100001111 SignBits:4 IsKnownNeverZero:1
+  ; CHECK-NEXT: %d:_ KnownBits:0011110000111100 SignBits:2 IsKnownNeverZero:1
+  ; CHECK-NEXT: %v:_ KnownBits:00?????????????? SignBits:2 IsKnownNeverZero:1
+  ; CHECK-NEXT: %r:_ KnownBits:???????????????????????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %i:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000000 SignBits:64 IsKnownNeverZero:0
+  ; CHECK-NEXT: %e:_ KnownBits:???????????????????????????????? SignBits:1 IsKnownNeverZero:0
+    %a:_(i16) = G_CONSTANT i16 255        ; 0x00FF
+    %b:_(i16) = G_CONSTANT i16 4080       ; 0x0FF0
+    %c:_(i16) = G_CONSTANT i16 3855       ; 0xF0F0
+    %d:_(i16) = G_CONSTANT i16 15420      ; 0x3C3C
+    %v:_(<4 x i16>) = G_BUILD_VECTOR %a(i16), %b(i16), %c(i16), %d(i16)
+    %r:_(<2 x i32>) = G_BITCAST %v(<4 x i16>)
+    %i:_(i64) = G_CONSTANT i64 0
+    %e:_(i32) = G_EXTRACT_VECTOR_ELT %r, %i
+...
+---
+name: bitcast_anyscalar_unsupported
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @bitcast_anyscalar_unsupported
+  ; CHECK-NEXT: %c:_ KnownBits:00001111 SignBits:4 IsKnownNeverZero:1
+  ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4 IsKnownNeverZero:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????? SignBits:1 IsKnownNeverZero:0
+    %c:_(s8) = G_CONSTANT i8 15
+    %1:_(<4 x s8>) = G_BUILD_VECTOR %c(s8), %c(s8), %c(s8), %c(s8)
+    %2:_(<2 x s16>) = G_BITCAST %1(<4 x s8>)
+...

>From 10333ae83a8e124c3c543d336b58bb50594558e9 Mon Sep 17 00:00:00 2001
From: Xaver Fabian <xaver.fabian at gmail.com>
Date: Fri, 14 Aug 2026 11:17:53 +0200
Subject: [PATCH 2/4] [GlobalISel] Add G_BITCAST to computeKnownBitsImpl.

---
 .../CodeGen/GlobalISel/GISelValueTracking.cpp |  65 +++++++
 .../compute-known-bits-bitcast-assertion.ll   |   1 -
 .../AArch64/GlobalISel/knownbits-bitcast.mir  |  58 +++---
 llvm/test/CodeGen/AMDGPU/GlobalISel/andn2.ll  |   7 +-
 llvm/test/CodeGen/AMDGPU/GlobalISel/orn2.ll   |   7 +-
 .../AMDGPU/GlobalISel/shl-ext-reduce.ll       |   3 -
 .../test/CodeGen/AMDGPU/GlobalISel/uaddsat.ll | 174 ++++++------------
 .../test/CodeGen/AMDGPU/GlobalISel/usubsat.ll | 174 ++++++------------
 llvm/test/CodeGen/AMDGPU/v_sat_pk_u8_i16.ll   |   8 +-
 9 files changed, 225 insertions(+), 272 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index b7038765c7665..7b1a5482e1e75 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -1117,6 +1117,71 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
     }
     break;
   }
+  case TargetOpcode::G_BITCAST: {
+    if (DstTy.isScalableVector())
+      break;
+    Register SrcReg = MI.getOperand(1).getReg();
+    LLT SrcTy = MRI.getType(SrcReg);
+    unsigned SrcBitWidth = SrcTy.getScalarSizeInBits();
+    unsigned NumElts = DemandedElts.getBitWidth();
+    // Ignore bitcasts from unsupported types.
+    if (!(SrcTy.isInteger() || SrcTy.isIntegerVector() ||
+          SrcTy.isFloatOrFloatVector()))
+      break;
+
+    // Fast handling of 'identity' bitcasts.
+    if (BitWidth == SrcBitWidth) {
+      computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1);
+      break;
+    }
+
+    bool IsLE = getDataLayout().isLittleEndian();
+    // Bitcast 'small element' vector to 'large element' scalar/vector.
+    if ((BitWidth % SrcBitWidth) == 0) {
+      assert(SrcTy.isVector() && "Expected bitcast from vector");
+      // Collect known bits for the (larger) output by collecting the known
+      // bits from each set of sub elements and shift these into place.
+      // We need to separately call computeKnownBits for each set of
+      // sub elements as the knownbits for each is likely to be different.
+      unsigned SubScale = BitWidth / SrcBitWidth;
+      APInt SubDemandedElts(NumElts * SubScale, 0);
+      for (unsigned i = 0; i != NumElts; ++i)
+        if (DemandedElts[i])
+          SubDemandedElts.setBit(i * SubScale);
+      for (unsigned i = 0; i != SubScale; ++i) {
+        computeKnownBitsImpl(SrcReg, Known2, SubDemandedElts.shl(i), Depth + 1);
+        unsigned Shifts = IsLE ? i : SubScale - 1 - i;
+        Known.insertBits(Known2, SrcBitWidth * Shifts);
+      }
+    }
+
+    // Bitcast 'large element' scalar/vector to 'small element' vector.
+    if ((SrcBitWidth % BitWidth) == 0) {
+      assert(DstTy.isVector() && "Expected bitcast to vector");
+
+      // Collect known bits for the (smaller) output by collecting the known
+      // bits from the overlapping larger input elements and extracting the
+      // sub sections we actually care about.
+      unsigned SubScale = SrcBitWidth / BitWidth;
+
+      APInt SubDemandedElts =
+          APIntOps::ScaleBitMask(DemandedElts, NumElts / SubScale);
+      computeKnownBitsImpl(SrcReg, Known2, SubDemandedElts, Depth + 1);
+
+      Known.setAllConflict();
+
+      for (unsigned i = 0; i != NumElts; ++i)
+        if (DemandedElts[i]) {
+          unsigned Shifts = IsLE ? i : NumElts - 1 - i;
+          unsigned Offset = (Shifts % SubScale) * BitWidth;
+          Known = Known.intersectWith(Known2.extractBits(BitWidth, Offset));
+          // If we don't know any bits, early out.
+          if (Known.isUnknown())
+            break;
+        }
+    }
+    break;
+  }
   case TargetOpcode::G_ABS: {
     Register SrcReg = MI.getOperand(1).getReg();
     computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1);
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/compute-known-bits-bitcast-assertion.ll b/llvm/test/CodeGen/AArch64/GlobalISel/compute-known-bits-bitcast-assertion.ll
index 2002eee0be690..37e4f206bb3cb 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/compute-known-bits-bitcast-assertion.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/compute-known-bits-bitcast-assertion.ll
@@ -13,7 +13,6 @@ define <2 x i8> @test_bitcast_assertion(<4 x i32> %vqaddq_v2.i.i, ptr %BS_VAR_0)
 ; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
 ; CHECK-NEXT:    umov w10, v1.h[0]
 ; CHECK-NEXT:    str q0, [sp]
-; CHECK-NEXT:    and x10, x10, #0x3
 ; CHECK-NEXT:    umull x10, w10, w9
 ; CHECK-NEXT:    ldrh w10, [x8, x10]
 ; CHECK-NEXT:    stp q1, q1, [x0, #32]
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir
index 9d9db9eb3841f..64d34f78c2db3 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir
@@ -9,7 +9,7 @@ body: |
   ; CHECK-LABEL: name: @bitcast_splat_constant
   ; CHECK-NEXT: %c:_ KnownBits:00001111 SignBits:4 IsKnownNeverZero:1
   ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4 IsKnownNeverZero:1
-  ; CHECK-NEXT: %2:_ KnownBits:???????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %2:_ KnownBits:0000111100001111 SignBits:4 IsKnownNeverZero:1
     %c:_(i8) = G_CONSTANT i8 15
     %1:_(<4 x i8>) = G_BUILD_VECTOR %c(i8), %c(i8), %c(i8), %c(i8)
     %2:_(<2 x i16>) = G_BITCAST %1(<4 x i8>)
@@ -21,7 +21,7 @@ body: |
   ; CHECK-LABEL: name: @bitcast_small_large_vector
   ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
   ; CHECK-NEXT: %zext0:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
-  ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %2:_ KnownBits:00000000????????00000000???????? SignBits:8 IsKnownNeverZero:0
     %0:_(<4 x i8>) = COPY $s0
     %zext0:_(<4 x i16>) = G_ZEXT %0
     %2:_(<2 x i32>) = G_BITCAST %zext0(<4 x i16>)
@@ -36,7 +36,7 @@ body: |
   ; CHECK-NEXT: %mv:_ KnownBits:0000111100001111 SignBits:4 IsKnownNeverZero:1
   ; CHECK-NEXT: %zext0:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
   ; CHECK-NEXT: %masked:_ KnownBits:000000000000???? SignBits:12 IsKnownNeverZero:0
-  ; CHECK-NEXT: %5:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %5:_ KnownBits:0000???? SignBits:4 IsKnownNeverZero:0
     %0:_(<4 x i8>) = COPY $s0
     %m:_(i16) = G_CONSTANT i16 3855                       ; 0x0F0F
     %mv:_(<4 x i16>) = G_BUILD_VECTOR %m(i16), %m(i16), %m(i16), %m(i16)
@@ -51,7 +51,7 @@ body: |
   ; CHECK-LABEL: name: @bitcast_small_large_scalar
   ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
   ; CHECK-NEXT: %zext0:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
-  ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %2:_ KnownBits:00000000????????00000000????????00000000????????00000000???????? SignBits:8 IsKnownNeverZero:0
     %0:_(<4 x i8>) = COPY $s0
     %zext0:_(<4 x i16>) = G_ZEXT %0
     %2:_(i64) = G_BITCAST %zext0(<4 x i16>)
@@ -62,7 +62,7 @@ body: |
   bb.0:
   ; CHECK-LABEL: name: @bitcast_large_small_scalar
   ; CHECK-NEXT: %m:_ KnownBits:0000111100001111 SignBits:4 IsKnownNeverZero:1
-  ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4 IsKnownNeverZero:1
     %m:_(i16) = G_CONSTANT i16 3855                       ; 0x0F0F
     %1:_(<2 x i8>) = G_BITCAST %m(i16)
 ...
@@ -73,7 +73,7 @@ body: |
   ; CHECK-LABEL: name: @bitcast_int_float_vector
   ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
   ; CHECK-NEXT: %zext0:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
-  ; CHECK-NEXT: %2:_ KnownBits:???????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %2:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
     %0:_(<4 x i8>) = COPY $s0
     %zext0:_(<4 x i16>) = G_ZEXT %0
     %2:_(<4 x f16>) = G_BITCAST %zext0(<4 x i16>)
@@ -84,7 +84,7 @@ body: |
   bb.0:
   ; CHECK-LABEL: name: @bitcast_int_float
   ; CHECK-NEXT: %m:_ KnownBits:0000111100001111 SignBits:4 IsKnownNeverZero:1
-  ; CHECK-NEXT: %1:_ KnownBits:???????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %1:_ KnownBits:0000111100001111 SignBits:4 IsKnownNeverZero:1
     %m:_(i16) = G_CONSTANT i16 3855
     %1:_(f16) = G_BITCAST %m(i16)
 ...
@@ -102,11 +102,17 @@ body: |
 name: bitcast_small_large_alternating
 body: |
   bb.0:
-  ; CHECK-LABEL: name: @bitcast_small_large_alternating
-  ; CHECK-NEXT: %c:_ KnownBits:11111111 SignBits:8 IsKnownNeverZero:1
-  ; CHECK-NEXT: %d:_ KnownBits:00000000 SignBits:8 IsKnownNeverZero:0
-  ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:8 IsKnownNeverZero:0
-  ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:1 IsKnownNeverZero:0
+  ; LE-LABEL: name: @bitcast_small_large_alternating
+  ; LE-NEXT: %c:_ KnownBits:11111111 SignBits:8 IsKnownNeverZero:1
+  ; LE-NEXT: %d:_ KnownBits:00000000 SignBits:8 IsKnownNeverZero:0
+  ; LE-NEXT: %2:_ KnownBits:???????? SignBits:8 IsKnownNeverZero:0
+  ; LE-NEXT: %3:_ KnownBits:0000000011111111 SignBits:8 IsKnownNeverZero:1
+  ;
+  ; BE-LABEL: name: @bitcast_small_large_alternating
+  ; BE-NEXT: %c:_ KnownBits:11111111 SignBits:8 IsKnownNeverZero:1
+  ; BE-NEXT: %d:_ KnownBits:00000000 SignBits:8 IsKnownNeverZero:0
+  ; BE-NEXT: %2:_ KnownBits:???????? SignBits:8 IsKnownNeverZero:0
+  ; BE-NEXT: %3:_ KnownBits:1111111100000000 SignBits:8 IsKnownNeverZero:1
     %c:_(i8) = G_CONSTANT i8 255
     %d:_(i8) = G_CONSTANT i8 0
     %1:_(<4 x i8>) = G_BUILD_VECTOR %c(i8), %d(i8), %c(i8), %d(i8)
@@ -116,15 +122,25 @@ body: |
 name: bitcast_small_large_partial
 body: |
   bb.0:
-  ; CHECK-LABEL: name: @bitcast_small_large_partial
-  ; CHECK-NEXT: %a:_ KnownBits:0000000011111111 SignBits:8 IsKnownNeverZero:1
-  ; CHECK-NEXT: %b:_ KnownBits:0000111111110000 SignBits:4 IsKnownNeverZero:1
-  ; CHECK-NEXT: %c:_ KnownBits:0000111100001111 SignBits:4 IsKnownNeverZero:1
-  ; CHECK-NEXT: %d:_ KnownBits:0011110000111100 SignBits:2 IsKnownNeverZero:1
-  ; CHECK-NEXT: %v:_ KnownBits:00?????????????? SignBits:2 IsKnownNeverZero:1
-  ; CHECK-NEXT: %r:_ KnownBits:???????????????????????????????? SignBits:1 IsKnownNeverZero:0
-  ; CHECK-NEXT: %i:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000000 SignBits:64 IsKnownNeverZero:0
-  ; CHECK-NEXT: %e:_ KnownBits:???????????????????????????????? SignBits:1 IsKnownNeverZero:0
+  ; LE-LABEL: name: @bitcast_small_large_partial
+  ; LE-NEXT: %a:_ KnownBits:0000000011111111 SignBits:8 IsKnownNeverZero:1
+  ; LE-NEXT: %b:_ KnownBits:0000111111110000 SignBits:4 IsKnownNeverZero:1
+  ; LE-NEXT: %c:_ KnownBits:0000111100001111 SignBits:4 IsKnownNeverZero:1
+  ; LE-NEXT: %d:_ KnownBits:0011110000111100 SignBits:2 IsKnownNeverZero:1
+  ; LE-NEXT: %v:_ KnownBits:00?????????????? SignBits:2 IsKnownNeverZero:1
+  ; LE-NEXT: %r:_ KnownBits:00??11????11??000000????????1111 SignBits:2 IsKnownNeverZero:1
+  ; LE-NEXT: %i:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000000 SignBits:64 IsKnownNeverZero:0
+  ; LE-NEXT: %e:_ KnownBits:00001111111100000000000011111111 SignBits:4 IsKnownNeverZero:1
+  ;
+  ; BE-LABEL: name: @bitcast_small_large_partial
+  ; BE-NEXT: %a:_ KnownBits:0000000011111111 SignBits:8 IsKnownNeverZero:1
+  ; BE-NEXT: %b:_ KnownBits:0000111111110000 SignBits:4 IsKnownNeverZero:1
+  ; BE-NEXT: %c:_ KnownBits:0000111100001111 SignBits:4 IsKnownNeverZero:1
+  ; BE-NEXT: %d:_ KnownBits:0011110000111100 SignBits:2 IsKnownNeverZero:1
+  ; BE-NEXT: %v:_ KnownBits:00?????????????? SignBits:2 IsKnownNeverZero:1
+  ; BE-NEXT: %r:_ KnownBits:0000????????111100??11????11??00 SignBits:4 IsKnownNeverZero:1
+  ; BE-NEXT: %i:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000000 SignBits:64 IsKnownNeverZero:0
+  ; BE-NEXT: %e:_ KnownBits:00000000111111110000111111110000 SignBits:8 IsKnownNeverZero:1
     %a:_(i16) = G_CONSTANT i16 255        ; 0x00FF
     %b:_(i16) = G_CONSTANT i16 4080       ; 0x0FF0
     %c:_(i16) = G_CONSTANT i16 3855       ; 0xF0F0
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/andn2.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/andn2.ll
index d553f16d49013..c2cf88001e6e3 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/andn2.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/andn2.ll
@@ -958,16 +958,15 @@ define <3 x i16> @v_andn2_v3i16(<3 x i16> %src0, <3 x i16> %src1) {
 ; GFX6-NEXT:    v_lshlrev_b32_e32 v4, 16, v4
 ; GFX6-NEXT:    v_xor_b32_e32 v2, -1, v2
 ; GFX6-NEXT:    v_or_b32_e32 v0, v0, v4
-; GFX6-NEXT:    v_and_b32_e32 v3, 0xffff, v3
 ; GFX6-NEXT:    v_and_b32_e32 v0, v0, v2
+; GFX6-NEXT:    v_and_b32_e32 v3, 0xffff, v3
+; GFX6-NEXT:    v_lshrrev_b32_e32 v2, 16, v0
 ; GFX6-NEXT:    v_xor_b32_e32 v3, 0xfff5, v3
 ; GFX6-NEXT:    v_and_b32_e32 v1, 0xffff, v1
-; GFX6-NEXT:    v_lshrrev_b32_e32 v2, 16, v0
-; GFX6-NEXT:    v_and_b32_e32 v1, v1, v3
 ; GFX6-NEXT:    v_and_b32_e32 v0, 0xffff, v0
 ; GFX6-NEXT:    v_lshlrev_b32_e32 v2, 16, v2
+; GFX6-NEXT:    v_and_b32_e32 v1, v1, v3
 ; GFX6-NEXT:    v_or_b32_e32 v0, v0, v2
-; GFX6-NEXT:    v_and_b32_e32 v1, 0xffff, v1
 ; GFX6-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX9-LABEL: v_andn2_v3i16:
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/orn2.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/orn2.ll
index c226f7f9289ee..9433c89dea446 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/orn2.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/orn2.ll
@@ -957,16 +957,15 @@ define <3 x i16> @v_orn2_v3i16(<3 x i16> %src0, <3 x i16> %src1) {
 ; GFX6-NEXT:    v_lshlrev_b32_e32 v4, 16, v4
 ; GFX6-NEXT:    v_xor_b32_e32 v2, -1, v2
 ; GFX6-NEXT:    v_or_b32_e32 v0, v0, v4
-; GFX6-NEXT:    v_and_b32_e32 v3, 0xffff, v3
 ; GFX6-NEXT:    v_or_b32_e32 v0, v0, v2
+; GFX6-NEXT:    v_and_b32_e32 v3, 0xffff, v3
+; GFX6-NEXT:    v_lshrrev_b32_e32 v2, 16, v0
 ; GFX6-NEXT:    v_xor_b32_e32 v3, 0xfff5, v3
 ; GFX6-NEXT:    v_and_b32_e32 v1, 0xffff, v1
-; GFX6-NEXT:    v_lshrrev_b32_e32 v2, 16, v0
-; GFX6-NEXT:    v_or_b32_e32 v1, v1, v3
 ; GFX6-NEXT:    v_and_b32_e32 v0, 0xffff, v0
 ; GFX6-NEXT:    v_lshlrev_b32_e32 v2, 16, v2
+; GFX6-NEXT:    v_or_b32_e32 v1, v1, v3
 ; GFX6-NEXT:    v_or_b32_e32 v0, v0, v2
-; GFX6-NEXT:    v_and_b32_e32 v1, 0xffff, v1
 ; GFX6-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX9-LABEL: v_orn2_v3i16:
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/shl-ext-reduce.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/shl-ext-reduce.ll
index 55e38ee0134b2..d9dd43c9eb7ec 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/shl-ext-reduce.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/shl-ext-reduce.ll
@@ -642,7 +642,6 @@ define amdgpu_ps <2 x i32> @s_shl_v2i32_zext_v2i16(<2 x i16> inreg %x) {
 ; GFX7-NEXT:    s_lshl_b32 s0, s0, 2
 ; GFX7-NEXT:    s_lshl_b32 s1, s1, 2
 ; GFX7-NEXT:    s_and_b32 s0, s0, 0xffff
-; GFX7-NEXT:    s_and_b32 s1, s1, 0xffff
 ; GFX7-NEXT:    ; return to shader part epilog
 ;
 ; GFX8-LABEL: s_shl_v2i32_zext_v2i16:
@@ -652,7 +651,6 @@ define amdgpu_ps <2 x i32> @s_shl_v2i32_zext_v2i16(<2 x i16> inreg %x) {
 ; GFX8-NEXT:    s_lshl_b32 s0, s0, 2
 ; GFX8-NEXT:    s_lshl_b32 s1, s1, 2
 ; GFX8-NEXT:    s_and_b32 s0, 0xffff, s0
-; GFX8-NEXT:    s_and_b32 s1, 0xffff, s1
 ; GFX8-NEXT:    ; return to shader part epilog
 ;
 ; GFX9-LABEL: s_shl_v2i32_zext_v2i16:
@@ -718,7 +716,6 @@ define <2 x i32> @v_shl_v2i32_zext_v2i16(<2 x i16> %x) {
 ; GFX7-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
 ; GFX7-NEXT:    v_lshlrev_b32_e32 v1, 2, v1
 ; GFX7-NEXT:    v_and_b32_e32 v0, 0xffff, v0
-; GFX7-NEXT:    v_and_b32_e32 v1, 0xffff, v1
 ; GFX7-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX8-LABEL: v_shl_v2i32_zext_v2i16:
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/uaddsat.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/uaddsat.ll
index 749fe014ff706..5a204a0482f0e 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/uaddsat.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/uaddsat.ll
@@ -305,9 +305,9 @@ define i16 @v_uaddsat_v2i8(i16 %lhs.arg, i16 %rhs.arg) {
 ; GFX9-NEXT:    v_pk_lshlrev_b16 v1, 8, v1 op_sel_hi:[0,1]
 ; GFX9-NEXT:    v_pk_add_u16 v0, v0, v1 clamp
 ; GFX9-NEXT:    v_pk_lshrrev_b16 v0, 8, v0 op_sel_hi:[0,1]
-; GFX9-NEXT:    v_mov_b32_e32 v1, 0xff
-; GFX9-NEXT:    v_and_b32_sdwa v1, v0, v1 dst_sel:BYTE_1 dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
-; GFX9-NEXT:    v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
+; GFX9-NEXT:    v_lshrrev_b32_e32 v1, 16, v0
+; GFX9-NEXT:    v_lshlrev_b16_e32 v1, 8, v1
+; GFX9-NEXT:    v_or_b32_e32 v0, v0, v1
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX10-LABEL: v_uaddsat_v2i8:
@@ -321,10 +321,10 @@ define i16 @v_uaddsat_v2i8(i16 %lhs.arg, i16 %rhs.arg) {
 ; GFX10-NEXT:    v_pk_lshlrev_b16 v0, 8, v0 op_sel_hi:[0,1]
 ; GFX10-NEXT:    v_pk_lshlrev_b16 v1, 8, v1 op_sel_hi:[0,1]
 ; GFX10-NEXT:    v_pk_add_u16 v0, v0, v1 clamp
-; GFX10-NEXT:    v_mov_b32_e32 v1, 0xff
+; GFX10-NEXT:    v_mov_b32_e32 v1, 16
 ; GFX10-NEXT:    v_pk_lshrrev_b16 v0, 8, v0 op_sel_hi:[0,1]
-; GFX10-NEXT:    v_and_b32_sdwa v1, v0, v1 dst_sel:BYTE_1 dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
-; GFX10-NEXT:    v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
+; GFX10-NEXT:    v_lshrrev_b32_sdwa v1, v1, v0 dst_sel:BYTE_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX10-NEXT:    v_or_b32_e32 v0, v0, v1
 ; GFX10-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-TRUE16-LABEL: v_uaddsat_v2i8:
@@ -356,8 +356,6 @@ define i16 @v_uaddsat_v2i8(i16 %lhs.arg, i16 %rhs.arg) {
 ; GFX11-FAKE16-NEXT:    v_pk_add_u16 v0, v0, v1 clamp
 ; GFX11-FAKE16-NEXT:    v_pk_lshrrev_b16 v0, 8, v0 op_sel_hi:[0,1]
 ; GFX11-FAKE16-NEXT:    v_lshrrev_b32_e32 v1, 16, v0
-; GFX11-FAKE16-NEXT:    v_and_b32_e32 v0, 0xff, v0
-; GFX11-FAKE16-NEXT:    v_and_b32_e32 v1, 0xff, v1
 ; GFX11-FAKE16-NEXT:    v_lshlrev_b16 v1, 8, v1
 ; GFX11-FAKE16-NEXT:    v_or_b32_e32 v0, v0, v1
 ; GFX11-FAKE16-NEXT:    s_setpc_b64 s[30:31]
@@ -434,93 +432,35 @@ define amdgpu_ps i16 @s_uaddsat_v2i8(i16 inreg %lhs.arg, i16 inreg %rhs.arg) {
 ; GFX9-NEXT:    s_lshr_b32 s0, s0, 8
 ; GFX9-NEXT:    s_pack_ll_b32_b16 s0, s1, s0
 ; GFX9-NEXT:    s_lshr_b32 s1, s0, 16
-; GFX9-NEXT:    s_and_b32 s1, s1, 0xff
-; GFX9-NEXT:    s_and_b32 s0, s0, 0xff
 ; GFX9-NEXT:    s_lshl_b32 s1, s1, 8
 ; GFX9-NEXT:    s_or_b32 s0, s0, s1
 ; GFX9-NEXT:    ; return to shader part epilog
 ;
-; GFX10-LABEL: s_uaddsat_v2i8:
-; GFX10:       ; %bb.0:
-; GFX10-NEXT:    s_lshr_b32 s2, s0, 8
-; GFX10-NEXT:    s_lshr_b32 s3, s1, 8
-; GFX10-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
-; GFX10-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
-; GFX10-NEXT:    s_lshr_b32 s2, s0, 16
-; GFX10-NEXT:    s_lshr_b32 s3, s1, 16
-; GFX10-NEXT:    s_lshl_b32 s0, s0, 0x80008
-; GFX10-NEXT:    s_lshl_b32 s2, s2, 8
-; GFX10-NEXT:    s_lshl_b32 s1, s1, 0x80008
-; GFX10-NEXT:    s_lshl_b32 s3, s3, 8
-; GFX10-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
-; GFX10-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
-; GFX10-NEXT:    v_pk_add_u16 v0, s0, s1 clamp
-; GFX10-NEXT:    v_readfirstlane_b32 s0, v0
-; GFX10-NEXT:    s_and_b32 s1, s0, 0xffff
-; GFX10-NEXT:    s_lshr_b32 s0, s0, 16
-; GFX10-NEXT:    s_lshr_b32 s1, s1, 0x80008
-; GFX10-NEXT:    s_lshr_b32 s0, s0, 8
-; GFX10-NEXT:    s_pack_ll_b32_b16 s0, s1, s0
-; GFX10-NEXT:    s_lshr_b32 s1, s0, 16
-; GFX10-NEXT:    s_and_b32 s0, s0, 0xff
-; GFX10-NEXT:    s_and_b32 s1, s1, 0xff
-; GFX10-NEXT:    s_lshl_b32 s1, s1, 8
-; GFX10-NEXT:    s_or_b32 s0, s0, s1
-; GFX10-NEXT:    ; return to shader part epilog
-;
-; GFX11-TRUE16-LABEL: s_uaddsat_v2i8:
-; GFX11-TRUE16:       ; %bb.0:
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s2, s0, 8
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s3, s1, 8
-; GFX11-TRUE16-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
-; GFX11-TRUE16-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s2, s0, 16
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s3, s1, 16
-; GFX11-TRUE16-NEXT:    s_lshl_b32 s0, s0, 0x80008
-; GFX11-TRUE16-NEXT:    s_lshl_b32 s2, s2, 8
-; GFX11-TRUE16-NEXT:    s_lshl_b32 s1, s1, 0x80008
-; GFX11-TRUE16-NEXT:    s_lshl_b32 s3, s3, 8
-; GFX11-TRUE16-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
-; GFX11-TRUE16-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
-; GFX11-TRUE16-NEXT:    v_pk_add_u16 v0, s0, s1 clamp
-; GFX11-TRUE16-NEXT:    v_readfirstlane_b32 s0, v0
-; GFX11-TRUE16-NEXT:    s_and_b32 s1, s0, 0xffff
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s0, s0, 16
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s1, s1, 0x80008
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s0, s0, 8
-; GFX11-TRUE16-NEXT:    s_pack_ll_b32_b16 s0, s1, s0
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s1, s0, 16
-; GFX11-TRUE16-NEXT:    s_lshl_b32 s1, s1, 8
-; GFX11-TRUE16-NEXT:    s_or_b32 s0, s0, s1
-; GFX11-TRUE16-NEXT:    ; return to shader part epilog
-;
-; GFX11-FAKE16-LABEL: s_uaddsat_v2i8:
-; GFX11-FAKE16:       ; %bb.0:
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s2, s0, 8
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s3, s1, 8
-; GFX11-FAKE16-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
-; GFX11-FAKE16-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s2, s0, 16
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s3, s1, 16
-; GFX11-FAKE16-NEXT:    s_lshl_b32 s0, s0, 0x80008
-; GFX11-FAKE16-NEXT:    s_lshl_b32 s2, s2, 8
-; GFX11-FAKE16-NEXT:    s_lshl_b32 s1, s1, 0x80008
-; GFX11-FAKE16-NEXT:    s_lshl_b32 s3, s3, 8
-; GFX11-FAKE16-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
-; GFX11-FAKE16-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
-; GFX11-FAKE16-NEXT:    v_pk_add_u16 v0, s0, s1 clamp
-; GFX11-FAKE16-NEXT:    v_readfirstlane_b32 s0, v0
-; GFX11-FAKE16-NEXT:    s_and_b32 s1, s0, 0xffff
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s0, s0, 16
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s1, s1, 0x80008
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s0, s0, 8
-; GFX11-FAKE16-NEXT:    s_pack_ll_b32_b16 s0, s1, s0
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s1, s0, 16
-; GFX11-FAKE16-NEXT:    s_and_b32 s0, s0, 0xff
-; GFX11-FAKE16-NEXT:    s_and_b32 s1, s1, 0xff
-; GFX11-FAKE16-NEXT:    s_lshl_b32 s1, s1, 8
-; GFX11-FAKE16-NEXT:    s_or_b32 s0, s0, s1
-; GFX11-FAKE16-NEXT:    ; return to shader part epilog
+; GFX10PLUS-LABEL: s_uaddsat_v2i8:
+; GFX10PLUS:       ; %bb.0:
+; GFX10PLUS-NEXT:    s_lshr_b32 s2, s0, 8
+; GFX10PLUS-NEXT:    s_lshr_b32 s3, s1, 8
+; GFX10PLUS-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
+; GFX10PLUS-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
+; GFX10PLUS-NEXT:    s_lshr_b32 s2, s0, 16
+; GFX10PLUS-NEXT:    s_lshr_b32 s3, s1, 16
+; GFX10PLUS-NEXT:    s_lshl_b32 s0, s0, 0x80008
+; GFX10PLUS-NEXT:    s_lshl_b32 s2, s2, 8
+; GFX10PLUS-NEXT:    s_lshl_b32 s1, s1, 0x80008
+; GFX10PLUS-NEXT:    s_lshl_b32 s3, s3, 8
+; GFX10PLUS-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
+; GFX10PLUS-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
+; GFX10PLUS-NEXT:    v_pk_add_u16 v0, s0, s1 clamp
+; GFX10PLUS-NEXT:    v_readfirstlane_b32 s0, v0
+; GFX10PLUS-NEXT:    s_and_b32 s1, s0, 0xffff
+; GFX10PLUS-NEXT:    s_lshr_b32 s0, s0, 16
+; GFX10PLUS-NEXT:    s_lshr_b32 s1, s1, 0x80008
+; GFX10PLUS-NEXT:    s_lshr_b32 s0, s0, 8
+; GFX10PLUS-NEXT:    s_pack_ll_b32_b16 s0, s1, s0
+; GFX10PLUS-NEXT:    s_lshr_b32 s1, s0, 16
+; GFX10PLUS-NEXT:    s_lshl_b32 s1, s1, 8
+; GFX10PLUS-NEXT:    s_or_b32 s0, s0, s1
+; GFX10PLUS-NEXT:    ; return to shader part epilog
   %lhs = bitcast i16 %lhs.arg to <2 x i8>
   %rhs = bitcast i16 %rhs.arg to <2 x i8>
   %result = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %lhs, <2 x i8> %rhs)
@@ -612,21 +552,21 @@ define i32 @v_uaddsat_v4i8(i32 %lhs.arg, i32 %rhs.arg) {
 ; GFX9-NEXT:    v_or_b32_sdwa v4, v5, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
 ; GFX9-NEXT:    v_alignbit_b32 v1, v6, v1, 16
 ; GFX9-NEXT:    v_pk_lshlrev_b16 v3, 8, v3 op_sel_hi:[0,1]
-; GFX9-NEXT:    v_pk_lshlrev_b16 v4, 8, v4 op_sel_hi:[0,1]
 ; GFX9-NEXT:    v_pk_lshlrev_b16 v0, 8, v0 op_sel_hi:[0,1]
+; GFX9-NEXT:    v_pk_lshlrev_b16 v4, 8, v4 op_sel_hi:[0,1]
 ; GFX9-NEXT:    v_pk_lshlrev_b16 v1, 8, v1 op_sel_hi:[0,1]
 ; GFX9-NEXT:    v_pk_add_u16 v3, v3, v4 clamp
 ; GFX9-NEXT:    v_pk_add_u16 v0, v0, v1 clamp
 ; GFX9-NEXT:    v_pk_lshrrev_b16 v1, 8, v3 op_sel_hi:[0,1]
 ; GFX9-NEXT:    v_pk_lshrrev_b16 v0, 8, v0 op_sel_hi:[0,1]
-; GFX9-NEXT:    v_mov_b32_e32 v3, 0xff
-; GFX9-NEXT:    v_lshlrev_b32_sdwa v2, v2, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:BYTE_2
-; GFX9-NEXT:    v_and_or_b32 v1, v1, v3, v2
-; GFX9-NEXT:    v_and_b32_e32 v2, 0xff, v0
-; GFX9-NEXT:    v_mov_b32_e32 v3, 24
-; GFX9-NEXT:    v_lshlrev_b32_e32 v2, 16, v2
-; GFX9-NEXT:    v_lshlrev_b32_sdwa v0, v3, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:BYTE_2
-; GFX9-NEXT:    v_or3_b32 v0, v1, v2, v0
+; GFX9-NEXT:    v_lshrrev_b32_e32 v3, 16, v0
+; GFX9-NEXT:    v_mov_b32_e32 v4, 0xff
+; GFX9-NEXT:    v_lshlrev_b32_sdwa v2, v2, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX9-NEXT:    v_and_b32_e32 v0, 0xff, v0
+; GFX9-NEXT:    v_and_or_b32 v1, v1, v4, v2
+; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 16, v0
+; GFX9-NEXT:    v_lshlrev_b32_e32 v2, 24, v3
+; GFX9-NEXT:    v_or3_b32 v0, v1, v0, v2
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX10-LABEL: v_uaddsat_v4i8:
@@ -647,14 +587,14 @@ define i32 @v_uaddsat_v4i8(i32 %lhs.arg, i32 %rhs.arg) {
 ; GFX10-NEXT:    v_pk_lshlrev_b16 v1, 8, v1 op_sel_hi:[0,1]
 ; GFX10-NEXT:    v_pk_add_u16 v3, v3, v4 clamp
 ; GFX10-NEXT:    v_pk_add_u16 v0, v0, v1 clamp
-; GFX10-NEXT:    v_mov_b32_e32 v4, 24
 ; GFX10-NEXT:    v_pk_lshrrev_b16 v1, 8, v3 op_sel_hi:[0,1]
 ; GFX10-NEXT:    v_pk_lshrrev_b16 v0, 8, v0 op_sel_hi:[0,1]
-; GFX10-NEXT:    v_lshlrev_b32_sdwa v2, v2, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:BYTE_2
+; GFX10-NEXT:    v_lshlrev_b32_sdwa v2, v2, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
 ; GFX10-NEXT:    v_and_b32_e32 v3, 0xff, v0
-; GFX10-NEXT:    v_lshlrev_b32_sdwa v0, v4, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:BYTE_2
+; GFX10-NEXT:    v_lshrrev_b32_e32 v0, 16, v0
 ; GFX10-NEXT:    v_and_or_b32 v1, 0xff, v1, v2
 ; GFX10-NEXT:    v_lshlrev_b32_e32 v2, 16, v3
+; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 24, v0
 ; GFX10-NEXT:    v_or3_b32 v0, v1, v2, v0
 ; GFX10-NEXT:    s_setpc_b64 s[30:31]
 ;
@@ -712,9 +652,9 @@ define i32 @v_uaddsat_v4i8(i32 %lhs.arg, i32 %rhs.arg) {
 ; GFX11-FAKE16-NEXT:    v_pk_add_u16 v0, v0, v1 clamp
 ; GFX11-FAKE16-NEXT:    v_pk_lshrrev_b16 v1, 8, v2 op_sel_hi:[0,1]
 ; GFX11-FAKE16-NEXT:    v_pk_lshrrev_b16 v0, 8, v0 op_sel_hi:[0,1]
-; GFX11-FAKE16-NEXT:    v_bfe_u32 v2, v1, 16, 8
+; GFX11-FAKE16-NEXT:    v_lshrrev_b32_e32 v2, 16, v1
 ; GFX11-FAKE16-NEXT:    v_and_b32_e32 v3, 0xff, v0
-; GFX11-FAKE16-NEXT:    v_bfe_u32 v0, v0, 16, 8
+; GFX11-FAKE16-NEXT:    v_lshrrev_b32_e32 v0, 16, v0
 ; GFX11-FAKE16-NEXT:    v_lshlrev_b32_e32 v2, 8, v2
 ; GFX11-FAKE16-NEXT:    v_lshlrev_b32_e32 v3, 16, v3
 ; GFX11-FAKE16-NEXT:    v_lshlrev_b32_e32 v0, 24, v0
@@ -857,15 +797,15 @@ define amdgpu_ps i32 @s_uaddsat_v4i8(i32 inreg %lhs.arg, i32 inreg %rhs.arg) {
 ; GFX9-NEXT:    s_lshr_b32 s2, s2, 0x80008
 ; GFX9-NEXT:    s_lshr_b32 s1, s1, 8
 ; GFX9-NEXT:    s_pack_ll_b32_b16 s1, s2, s1
-; GFX9-NEXT:    s_and_b32 s2, s0, 0xff
-; GFX9-NEXT:    s_bfe_u32 s0, s0, 0x80010
-; GFX9-NEXT:    s_lshl_b32 s0, s0, 8
-; GFX9-NEXT:    s_or_b32 s0, s2, s0
-; GFX9-NEXT:    s_and_b32 s2, s1, 0xff
-; GFX9-NEXT:    s_lshl_b32 s2, s2, 16
-; GFX9-NEXT:    s_bfe_u32 s1, s1, 0x80010
+; GFX9-NEXT:    s_lshr_b32 s2, s0, 16
+; GFX9-NEXT:    s_lshr_b32 s3, s1, 16
+; GFX9-NEXT:    s_and_b32 s0, s0, 0xff
+; GFX9-NEXT:    s_lshl_b32 s2, s2, 8
+; GFX9-NEXT:    s_and_b32 s1, s1, 0xff
 ; GFX9-NEXT:    s_or_b32 s0, s0, s2
-; GFX9-NEXT:    s_lshl_b32 s1, s1, 24
+; GFX9-NEXT:    s_lshl_b32 s1, s1, 16
+; GFX9-NEXT:    s_or_b32 s0, s0, s1
+; GFX9-NEXT:    s_lshl_b32 s1, s3, 24
 ; GFX9-NEXT:    s_or_b32 s0, s0, s1
 ; GFX9-NEXT:    ; return to shader part epilog
 ;
@@ -911,13 +851,13 @@ define amdgpu_ps i32 @s_uaddsat_v4i8(i32 inreg %lhs.arg, i32 inreg %rhs.arg) {
 ; GFX10-NEXT:    s_lshr_b32 s1, s1, 8
 ; GFX10-NEXT:    s_pack_ll_b32_b16 s0, s2, s0
 ; GFX10-NEXT:    s_pack_ll_b32_b16 s1, s3, s1
-; GFX10-NEXT:    s_bfe_u32 s2, s0, 0x80010
+; GFX10-NEXT:    s_lshr_b32 s2, s0, 16
 ; GFX10-NEXT:    s_and_b32 s0, s0, 0xff
 ; GFX10-NEXT:    s_lshl_b32 s2, s2, 8
 ; GFX10-NEXT:    s_and_b32 s3, s1, 0xff
 ; GFX10-NEXT:    s_or_b32 s0, s0, s2
 ; GFX10-NEXT:    s_lshl_b32 s2, s3, 16
-; GFX10-NEXT:    s_bfe_u32 s1, s1, 0x80010
+; GFX10-NEXT:    s_lshr_b32 s1, s1, 16
 ; GFX10-NEXT:    s_or_b32 s0, s0, s2
 ; GFX10-NEXT:    s_lshl_b32 s1, s1, 24
 ; GFX10-NEXT:    s_or_b32 s0, s0, s1
@@ -1017,13 +957,13 @@ define amdgpu_ps i32 @s_uaddsat_v4i8(i32 inreg %lhs.arg, i32 inreg %rhs.arg) {
 ; GFX11-FAKE16-NEXT:    s_lshr_b32 s1, s1, 8
 ; GFX11-FAKE16-NEXT:    s_pack_ll_b32_b16 s0, s2, s0
 ; GFX11-FAKE16-NEXT:    s_pack_ll_b32_b16 s1, s3, s1
-; GFX11-FAKE16-NEXT:    s_bfe_u32 s2, s0, 0x80010
+; GFX11-FAKE16-NEXT:    s_lshr_b32 s2, s0, 16
 ; GFX11-FAKE16-NEXT:    s_and_b32 s0, s0, 0xff
 ; GFX11-FAKE16-NEXT:    s_lshl_b32 s2, s2, 8
 ; GFX11-FAKE16-NEXT:    s_and_b32 s3, s1, 0xff
 ; GFX11-FAKE16-NEXT:    s_or_b32 s0, s0, s2
 ; GFX11-FAKE16-NEXT:    s_lshl_b32 s2, s3, 16
-; GFX11-FAKE16-NEXT:    s_bfe_u32 s1, s1, 0x80010
+; GFX11-FAKE16-NEXT:    s_lshr_b32 s1, s1, 16
 ; GFX11-FAKE16-NEXT:    s_or_b32 s0, s0, s2
 ; GFX11-FAKE16-NEXT:    s_lshl_b32 s1, s1, 24
 ; GFX11-FAKE16-NEXT:    s_or_b32 s0, s0, s1
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/usubsat.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/usubsat.ll
index 2e76abae2ff4f..76ab4772cf8a3 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/usubsat.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/usubsat.ll
@@ -299,9 +299,9 @@ define i16 @v_usubsat_v2i8(i16 %lhs.arg, i16 %rhs.arg) {
 ; GFX9-NEXT:    v_pk_lshlrev_b16 v1, 8, v1 op_sel_hi:[0,1]
 ; GFX9-NEXT:    v_pk_sub_u16 v0, v0, v1 clamp
 ; GFX9-NEXT:    v_pk_lshrrev_b16 v0, 8, v0 op_sel_hi:[0,1]
-; GFX9-NEXT:    v_mov_b32_e32 v1, 0xff
-; GFX9-NEXT:    v_and_b32_sdwa v1, v0, v1 dst_sel:BYTE_1 dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
-; GFX9-NEXT:    v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
+; GFX9-NEXT:    v_lshrrev_b32_e32 v1, 16, v0
+; GFX9-NEXT:    v_lshlrev_b16_e32 v1, 8, v1
+; GFX9-NEXT:    v_or_b32_e32 v0, v0, v1
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX10-LABEL: v_usubsat_v2i8:
@@ -315,10 +315,10 @@ define i16 @v_usubsat_v2i8(i16 %lhs.arg, i16 %rhs.arg) {
 ; GFX10-NEXT:    v_pk_lshlrev_b16 v0, 8, v0 op_sel_hi:[0,1]
 ; GFX10-NEXT:    v_pk_lshlrev_b16 v1, 8, v1 op_sel_hi:[0,1]
 ; GFX10-NEXT:    v_pk_sub_u16 v0, v0, v1 clamp
-; GFX10-NEXT:    v_mov_b32_e32 v1, 0xff
+; GFX10-NEXT:    v_mov_b32_e32 v1, 16
 ; GFX10-NEXT:    v_pk_lshrrev_b16 v0, 8, v0 op_sel_hi:[0,1]
-; GFX10-NEXT:    v_and_b32_sdwa v1, v0, v1 dst_sel:BYTE_1 dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
-; GFX10-NEXT:    v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
+; GFX10-NEXT:    v_lshrrev_b32_sdwa v1, v1, v0 dst_sel:BYTE_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX10-NEXT:    v_or_b32_e32 v0, v0, v1
 ; GFX10-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-TRUE16-LABEL: v_usubsat_v2i8:
@@ -350,8 +350,6 @@ define i16 @v_usubsat_v2i8(i16 %lhs.arg, i16 %rhs.arg) {
 ; GFX11-FAKE16-NEXT:    v_pk_sub_u16 v0, v0, v1 clamp
 ; GFX11-FAKE16-NEXT:    v_pk_lshrrev_b16 v0, 8, v0 op_sel_hi:[0,1]
 ; GFX11-FAKE16-NEXT:    v_lshrrev_b32_e32 v1, 16, v0
-; GFX11-FAKE16-NEXT:    v_and_b32_e32 v0, 0xff, v0
-; GFX11-FAKE16-NEXT:    v_and_b32_e32 v1, 0xff, v1
 ; GFX11-FAKE16-NEXT:    v_lshlrev_b16 v1, 8, v1
 ; GFX11-FAKE16-NEXT:    v_or_b32_e32 v0, v0, v1
 ; GFX11-FAKE16-NEXT:    s_setpc_b64 s[30:31]
@@ -426,93 +424,35 @@ define amdgpu_ps i16 @s_usubsat_v2i8(i16 inreg %lhs.arg, i16 inreg %rhs.arg) {
 ; GFX9-NEXT:    s_lshr_b32 s0, s0, 8
 ; GFX9-NEXT:    s_pack_ll_b32_b16 s0, s1, s0
 ; GFX9-NEXT:    s_lshr_b32 s1, s0, 16
-; GFX9-NEXT:    s_and_b32 s1, s1, 0xff
-; GFX9-NEXT:    s_and_b32 s0, s0, 0xff
 ; GFX9-NEXT:    s_lshl_b32 s1, s1, 8
 ; GFX9-NEXT:    s_or_b32 s0, s0, s1
 ; GFX9-NEXT:    ; return to shader part epilog
 ;
-; GFX10-LABEL: s_usubsat_v2i8:
-; GFX10:       ; %bb.0:
-; GFX10-NEXT:    s_lshr_b32 s2, s0, 8
-; GFX10-NEXT:    s_lshr_b32 s3, s1, 8
-; GFX10-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
-; GFX10-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
-; GFX10-NEXT:    s_lshr_b32 s2, s0, 16
-; GFX10-NEXT:    s_lshr_b32 s3, s1, 16
-; GFX10-NEXT:    s_lshl_b32 s0, s0, 0x80008
-; GFX10-NEXT:    s_lshl_b32 s2, s2, 8
-; GFX10-NEXT:    s_lshl_b32 s1, s1, 0x80008
-; GFX10-NEXT:    s_lshl_b32 s3, s3, 8
-; GFX10-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
-; GFX10-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
-; GFX10-NEXT:    v_pk_sub_u16 v0, s0, s1 clamp
-; GFX10-NEXT:    v_readfirstlane_b32 s0, v0
-; GFX10-NEXT:    s_and_b32 s1, s0, 0xffff
-; GFX10-NEXT:    s_lshr_b32 s0, s0, 16
-; GFX10-NEXT:    s_lshr_b32 s1, s1, 0x80008
-; GFX10-NEXT:    s_lshr_b32 s0, s0, 8
-; GFX10-NEXT:    s_pack_ll_b32_b16 s0, s1, s0
-; GFX10-NEXT:    s_lshr_b32 s1, s0, 16
-; GFX10-NEXT:    s_and_b32 s0, s0, 0xff
-; GFX10-NEXT:    s_and_b32 s1, s1, 0xff
-; GFX10-NEXT:    s_lshl_b32 s1, s1, 8
-; GFX10-NEXT:    s_or_b32 s0, s0, s1
-; GFX10-NEXT:    ; return to shader part epilog
-;
-; GFX11-TRUE16-LABEL: s_usubsat_v2i8:
-; GFX11-TRUE16:       ; %bb.0:
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s2, s0, 8
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s3, s1, 8
-; GFX11-TRUE16-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
-; GFX11-TRUE16-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s2, s0, 16
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s3, s1, 16
-; GFX11-TRUE16-NEXT:    s_lshl_b32 s0, s0, 0x80008
-; GFX11-TRUE16-NEXT:    s_lshl_b32 s2, s2, 8
-; GFX11-TRUE16-NEXT:    s_lshl_b32 s1, s1, 0x80008
-; GFX11-TRUE16-NEXT:    s_lshl_b32 s3, s3, 8
-; GFX11-TRUE16-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
-; GFX11-TRUE16-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
-; GFX11-TRUE16-NEXT:    v_pk_sub_u16 v0, s0, s1 clamp
-; GFX11-TRUE16-NEXT:    v_readfirstlane_b32 s0, v0
-; GFX11-TRUE16-NEXT:    s_and_b32 s1, s0, 0xffff
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s0, s0, 16
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s1, s1, 0x80008
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s0, s0, 8
-; GFX11-TRUE16-NEXT:    s_pack_ll_b32_b16 s0, s1, s0
-; GFX11-TRUE16-NEXT:    s_lshr_b32 s1, s0, 16
-; GFX11-TRUE16-NEXT:    s_lshl_b32 s1, s1, 8
-; GFX11-TRUE16-NEXT:    s_or_b32 s0, s0, s1
-; GFX11-TRUE16-NEXT:    ; return to shader part epilog
-;
-; GFX11-FAKE16-LABEL: s_usubsat_v2i8:
-; GFX11-FAKE16:       ; %bb.0:
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s2, s0, 8
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s3, s1, 8
-; GFX11-FAKE16-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
-; GFX11-FAKE16-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s2, s0, 16
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s3, s1, 16
-; GFX11-FAKE16-NEXT:    s_lshl_b32 s0, s0, 0x80008
-; GFX11-FAKE16-NEXT:    s_lshl_b32 s2, s2, 8
-; GFX11-FAKE16-NEXT:    s_lshl_b32 s1, s1, 0x80008
-; GFX11-FAKE16-NEXT:    s_lshl_b32 s3, s3, 8
-; GFX11-FAKE16-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
-; GFX11-FAKE16-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
-; GFX11-FAKE16-NEXT:    v_pk_sub_u16 v0, s0, s1 clamp
-; GFX11-FAKE16-NEXT:    v_readfirstlane_b32 s0, v0
-; GFX11-FAKE16-NEXT:    s_and_b32 s1, s0, 0xffff
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s0, s0, 16
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s1, s1, 0x80008
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s0, s0, 8
-; GFX11-FAKE16-NEXT:    s_pack_ll_b32_b16 s0, s1, s0
-; GFX11-FAKE16-NEXT:    s_lshr_b32 s1, s0, 16
-; GFX11-FAKE16-NEXT:    s_and_b32 s0, s0, 0xff
-; GFX11-FAKE16-NEXT:    s_and_b32 s1, s1, 0xff
-; GFX11-FAKE16-NEXT:    s_lshl_b32 s1, s1, 8
-; GFX11-FAKE16-NEXT:    s_or_b32 s0, s0, s1
-; GFX11-FAKE16-NEXT:    ; return to shader part epilog
+; GFX10PLUS-LABEL: s_usubsat_v2i8:
+; GFX10PLUS:       ; %bb.0:
+; GFX10PLUS-NEXT:    s_lshr_b32 s2, s0, 8
+; GFX10PLUS-NEXT:    s_lshr_b32 s3, s1, 8
+; GFX10PLUS-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
+; GFX10PLUS-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
+; GFX10PLUS-NEXT:    s_lshr_b32 s2, s0, 16
+; GFX10PLUS-NEXT:    s_lshr_b32 s3, s1, 16
+; GFX10PLUS-NEXT:    s_lshl_b32 s0, s0, 0x80008
+; GFX10PLUS-NEXT:    s_lshl_b32 s2, s2, 8
+; GFX10PLUS-NEXT:    s_lshl_b32 s1, s1, 0x80008
+; GFX10PLUS-NEXT:    s_lshl_b32 s3, s3, 8
+; GFX10PLUS-NEXT:    s_pack_ll_b32_b16 s0, s0, s2
+; GFX10PLUS-NEXT:    s_pack_ll_b32_b16 s1, s1, s3
+; GFX10PLUS-NEXT:    v_pk_sub_u16 v0, s0, s1 clamp
+; GFX10PLUS-NEXT:    v_readfirstlane_b32 s0, v0
+; GFX10PLUS-NEXT:    s_and_b32 s1, s0, 0xffff
+; GFX10PLUS-NEXT:    s_lshr_b32 s0, s0, 16
+; GFX10PLUS-NEXT:    s_lshr_b32 s1, s1, 0x80008
+; GFX10PLUS-NEXT:    s_lshr_b32 s0, s0, 8
+; GFX10PLUS-NEXT:    s_pack_ll_b32_b16 s0, s1, s0
+; GFX10PLUS-NEXT:    s_lshr_b32 s1, s0, 16
+; GFX10PLUS-NEXT:    s_lshl_b32 s1, s1, 8
+; GFX10PLUS-NEXT:    s_or_b32 s0, s0, s1
+; GFX10PLUS-NEXT:    ; return to shader part epilog
   %lhs = bitcast i16 %lhs.arg to <2 x i8>
   %rhs = bitcast i16 %rhs.arg to <2 x i8>
   %result = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %lhs, <2 x i8> %rhs)
@@ -600,21 +540,21 @@ define i32 @v_usubsat_v4i8(i32 %lhs.arg, i32 %rhs.arg) {
 ; GFX9-NEXT:    v_or_b32_sdwa v4, v5, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
 ; GFX9-NEXT:    v_alignbit_b32 v1, v6, v1, 16
 ; GFX9-NEXT:    v_pk_lshlrev_b16 v3, 8, v3 op_sel_hi:[0,1]
-; GFX9-NEXT:    v_pk_lshlrev_b16 v4, 8, v4 op_sel_hi:[0,1]
 ; GFX9-NEXT:    v_pk_lshlrev_b16 v0, 8, v0 op_sel_hi:[0,1]
+; GFX9-NEXT:    v_pk_lshlrev_b16 v4, 8, v4 op_sel_hi:[0,1]
 ; GFX9-NEXT:    v_pk_lshlrev_b16 v1, 8, v1 op_sel_hi:[0,1]
 ; GFX9-NEXT:    v_pk_sub_u16 v3, v3, v4 clamp
 ; GFX9-NEXT:    v_pk_sub_u16 v0, v0, v1 clamp
 ; GFX9-NEXT:    v_pk_lshrrev_b16 v1, 8, v3 op_sel_hi:[0,1]
 ; GFX9-NEXT:    v_pk_lshrrev_b16 v0, 8, v0 op_sel_hi:[0,1]
-; GFX9-NEXT:    v_mov_b32_e32 v3, 0xff
-; GFX9-NEXT:    v_lshlrev_b32_sdwa v2, v2, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:BYTE_2
-; GFX9-NEXT:    v_and_or_b32 v1, v1, v3, v2
-; GFX9-NEXT:    v_and_b32_e32 v2, 0xff, v0
-; GFX9-NEXT:    v_mov_b32_e32 v3, 24
-; GFX9-NEXT:    v_lshlrev_b32_e32 v2, 16, v2
-; GFX9-NEXT:    v_lshlrev_b32_sdwa v0, v3, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:BYTE_2
-; GFX9-NEXT:    v_or3_b32 v0, v1, v2, v0
+; GFX9-NEXT:    v_lshrrev_b32_e32 v3, 16, v0
+; GFX9-NEXT:    v_mov_b32_e32 v4, 0xff
+; GFX9-NEXT:    v_lshlrev_b32_sdwa v2, v2, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX9-NEXT:    v_and_b32_e32 v0, 0xff, v0
+; GFX9-NEXT:    v_and_or_b32 v1, v1, v4, v2
+; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 16, v0
+; GFX9-NEXT:    v_lshlrev_b32_e32 v2, 24, v3
+; GFX9-NEXT:    v_or3_b32 v0, v1, v0, v2
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX10-LABEL: v_usubsat_v4i8:
@@ -635,14 +575,14 @@ define i32 @v_usubsat_v4i8(i32 %lhs.arg, i32 %rhs.arg) {
 ; GFX10-NEXT:    v_pk_lshlrev_b16 v1, 8, v1 op_sel_hi:[0,1]
 ; GFX10-NEXT:    v_pk_sub_u16 v3, v3, v4 clamp
 ; GFX10-NEXT:    v_pk_sub_u16 v0, v0, v1 clamp
-; GFX10-NEXT:    v_mov_b32_e32 v4, 24
 ; GFX10-NEXT:    v_pk_lshrrev_b16 v1, 8, v3 op_sel_hi:[0,1]
 ; GFX10-NEXT:    v_pk_lshrrev_b16 v0, 8, v0 op_sel_hi:[0,1]
-; GFX10-NEXT:    v_lshlrev_b32_sdwa v2, v2, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:BYTE_2
+; GFX10-NEXT:    v_lshlrev_b32_sdwa v2, v2, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
 ; GFX10-NEXT:    v_and_b32_e32 v3, 0xff, v0
-; GFX10-NEXT:    v_lshlrev_b32_sdwa v0, v4, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:BYTE_2
+; GFX10-NEXT:    v_lshrrev_b32_e32 v0, 16, v0
 ; GFX10-NEXT:    v_and_or_b32 v1, 0xff, v1, v2
 ; GFX10-NEXT:    v_lshlrev_b32_e32 v2, 16, v3
+; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 24, v0
 ; GFX10-NEXT:    v_or3_b32 v0, v1, v2, v0
 ; GFX10-NEXT:    s_setpc_b64 s[30:31]
 ;
@@ -700,9 +640,9 @@ define i32 @v_usubsat_v4i8(i32 %lhs.arg, i32 %rhs.arg) {
 ; GFX11-FAKE16-NEXT:    v_pk_sub_u16 v0, v0, v1 clamp
 ; GFX11-FAKE16-NEXT:    v_pk_lshrrev_b16 v1, 8, v2 op_sel_hi:[0,1]
 ; GFX11-FAKE16-NEXT:    v_pk_lshrrev_b16 v0, 8, v0 op_sel_hi:[0,1]
-; GFX11-FAKE16-NEXT:    v_bfe_u32 v2, v1, 16, 8
+; GFX11-FAKE16-NEXT:    v_lshrrev_b32_e32 v2, 16, v1
 ; GFX11-FAKE16-NEXT:    v_and_b32_e32 v3, 0xff, v0
-; GFX11-FAKE16-NEXT:    v_bfe_u32 v0, v0, 16, 8
+; GFX11-FAKE16-NEXT:    v_lshrrev_b32_e32 v0, 16, v0
 ; GFX11-FAKE16-NEXT:    v_lshlrev_b32_e32 v2, 8, v2
 ; GFX11-FAKE16-NEXT:    v_lshlrev_b32_e32 v3, 16, v3
 ; GFX11-FAKE16-NEXT:    v_lshlrev_b32_e32 v0, 24, v0
@@ -841,15 +781,15 @@ define amdgpu_ps i32 @s_usubsat_v4i8(i32 inreg %lhs.arg, i32 inreg %rhs.arg) {
 ; GFX9-NEXT:    s_lshr_b32 s2, s2, 0x80008
 ; GFX9-NEXT:    s_lshr_b32 s1, s1, 8
 ; GFX9-NEXT:    s_pack_ll_b32_b16 s1, s2, s1
-; GFX9-NEXT:    s_and_b32 s2, s0, 0xff
-; GFX9-NEXT:    s_bfe_u32 s0, s0, 0x80010
-; GFX9-NEXT:    s_lshl_b32 s0, s0, 8
-; GFX9-NEXT:    s_or_b32 s0, s2, s0
-; GFX9-NEXT:    s_and_b32 s2, s1, 0xff
-; GFX9-NEXT:    s_lshl_b32 s2, s2, 16
-; GFX9-NEXT:    s_bfe_u32 s1, s1, 0x80010
+; GFX9-NEXT:    s_lshr_b32 s2, s0, 16
+; GFX9-NEXT:    s_lshr_b32 s3, s1, 16
+; GFX9-NEXT:    s_and_b32 s0, s0, 0xff
+; GFX9-NEXT:    s_lshl_b32 s2, s2, 8
+; GFX9-NEXT:    s_and_b32 s1, s1, 0xff
 ; GFX9-NEXT:    s_or_b32 s0, s0, s2
-; GFX9-NEXT:    s_lshl_b32 s1, s1, 24
+; GFX9-NEXT:    s_lshl_b32 s1, s1, 16
+; GFX9-NEXT:    s_or_b32 s0, s0, s1
+; GFX9-NEXT:    s_lshl_b32 s1, s3, 24
 ; GFX9-NEXT:    s_or_b32 s0, s0, s1
 ; GFX9-NEXT:    ; return to shader part epilog
 ;
@@ -895,13 +835,13 @@ define amdgpu_ps i32 @s_usubsat_v4i8(i32 inreg %lhs.arg, i32 inreg %rhs.arg) {
 ; GFX10-NEXT:    s_lshr_b32 s1, s1, 8
 ; GFX10-NEXT:    s_pack_ll_b32_b16 s0, s2, s0
 ; GFX10-NEXT:    s_pack_ll_b32_b16 s1, s3, s1
-; GFX10-NEXT:    s_bfe_u32 s2, s0, 0x80010
+; GFX10-NEXT:    s_lshr_b32 s2, s0, 16
 ; GFX10-NEXT:    s_and_b32 s0, s0, 0xff
 ; GFX10-NEXT:    s_lshl_b32 s2, s2, 8
 ; GFX10-NEXT:    s_and_b32 s3, s1, 0xff
 ; GFX10-NEXT:    s_or_b32 s0, s0, s2
 ; GFX10-NEXT:    s_lshl_b32 s2, s3, 16
-; GFX10-NEXT:    s_bfe_u32 s1, s1, 0x80010
+; GFX10-NEXT:    s_lshr_b32 s1, s1, 16
 ; GFX10-NEXT:    s_or_b32 s0, s0, s2
 ; GFX10-NEXT:    s_lshl_b32 s1, s1, 24
 ; GFX10-NEXT:    s_or_b32 s0, s0, s1
@@ -1001,13 +941,13 @@ define amdgpu_ps i32 @s_usubsat_v4i8(i32 inreg %lhs.arg, i32 inreg %rhs.arg) {
 ; GFX11-FAKE16-NEXT:    s_lshr_b32 s1, s1, 8
 ; GFX11-FAKE16-NEXT:    s_pack_ll_b32_b16 s0, s2, s0
 ; GFX11-FAKE16-NEXT:    s_pack_ll_b32_b16 s1, s3, s1
-; GFX11-FAKE16-NEXT:    s_bfe_u32 s2, s0, 0x80010
+; GFX11-FAKE16-NEXT:    s_lshr_b32 s2, s0, 16
 ; GFX11-FAKE16-NEXT:    s_and_b32 s0, s0, 0xff
 ; GFX11-FAKE16-NEXT:    s_lshl_b32 s2, s2, 8
 ; GFX11-FAKE16-NEXT:    s_and_b32 s3, s1, 0xff
 ; GFX11-FAKE16-NEXT:    s_or_b32 s0, s0, s2
 ; GFX11-FAKE16-NEXT:    s_lshl_b32 s2, s3, 16
-; GFX11-FAKE16-NEXT:    s_bfe_u32 s1, s1, 0x80010
+; GFX11-FAKE16-NEXT:    s_lshr_b32 s1, s1, 16
 ; GFX11-FAKE16-NEXT:    s_or_b32 s0, s0, s2
 ; GFX11-FAKE16-NEXT:    s_lshl_b32 s1, s1, 24
 ; GFX11-FAKE16-NEXT:    s_or_b32 s0, s0, s1
diff --git a/llvm/test/CodeGen/AMDGPU/v_sat_pk_u8_i16.ll b/llvm/test/CodeGen/AMDGPU/v_sat_pk_u8_i16.ll
index 58ccba8b84b56..61a631d29de6e 100644
--- a/llvm/test/CodeGen/AMDGPU/v_sat_pk_u8_i16.ll
+++ b/llvm/test/CodeGen/AMDGPU/v_sat_pk_u8_i16.ll
@@ -1783,7 +1783,7 @@ define i16 @basic_smax_smin_vec_input_rev(<2 x i16> %src) {
 ; GISEL-GFX9-NEXT:    v_pk_min_i16 v0, v1, v0
 ; GISEL-GFX9-NEXT:    v_mov_b32_e32 v1, 0xff
 ; GISEL-GFX9-NEXT:    v_and_b32_sdwa v1, v0, v1 dst_sel:BYTE_1 dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
-; GISEL-GFX9-NEXT:    v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
+; GISEL-GFX9-NEXT:    v_or_b32_e32 v0, v0, v1
 ; GISEL-GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GISEL-GFX11-TRUE16-LABEL: basic_smax_smin_vec_input_rev:
@@ -1804,8 +1804,7 @@ define i16 @basic_smax_smin_vec_input_rev(<2 x i16> %src) {
 ; GISEL-GFX11-FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
 ; GISEL-GFX11-FAKE16-NEXT:    v_pk_min_i16 v0, 0xff00ff, v0
 ; GISEL-GFX11-FAKE16-NEXT:    v_lshrrev_b32_e32 v1, 16, v0
-; GISEL-GFX11-FAKE16-NEXT:    v_and_b32_e32 v0, 0xff, v0
-; GISEL-GFX11-FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GISEL-GFX11-FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
 ; GISEL-GFX11-FAKE16-NEXT:    v_and_b32_e32 v1, 0xff, v1
 ; GISEL-GFX11-FAKE16-NEXT:    v_lshlrev_b16 v1, 8, v1
 ; GISEL-GFX11-FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
@@ -1838,8 +1837,7 @@ define i16 @basic_smax_smin_vec_input_rev(<2 x i16> %src) {
 ; GISEL-GFX12-FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
 ; GISEL-GFX12-FAKE16-NEXT:    v_pk_min_i16 v0, 0xff00ff, v0
 ; GISEL-GFX12-FAKE16-NEXT:    v_lshrrev_b32_e32 v1, 16, v0
-; GISEL-GFX12-FAKE16-NEXT:    v_and_b32_e32 v0, 0xff, v0
-; GISEL-GFX12-FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GISEL-GFX12-FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
 ; GISEL-GFX12-FAKE16-NEXT:    v_and_b32_e32 v1, 0xff, v1
 ; GISEL-GFX12-FAKE16-NEXT:    v_lshlrev_b16 v1, 8, v1
 ; GISEL-GFX12-FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1)

>From 8a886d7421e871bfec6cb01a1bf03b2f17db753e Mon Sep 17 00:00:00 2001
From: Xaver Fabian <xaver.fabian at gmail.com>
Date: Tue, 18 Aug 2026 16:08:48 +0200
Subject: [PATCH 3/4] Update
 llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir

Co-authored-by: Matt Arsenault <arsenm2 at gmail.com>
---
 llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir
index 64d34f78c2db3..924f9da0600f5 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir
@@ -1,6 +1,6 @@
 # NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5
-# RUN: llc -mtriple aarch64 -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s --check-prefixes=CHECK,LE
-# RUN: llc -mtriple aarch64_be -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s --check-prefixes=CHECK,BE
+# RUN: llc -mtriple=aarch64 -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s --check-prefixes=CHECK,LE
+# RUN: llc -mtriple=aarch64_be -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s --check-prefixes=CHECK,BE
 
 ---
 name: bitcast_splat_constant

>From d33747a56b0444cf3fe2cabd813a4ea0ae50a3c2 Mon Sep 17 00:00:00 2001
From: Xaver Fabian <xaver.fabian at gmail.com>
Date: Tue, 18 Aug 2026 17:58:22 +0200
Subject: [PATCH 4/4] Address review comments

---
 llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp     |  8 ++++----
 .../CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir   | 10 ++++++----
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 7b1a5482e1e75..aa919b0f87fc8 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -1122,12 +1122,12 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
       break;
     Register SrcReg = MI.getOperand(1).getReg();
     LLT SrcTy = MRI.getType(SrcReg);
+    // Ignore bitcasts from untyped sources.
+    if (SrcTy.isAnyScalar() || SrcTy.isAnyVector())
+      break;
+
     unsigned SrcBitWidth = SrcTy.getScalarSizeInBits();
     unsigned NumElts = DemandedElts.getBitWidth();
-    // Ignore bitcasts from unsupported types.
-    if (!(SrcTy.isInteger() || SrcTy.isIntegerVector() ||
-          SrcTy.isFloatOrFloatVector()))
-      break;
 
     // Fast handling of 'identity' bitcasts.
     if (BitWidth == SrcBitWidth) {
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir
index 924f9da0600f5..2aa304184ebf4 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-bitcast.mir
@@ -93,10 +93,12 @@ name: bitcast_address_space
 body: |
   bb.0:
   ; CHECK-LABEL: name: @bitcast_address_space
-  ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
-  ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
-    %0:_(p0) = COPY $x0
-    %1:_(p1) = G_BITCAST %0(p0)
+  ; CHECK-NEXT: %0:_ KnownBits:0000000000000000000000000000000000000000000000000000000000001100 SignBits:60 IsKnownNeverZero:1
+  ; CHECK-NEXT: %1:_ KnownBits:0000000000000000000000000000000000000000000000000000000000001100 SignBits:60 IsKnownNeverZero:1
+  ; CHECK-NEXT: %2:_ KnownBits:0000000000000000000000000000000000000000000000000000000000001100 SignBits:60 IsKnownNeverZero:1
+    %0:_(i64) = G_CONSTANT i64 12
+    %1:_(p0) = G_INTTOPTR %0(i64)
+    %2:_(p1) = G_BITCAST %1(p0)
 ...
 ---
 name: bitcast_small_large_alternating



More information about the llvm-commits mailing list