[llvm] [SPARC] Don't combine misaligned memory ops with BSWAP (PR #206345)

Sergei Barannikov via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 4 00:54:13 PDT 2026


================
@@ -262,4 +479,192 @@ define void @u64_bswapstore(ptr %0, i64 %1) #0 {
   ret void
 }
 
+define void @u16_bswapstore_misaligned(ptr %0, i16 %1) #0 {
+; SPARC32-LABEL: u16_bswapstore_misaligned:
+; SPARC32:       ! %bb.0:
+; SPARC32-NEXT:    add %sp, -96, %sp
+; SPARC32-NEXT:    add %sp, 92, %o2
+; SPARC32-NEXT:    sta %o1, [%o2] #ASI_P_L
+; SPARC32-NEXT:    ld [%sp+92], %o1
+; SPARC32-NEXT:    srl %o1, 16, %o2
+; SPARC32-NEXT:    stb %o2, [%o0+1]
+; SPARC32-NEXT:    srl %o1, 24, %o1
+; SPARC32-NEXT:    stb %o1, [%o0]
+; SPARC32-NEXT:    retl
+; SPARC32-NEXT:    add %sp, 96, %sp
+;
+; SPARCEL-LABEL: u16_bswapstore_misaligned:
+; SPARCEL:       ! %bb.0:
+; SPARCEL-NEXT:    add %sp, -96, %sp
+; SPARCEL-NEXT:    add %sp, 92, %o2
+; SPARCEL-NEXT:    sta %o1, [%o2] #ASI_P
+; SPARCEL-NEXT:    ld [%sp+92], %o1
+; SPARCEL-NEXT:    srl %o1, 16, %o2
+; SPARCEL-NEXT:    srl %o1, 24, %o1
+; SPARCEL-NEXT:    stb %o1, [%o0+1]
+; SPARCEL-NEXT:    stb %o2, [%o0]
+; SPARCEL-NEXT:    retl
+; SPARCEL-NEXT:    add %sp, 96, %sp
+;
+; SPARC64-LABEL: u16_bswapstore_misaligned:
+; SPARC64:       ! %bb.0:
+; SPARC64-NEXT:    add %sp, -144, %sp
+; SPARC64-NEXT:    add %sp, 2187, %o2
+; SPARC64-NEXT:    sta %o1, [%o2] #ASI_P_L
+; SPARC64-NEXT:    ld [%sp+2187], %o1
+; SPARC64-NEXT:    srl %o1, 16, %o2
+; SPARC64-NEXT:    stb %o2, [%o0+1]
+; SPARC64-NEXT:    srl %o1, 24, %o1
+; SPARC64-NEXT:    stb %o1, [%o0]
+; SPARC64-NEXT:    retl
+; SPARC64-NEXT:    add %sp, 144, %sp
+  %3 = tail call i16 @llvm.bswap.i16(i16 %1)
+  store i16 %3, ptr %0, align 1
+  ret void
+}
+
+define void @u32_bswapstore_misaligned(ptr %0, i32 %1) #0 {
+; SPARC32-LABEL: u32_bswapstore_misaligned:
+; SPARC32:       ! %bb.0:
+; SPARC32-NEXT:    add %sp, -96, %sp
+; SPARC32-NEXT:    add %sp, 92, %o2
+; SPARC32-NEXT:    sta %o1, [%o2] #ASI_P_L
+; SPARC32-NEXT:    ld [%sp+92], %o1
+; SPARC32-NEXT:    stb %o1, [%o0+3]
+; SPARC32-NEXT:    srl %o1, 8, %o2
+; SPARC32-NEXT:    stb %o2, [%o0+2]
+; SPARC32-NEXT:    srl %o1, 16, %o2
+; SPARC32-NEXT:    stb %o2, [%o0+1]
+; SPARC32-NEXT:    srl %o1, 24, %o1
+; SPARC32-NEXT:    stb %o1, [%o0]
+; SPARC32-NEXT:    retl
+; SPARC32-NEXT:    add %sp, 96, %sp
+;
+; SPARCEL-LABEL: u32_bswapstore_misaligned:
+; SPARCEL:       ! %bb.0:
+; SPARCEL-NEXT:    add %sp, -96, %sp
+; SPARCEL-NEXT:    add %sp, 92, %o2
+; SPARCEL-NEXT:    sta %o1, [%o2] #ASI_P
+; SPARCEL-NEXT:    ld [%sp+92], %o1
+; SPARCEL-NEXT:    stb %o1, [%o0]
+; SPARCEL-NEXT:    srl %o1, 24, %o2
+; SPARCEL-NEXT:    stb %o2, [%o0+3]
+; SPARCEL-NEXT:    srl %o1, 16, %o2
+; SPARCEL-NEXT:    stb %o2, [%o0+2]
+; SPARCEL-NEXT:    srl %o1, 8, %o1
+; SPARCEL-NEXT:    stb %o1, [%o0+1]
+; SPARCEL-NEXT:    retl
+; SPARCEL-NEXT:    add %sp, 96, %sp
+;
+; SPARC64-LABEL: u32_bswapstore_misaligned:
+; SPARC64:       ! %bb.0:
+; SPARC64-NEXT:    add %sp, -144, %sp
+; SPARC64-NEXT:    add %sp, 2187, %o2
+; SPARC64-NEXT:    sta %o1, [%o2] #ASI_P_L
+; SPARC64-NEXT:    ld [%sp+2187], %o1
+; SPARC64-NEXT:    stb %o1, [%o0+3]
+; SPARC64-NEXT:    srl %o1, 8, %o2
+; SPARC64-NEXT:    stb %o2, [%o0+2]
+; SPARC64-NEXT:    srl %o1, 16, %o2
+; SPARC64-NEXT:    stb %o2, [%o0+1]
+; SPARC64-NEXT:    srl %o1, 24, %o1
+; SPARC64-NEXT:    stb %o1, [%o0]
+; SPARC64-NEXT:    retl
+; SPARC64-NEXT:    add %sp, 144, %sp
+  %3 = tail call i32 @llvm.bswap.i32(i32 %1)
+  store i32 %3, ptr %0, align 1
+  ret void
+}
+
+define void @u64_bswapstore_misaligned(ptr %0, i64 %1) #0 {
+; SPARC32-LABEL: u64_bswapstore_misaligned:
+; SPARC32:       ! %bb.0:
+; SPARC32-NEXT:    add %sp, -112, %sp
+; SPARC32-NEXT:    add %sp, 96, %o3
+; SPARC32-NEXT:    sta %o1, [%o3] #ASI_P_L
+; SPARC32-NEXT:    add %sp, 100, %o1
+; SPARC32-NEXT:    sta %o2, [%o1] #ASI_P_L
+; SPARC32-NEXT:    ld [%sp+96], %o3
+; SPARC32-NEXT:    ld [%sp+100], %o2
+; SPARC32-NEXT:    std %o2, [%sp+104]
+; SPARC32-NEXT:    add %sp, 104, %o1
+; SPARC32-NEXT:    or %o1, 4, %o1
+; SPARC32-NEXT:    ld [%o1], %o1
+; SPARC32-NEXT:    stb %o1, [%o0+7]
+; SPARC32-NEXT:    ld [%sp+104], %o2
+; SPARC32-NEXT:    stb %o2, [%o0+3]
+; SPARC32-NEXT:    srl %o1, 8, %o3
+; SPARC32-NEXT:    stb %o3, [%o0+6]
+; SPARC32-NEXT:    srl %o1, 16, %o3
+; SPARC32-NEXT:    stb %o3, [%o0+5]
+; SPARC32-NEXT:    srl %o1, 24, %o1
+; SPARC32-NEXT:    stb %o1, [%o0+4]
+; SPARC32-NEXT:    srl %o2, 8, %o1
+; SPARC32-NEXT:    stb %o1, [%o0+2]
+; SPARC32-NEXT:    srl %o2, 16, %o1
+; SPARC32-NEXT:    stb %o1, [%o0+1]
+; SPARC32-NEXT:    srl %o2, 24, %o1
+; SPARC32-NEXT:    stb %o1, [%o0]
+; SPARC32-NEXT:    retl
+; SPARC32-NEXT:    add %sp, 112, %sp
+;
+; SPARCEL-LABEL: u64_bswapstore_misaligned:
+; SPARCEL:       ! %bb.0:
+; SPARCEL-NEXT:    add %sp, -112, %sp
+; SPARCEL-NEXT:    add %sp, 96, %o3
+; SPARCEL-NEXT:    sta %o1, [%o3] #ASI_P
+; SPARCEL-NEXT:    add %sp, 100, %o1
+; SPARCEL-NEXT:    sta %o2, [%o1] #ASI_P
+; SPARCEL-NEXT:    ld [%sp+96], %o3
+; SPARCEL-NEXT:    ld [%sp+100], %o2
+; SPARCEL-NEXT:    std %o2, [%sp+104]
+; SPARCEL-NEXT:    add %sp, 104, %o1
+; SPARCEL-NEXT:    or %o1, 4, %o1
+; SPARCEL-NEXT:    ld [%o1], %o1
+; SPARCEL-NEXT:    stb %o1, [%o0+4]
+; SPARCEL-NEXT:    ld [%sp+104], %o2
+; SPARCEL-NEXT:    stb %o2, [%o0]
+; SPARCEL-NEXT:    srl %o1, 24, %o3
+; SPARCEL-NEXT:    stb %o3, [%o0+7]
+; SPARCEL-NEXT:    srl %o1, 16, %o3
+; SPARCEL-NEXT:    stb %o3, [%o0+6]
+; SPARCEL-NEXT:    srl %o1, 8, %o1
+; SPARCEL-NEXT:    stb %o1, [%o0+5]
+; SPARCEL-NEXT:    srl %o2, 24, %o1
+; SPARCEL-NEXT:    stb %o1, [%o0+3]
+; SPARCEL-NEXT:    srl %o2, 16, %o1
+; SPARCEL-NEXT:    stb %o1, [%o0+2]
+; SPARCEL-NEXT:    srl %o2, 8, %o1
+; SPARCEL-NEXT:    stb %o1, [%o0+1]
+; SPARCEL-NEXT:    retl
+; SPARCEL-NEXT:    add %sp, 112, %sp
+;
+; SPARC64-LABEL: u64_bswapstore_misaligned:
+; SPARC64:       ! %bb.0:
+; SPARC64-NEXT:    add %sp, -144, %sp
+; SPARC64-NEXT:    add %sp, 2183, %o2
+; SPARC64-NEXT:    stxa %o1, [%o2] #ASI_P_L
+; SPARC64-NEXT:    ldx [%sp+2183], %o1
----------------
s-barannikov wrote:

> This one would expand to byte stores anyway since SPARC doesn't allow misaligned stores at all...

Then I don't know if we can do anything better than a libcall here.

https://github.com/llvm/llvm-project/pull/206345


More information about the llvm-commits mailing list