[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