[llvm] [AArch64][GlobalISel] Preserve scalar type when widening atomic G_STORE (PR #216162)

Kristina Bessonova via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 17 06:14:18 PDT 2026


https://github.com/chbessonova updated https://github.com/llvm/llvm-project/pull/216162

>From 147023397748b0e58dfbecdc81f19423f35815b8 Mon Sep 17 00:00:00 2001
From: Kristina Bessonova <kbessonova at accesssoftek.com>
Date: Thu, 13 Aug 2026 20:10:16 +0200
Subject: [PATCH 1/3] [AArch64][GlobalISel] Preserve scalar type when widening
 atomic G_STORE

Use `changeElementSizeTo` instead of `changeTo` in the G_STORE
legalization rule for narrow atomic stores.

`changeTo` changes the type of the stored value to generic `s32`,
which can be propagated to its defining instruction. For example,
this can turn an integer `G_AND` into an `s32` operation and prevent
it from being correctly selected.

Changing only the element size preserves the value's scalar type while
still widening the value as required by the legalization rule.
---
 .../AArch64/GISel/AArch64LegalizerInfo.cpp    |  2 +-
 .../GlobalISel/i1-zext-i8-atomic-store.ll     | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/i1-zext-i8-atomic-store.ll

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index b7ad88a02b9ce..1274aab686bae 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -616,7 +616,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
       .widenScalarIf(
           all(scalarNarrowerThan(0, 32),
               atomicOrderingAtLeastOrStrongerThan(0, AtomicOrdering::Release)),
-          changeTo(0, s32))
+          changeElementSizeTo(0, s32))
       .legalForTypesWithMemDesc(
           {{s8, p0, s8, 8},     {s16, p0, s8, 8},  // truncstorei8 from s16
            {s32, p0, s8, 8},                       // truncstorei8 from s32
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/i1-zext-i8-atomic-store.ll b/llvm/test/CodeGen/AArch64/GlobalISel/i1-zext-i8-atomic-store.ll
new file mode 100644
index 0000000000000..05e4be5638003
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/i1-zext-i8-atomic-store.ll
@@ -0,0 +1,19 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -global-isel --global-isel-abort=1 < %s | FileCheck %s
+
+target triple = "aarch64-unknown-linux-gnueabi"
+
+define i32 @test(ptr %p) {
+; CHECK-LABEL: test:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    mov x8, x0
+; CHECK-NEXT:    mov w0, wzr
+; CHECK-NEXT:    ldrb w9, [x8]
+; CHECK-NEXT:    and w9, w9, #0x1
+; CHECK-NEXT:    stlrb w9, [x8]
+; CHECK-NEXT:    ret
+  %v = load i1, ptr %p
+  %v8 = zext i1 %v to i8
+  store atomic i8 %v8, ptr %p seq_cst, align 1
+  ret i32 0
+}

>From d9087306ef70ae8dcb21b135ee9adbe2eef1137f Mon Sep 17 00:00:00 2001
From: Kristina Bessonova <kbessonova at accesssoftek.com>
Date: Sat, 15 Aug 2026 09:51:08 +0200
Subject: [PATCH 2/3] Add MIR test case

---
 .../legalize-non-pow2-load-store.mir          | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-non-pow2-load-store.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-non-pow2-load-store.mir
index c1d93931f8e5a..d145bbcfbce1d 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-non-pow2-load-store.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-non-pow2-load-store.mir
@@ -173,3 +173,28 @@ body:             |
     %val:_(i142) = G_IMPLICIT_DEF
     G_STORE %val(i142), %ptr(p0) :: (store (i142), align 8)
     RET_ReallyLR
+
+...
+---
+name:            store_i1_zext_i8
+alignment:       4
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $x0
+    ; CHECK-LABEL: name: store_i1_zext_i8
+    ; CHECK: liveins: $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(i8) = G_LOAD [[COPY]](p0) :: (load (i8))
+    ; CHECK-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(i8) = G_ASSERT_ZEXT [[LOAD]], 1
+    ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(i32) = G_ANYEXT [[ASSERT_ZEXT]](i8)
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 1
+    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(i32) = G_AND [[ANYEXT]], [[C]]
+    ; CHECK-NEXT: G_STORE [[AND]](i32), [[COPY]](p0) :: (store seq_cst (i8))
+    ; CHECK-NEXT: RET_ReallyLR
+    %0:_(p0) = COPY $x0
+    %1:_(i1) = G_LOAD %0(p0) :: (load (i1))
+    %2:_(i8) = G_ZEXT %1(i1)
+    G_STORE %2(i8), %0(p0) :: (store seq_cst (i8))
+    RET_ReallyLR

>From 63343b0dafe47ef024fafd74fb04350dccf03c21 Mon Sep 17 00:00:00 2001
From: Kristina Bessonova <kbessonova at accesssoftek.com>
Date: Mon, 17 Aug 2026 15:13:07 +0200
Subject: [PATCH 3/3] Add trailing ...

---
 .../CodeGen/AArch64/GlobalISel/legalize-non-pow2-load-store.mir  | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-non-pow2-load-store.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-non-pow2-load-store.mir
index d145bbcfbce1d..4990f1b95bd0d 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-non-pow2-load-store.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-non-pow2-load-store.mir
@@ -198,3 +198,4 @@ body:             |
     %2:_(i8) = G_ZEXT %1(i1)
     G_STORE %2(i8), %0(p0) :: (store seq_cst (i8))
     RET_ReallyLR
+...



More information about the llvm-commits mailing list