[llvm] [GlobalISel] Add known bits calculation for atomic G_LOAD (PR #222870)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 11 00:35:26 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
@llvm/pr-subscribers-backend-aarch64
Author: MishkaSimakov
<details>
<summary>Changes</summary>
Ported code from SelectionDAG::computeKnownBits for G_LOAD with atomic argument.
Part of https://github.com/llvm/llvm-project/issues/150515.
Ticks off ATOMIC_LOAD for computeKnownBits.
Six tests for AMDGPU were updated because better known bits analysis leads to different instructions in these cases.
I've compared output of llc with updated GISel to the output of llc with SelectionDAG on these tests.
Ultimately in atomic_load_*_monotonic_i16_d16_lo_vector_insert tests `(0xffff & v0) | (~0xffff & v2)` is replaced with `(v2 & 0xffff0000) | v0`. This is correct, because atomic loads zero extend 16 bits when loading to v0.
In atomic_load_*_monotonic_i16_d16_hi_vector_insert tests v_perm_b32 is replaced with equivalent combination of v_lshlrev_b32_e32 and v_and_or_b32.
---
Full diff: https://github.com/llvm/llvm-project/pull/222870.diff
6 Files Affected:
- (modified) llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp (+17-1)
- (added) llvm/test/CodeGen/AArch64/GlobalISel/knownbits-atomic-load.mir (+65)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/atomic_load_flat.ll (+7-8)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/atomic_load_global.ll (+7-8)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/atomic_load_local_2.ll (+7-6)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/knownbits-atomic-load.mir (+32)
``````````diff
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index d8e94cecc5e2a..4fcc767367397 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -708,7 +708,23 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
KnownBits KnownRange(MMO->getMemoryType().getScalarSizeInBits());
if (const MDNode *Ranges = MMO->getRanges())
computeKnownBitsFromRangeMetadata(*Ranges, KnownRange);
- Known = KnownRange.anyext(Known.getBitWidth());
+
+ if (MMO->isAtomic()) {
+ switch (TL.getExtendForAtomicOps()) {
+ case ISD::ZERO_EXTEND:
+ Known = KnownRange.zext(Known.getBitWidth());
+ break;
+ case ISD::SIGN_EXTEND:
+ Known = KnownRange.sext(Known.getBitWidth());
+ break;
+ default:
+ Known = KnownRange.anyext(Known.getBitWidth());
+ break;
+ }
+ } else {
+ Known = KnownRange.anyext(Known.getBitWidth());
+ }
+
break;
}
case TargetOpcode::G_SEXTLOAD:
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-atomic-load.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-atomic-load.mir
new file mode 100644
index 0000000000000..b3ee86af4b229
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-atomic-load.mir
@@ -0,0 +1,65 @@
+# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple=aarch64 -passes="print<gisel-value-tracking>" -filetype=null %s 2>&1 | FileCheck %s
+
+--- |
+ define void @Extend() { unreachable }
+ define void @WithoutExtend() { unreachable }
+ define void @WithRangeMetadataAllBitsKnown() { unreachable }
+ define void @WithRangeMetadataSomeBitsUnknown() { unreachable }
+ define void @DoesntSignExtend() { unreachable }
+
+ !0 = !{i8 1, i8 2}
+ !1 = !{i8 1, i8 5}
+ !2 = !{i8 255, i8 256}
+
+...
+---
+name: Extend
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @Extend
+ ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %1:_ KnownBits:000000000000000000000000???????? SignBits:1 IsKnownNeverZero:0
+ %0:_(p0) = G_IMPLICIT_DEF
+ %1:_(i32) = G_LOAD %0(p0) :: (load seq_cst (i8))
+...
+---
+name: WithoutExtend
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @WithoutExtend
+ ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1 IsKnownNeverZero:0
+ %0:_(p0) = G_IMPLICIT_DEF
+ %1:_(i32) = G_LOAD %0(p0) :: (load seq_cst (i32))
+...
+---
+name: WithRangeMetadataAllBitsKnown
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @WithRangeMetadataAllBitsKnown
+ ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %1:_ KnownBits:00000000000000000000000000000001 SignBits:7 IsKnownNeverZero:1
+ %0:_(p0) = G_IMPLICIT_DEF
+ %1:_(i32) = G_LOAD %0(p0) :: (load seq_cst (i8), !range !0)
+...
+---
+name: WithRangeMetadataSomeBitsUnknown
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @WithRangeMetadataSomeBitsUnknown
+ ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %1:_ KnownBits:00000000000000000000000000000??? SignBits:5 IsKnownNeverZero:0
+ %0:_(p0) = G_IMPLICIT_DEF
+ %1:_(i32) = G_LOAD %0(p0) :: (load seq_cst (i8), !range !1)
+...
+---
+name: DoesntSignExtend
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @DoesntSignExtend
+ ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %1:_ KnownBits:00000000000000000000000011111111 SignBits:8 IsKnownNeverZero:1
+ %0:_(p0) = G_IMPLICIT_DEF
+ %1:_(i32) = G_LOAD %0(p0) :: (load seq_cst (i8), !range !2)
+...
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/atomic_load_flat.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/atomic_load_flat.ll
index fe64a5b1bbcdc..d64f22900f415 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/atomic_load_flat.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/atomic_load_flat.ll
@@ -182,11 +182,11 @@ define <2 x i16> @atomic_load_flat_monotonic_i16_d16_hi_vector_insert(ptr %ptr,
; GFX9-LABEL: atomic_load_flat_monotonic_i16_d16_hi_vector_insert:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: flat_load_ushort v3, v[0:1] glc
-; GFX9-NEXT: s_nop 0
-; GFX9-NEXT: flat_load_short_d16_hi v2, v[0:1] glc
+; GFX9-NEXT: flat_load_ushort v0, v[0:1] glc
+; GFX9-NEXT: v_mov_b32_e32 v1, 0xffff
; GFX9-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)
-; GFX9-NEXT: v_mov_b32_e32 v0, v2
+; GFX9-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX9-NEXT: v_and_or_b32 v0, v2, v1, v0
; GFX9-NEXT: s_setpc_b64 s[30:31]
%load = load atomic i16, ptr %ptr monotonic, align 2
%insert = insertelement <2 x i16> %vec, i16 %load, i32 1
@@ -252,11 +252,10 @@ define <2 x i16> @atomic_load_flat_monotonic_i16_d16_lo_vector_insert(ptr %ptr,
; GFX9-LABEL: atomic_load_flat_monotonic_i16_d16_lo_vector_insert:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: flat_load_ushort v3, v[0:1] glc
-; GFX9-NEXT: s_nop 0
-; GFX9-NEXT: flat_load_short_d16 v2, v[0:1] glc
+; GFX9-NEXT: flat_load_ushort v0, v[0:1] glc
+; GFX9-NEXT: v_mov_b32_e32 v1, 0xffff0000
; GFX9-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0)
-; GFX9-NEXT: v_mov_b32_e32 v0, v2
+; GFX9-NEXT: v_and_or_b32 v0, v2, v1, v0
; GFX9-NEXT: s_setpc_b64 s[30:31]
%load = load atomic i16, ptr %ptr monotonic, align 2
%insert = insertelement <2 x i16> %vec, i16 %load, i32 0
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/atomic_load_global.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/atomic_load_global.ll
index f555a2073b46c..02d300763b943 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/atomic_load_global.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/atomic_load_global.ll
@@ -511,11 +511,11 @@ define <2 x i16> @atomic_load_global_monotonic_i16_d16_hi_vector_insert(ptr addr
; GFX9-LABEL: atomic_load_global_monotonic_i16_d16_hi_vector_insert:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: global_load_ushort v3, v[0:1], off glc
-; GFX9-NEXT: s_nop 0
-; GFX9-NEXT: global_load_short_d16_hi v2, v[0:1], off glc
+; GFX9-NEXT: global_load_ushort v0, v[0:1], off glc
+; GFX9-NEXT: v_mov_b32_e32 v1, 0xffff
; GFX9-NEXT: s_waitcnt vmcnt(0)
-; GFX9-NEXT: v_mov_b32_e32 v0, v2
+; GFX9-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX9-NEXT: v_and_or_b32 v0, v2, v1, v0
; GFX9-NEXT: s_setpc_b64 s[30:31]
%load = load atomic i16, ptr addrspace(1) %ptr monotonic, align 2
%insert = insertelement <2 x i16> %vec, i16 %load, i32 1
@@ -606,11 +606,10 @@ define <2 x i16> @atomic_load_global_monotonic_i16_d16_lo_vector_insert(ptr addr
; GFX9-LABEL: atomic_load_global_monotonic_i16_d16_lo_vector_insert:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: global_load_ushort v3, v[0:1], off glc
-; GFX9-NEXT: s_nop 0
-; GFX9-NEXT: global_load_short_d16 v2, v[0:1], off glc
+; GFX9-NEXT: global_load_ushort v0, v[0:1], off glc
+; GFX9-NEXT: v_mov_b32_e32 v1, 0xffff0000
; GFX9-NEXT: s_waitcnt vmcnt(0)
-; GFX9-NEXT: v_mov_b32_e32 v0, v2
+; GFX9-NEXT: v_and_or_b32 v0, v2, v1, v0
; GFX9-NEXT: s_setpc_b64 s[30:31]
%load = load atomic i16, ptr addrspace(1) %ptr monotonic, align 2
%insert = insertelement <2 x i16> %vec, i16 %load, i32 0
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/atomic_load_local_2.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/atomic_load_local_2.ll
index 717c848d36f7c..a971d1ef1a5f5 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/atomic_load_local_2.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/atomic_load_local_2.ll
@@ -396,10 +396,11 @@ define <2 x i16> @atomic_load_local_monotonic_i16_d16_hi_vector_insert(ptr addrs
; GFX9-LABEL: atomic_load_local_monotonic_i16_d16_hi_vector_insert:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: ds_read_u16 v2, v0
-; GFX9-NEXT: ds_read_u16_d16_hi v1, v0
+; GFX9-NEXT: ds_read_u16 v0, v0
+; GFX9-NEXT: v_mov_b32_e32 v2, 0xffff
; GFX9-NEXT: s_waitcnt lgkmcnt(0)
-; GFX9-NEXT: v_mov_b32_e32 v0, v1
+; GFX9-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX9-NEXT: v_and_or_b32 v0, v1, v2, v0
; GFX9-NEXT: s_setpc_b64 s[30:31]
%load = load atomic i16, ptr addrspace(3) %ptr monotonic, align 2
%insert = insertelement <2 x i16> %vec, i16 %load, i32 1
@@ -469,10 +470,10 @@ define <2 x i16> @atomic_load_local_monotonic_i16_d16_lo_vector_insert(ptr addrs
; GFX9-LABEL: atomic_load_local_monotonic_i16_d16_lo_vector_insert:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: ds_read_u16 v2, v0
-; GFX9-NEXT: ds_read_u16_d16 v1, v0
+; GFX9-NEXT: ds_read_u16 v0, v0
+; GFX9-NEXT: v_mov_b32_e32 v2, 0xffff0000
; GFX9-NEXT: s_waitcnt lgkmcnt(0)
-; GFX9-NEXT: v_mov_b32_e32 v0, v1
+; GFX9-NEXT: v_and_or_b32 v0, v1, v2, v0
; GFX9-NEXT: s_setpc_b64 s[30:31]
%load = load atomic i16, ptr addrspace(3) %ptr monotonic, align 2
%insert = insertelement <2 x i16> %vec, i16 %load, i32 0
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/knownbits-atomic-load.mir b/llvm/test/CodeGen/RISCV/GlobalISel/knownbits-atomic-load.mir
new file mode 100644
index 0000000000000..6bb7d43fab849
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/knownbits-atomic-load.mir
@@ -0,0 +1,32 @@
+# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple=riscv64 -passes="print<gisel-value-tracking>" -filetype=null %s 2>&1 | FileCheck %s
+
+--- |
+ define void @SignExtendZeros() { unreachable }
+ define void @SignExtendOnes() { unreachable }
+
+ !0 = !{i8 0, i8 1}
+ !1 = !{i8 255, i8 256}
+
+...
+---
+name: SignExtendZeros
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @SignExtendZeros
+ ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %1:_ KnownBits:00000000000000000000000000000000 SignBits:8 IsKnownNeverZero:0
+ %0:_(p0) = G_IMPLICIT_DEF
+ %1:_(i32) = G_LOAD %0(p0) :: (load seq_cst (i8), !range !0)
+...
+---
+name: SignExtendOnes
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @SignExtendOnes
+ ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %1:_ KnownBits:11111111111111111111111111111111 SignBits:8 IsKnownNeverZero:1
+ %0:_(p0) = G_IMPLICIT_DEF
+ %1:_(i32) = G_LOAD %0(p0) :: (load seq_cst (i8), !range !1)
+...
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/222870
More information about the llvm-commits
mailing list