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

Kristina Bessonova via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 13 12:51:12 PDT 2026


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

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.

>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] [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
+}



More information about the llvm-commits mailing list