[clang] [llvm] [SROA] Vector promote some memsets (PR #133301)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 30 01:42:50 PDT 2025


================
@@ -0,0 +1,124 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes='sroa' -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
+
+%ptr_pair = type { ptr, ptr }
+
+%struct.a = type { <32 x i8> }
+define void @vector_promote_memset_a(ptr %0) {
+; CHECK-LABEL: @vector_promote_memset_a(
+; CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8
+; CHECK-NEXT:    [[TMP3:%.*]] = load i8, ptr [[TMP2]], align 1
+; CHECK-NEXT:    [[DOTSROA_0_0_VEC_INSERT:%.*]] = insertelement <32 x i8> zeroinitializer, i8 [[TMP3]], i32 0
+; CHECK-NEXT:    ret void
+;
+  %2 = alloca %struct.a, align 32
+  %3 = alloca %ptr_pair, align 8
+  call void @llvm.memset.p0.i64(ptr align 32 %2, i8 0, i64 32, i1 false)
+
+  store ptr %2, ptr %3, align 8
+
+  %4 = getelementptr inbounds %ptr_pair, ptr %3, i64 0, i32 1
+  %5 = load ptr, ptr %0, align 8
+  store ptr %5, ptr %4, align 8
+
+  %6 = getelementptr inbounds i8, ptr %3, i32 8
+  %7 = load ptr, ptr %6, align 8
+
+  %8 = load i8, ptr %7, align 1
+  store i8 %8, ptr %2, align 32
+
+  ret void
+}
+
+%struct.b = type { <16 x i16> }
+define void @vector_promote_memset_b(ptr %0) {
+; CHECK-LABEL: @vector_promote_memset_b(
+; CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8
+; CHECK-NEXT:    [[TMP3:%.*]] = load i16, ptr [[TMP2]], align 1
+; CHECK-NEXT:    [[DOTSROA_0_0_VEC_INSERT:%.*]] = insertelement <16 x i16> zeroinitializer, i16 [[TMP3]], i32 0
+; CHECK-NEXT:    ret void
+;
+  %2 = alloca %struct.b, align 16
+  %3 = alloca %ptr_pair, align 8
+  call void @llvm.memset.p0.i64(ptr align 32 %2, i8 0, i64 32, i1 false)
+
+  store ptr %2, ptr %3, align 8
+
+  %4 = getelementptr inbounds %ptr_pair, ptr %3, i64 0, i32 1
+  %5 = load ptr, ptr %0, align 8
+  store ptr %5, ptr %4, align 8
+
+  %6 = getelementptr inbounds i8, ptr %3, i32 8
+  %7 = load ptr, ptr %6, align 8
+
+  %8 = load i16, ptr %7, align 1
+  store i16 %8, ptr %2, align 16
+
+  ret void
+}
+
+%struct.c = type { <4 x i32> }
+define void @vector_promote_memset_c(ptr %0) {
+; CHECK-LABEL: @vector_promote_memset_c(
+; CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8
+; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 1
+; CHECK-NEXT:    [[DOTSROA_0_8_VEC_INSERT:%.*]] = insertelement <4 x i32> zeroinitializer, i32 [[TMP3]], i32 2
+; CHECK-NEXT:    ret void
+;
+  %2 = alloca %struct.c, align 4
+  %3 = alloca %ptr_pair, align 8
+  call void @llvm.memset.p0.i64(ptr align 32 %2, i8 0, i64 16, i1 false)
+
+  store ptr %2, ptr %3, align 8
+
+  %4 = getelementptr inbounds %ptr_pair, ptr %3, i64 0, i32 1
+  %5 = load ptr, ptr %0, align 8
+  store ptr %5, ptr %4, align 8
+
+  %6 = getelementptr inbounds i8, ptr %3, i32 8
+  %7 = load ptr, ptr %6, align 8
+
+  %8 = load i32, ptr %7, align 1
+
+  %9 = getelementptr inbounds i32, ptr %2, i32 2
+  store i32 %8, ptr %9, align 4
+
+  ret void
+}
+
+; We currently prevent promotion if the vector would require padding
+%struct.d = type { <6 x i32> }
+define void @vector_promote_memset_d(ptr %0) {
+; CHECK-LABEL: @vector_promote_memset_d(
+; CHECK-NEXT:    [[DOTSROA_2:%.*]] = alloca [3 x i32], align 4
+; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[DOTSROA_2]], i8 0, i64 12, i1 false)
+; CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8
+; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 1
+; CHECK-NEXT:    ret void
+;
+  %2 = alloca %struct.d, align 4
+  %3 = alloca %ptr_pair, align 8
+  call void @llvm.memset.p0.i64(ptr align 32 %2, i8 0, i64 24, i1 false)
+
+  store ptr %2, ptr %3, align 8
+
+  %4 = getelementptr inbounds %ptr_pair, ptr %3, i64 0, i32 1
+  %5 = load ptr, ptr %0, align 8
+  store ptr %5, ptr %4, align 8
+
+  %6 = getelementptr inbounds i8, ptr %3, i32 8
+  %7 = load ptr, ptr %6, align 8
+
+  %8 = load i32, ptr %7, align 1
+
+  %9 = getelementptr inbounds i32, ptr %2, i32 2
+  store i32 %8, ptr %9, align 4
+
+  ret void
+}
+
----------------
arsenm wrote:

Test with the number of elements equalling and exceeding 32-bit limit case? 

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


More information about the llvm-commits mailing list