[llvm] e30d304 - [MemCpyOpt] Introduce test for PR101930 (NFC)
Antonio Frighetto via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 3 00:54:36 PST 2024
Author: Antonio Frighetto
Date: 2024-12-03T09:50:56+01:00
New Revision: e30d304d72ac9a70671268c50ee850c2f0c42ba3
URL: https://github.com/llvm/llvm-project/commit/e30d304d72ac9a70671268c50ee850c2f0c42ba3
DIFF: https://github.com/llvm/llvm-project/commit/e30d304d72ac9a70671268c50ee850c2f0c42ba3.diff
LOG: [MemCpyOpt] Introduce test for PR101930 (NFC)
Added:
llvm/test/Transforms/MemCpyOpt/memset-memmove-redundant-memmove.ll
Modified:
Removed:
################################################################################
diff --git a/llvm/test/Transforms/MemCpyOpt/memset-memmove-redundant-memmove.ll b/llvm/test/Transforms/MemCpyOpt/memset-memmove-redundant-memmove.ll
new file mode 100644
index 00000000000000..4b09a2057b4c31
--- /dev/null
+++ b/llvm/test/Transforms/MemCpyOpt/memset-memmove-redundant-memmove.ll
@@ -0,0 +1,183 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=memcpyopt -S %s -verify-memoryssa | FileCheck %s
+
+; Redundant memmove.
+define i32 @redundant_memmove() {
+; CHECK-LABEL: @redundant_memmove(
+; CHECK-NEXT: [[ARRAY:%.*]] = alloca [26 x i32], align 16
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ARRAY]], i8 0, i64 104, i1 false)
+; CHECK-NEXT: [[ARRAY_IDX:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i64 4
+; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 16 [[ARRAY]], ptr align 4 [[ARRAY_IDX]], i64 100, i1 false)
+; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[ARRAY]], align 16
+; CHECK-NEXT: ret i32 [[VAL]]
+;
+ %array = alloca [26 x i32], align 16
+ call void @llvm.memset.p0.i64(ptr align 16 %array, i8 0, i64 104, i1 false)
+ %array.idx = getelementptr inbounds i8, ptr %array, i64 4
+ call void @llvm.memmove.p0.p0.i64(ptr align 16 %array, ptr align 4 %array.idx, i64 100, i1 false)
+ %val = load i32, ptr %array, align 16
+ ret i32 %val
+}
+
+; Used memmove, buffer is reset to zero.
+define i32 @used_memmove_1() {
+; CHECK-LABEL: @used_memmove_1(
+; CHECK-NEXT: [[ARRAY:%.*]] = alloca [26 x i32], align 16
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ARRAY]], i8 0, i64 104, i1 false)
+; CHECK-NEXT: [[ARRAY_IDX:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i64 4
+; CHECK-NEXT: store i32 1, ptr [[ARRAY_IDX]], align 4
+; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 16 [[ARRAY]], ptr align 4 [[ARRAY_IDX]], i64 100, i1 false)
+; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[ARRAY_IDX]], align 4
+; CHECK-NEXT: ret i32 [[VAL]]
+;
+ %array = alloca [26 x i32], align 16
+ call void @llvm.memset.p0.i64(ptr align 16 %array, i8 0, i64 104, i1 false)
+ %array.idx = getelementptr inbounds i8, ptr %array, i64 4
+ store i32 1, ptr %array.idx
+ call void @llvm.memmove.p0.p0.i64(ptr align 16 %array, ptr align 4 %array.idx, i64 100, i1 false)
+ %val = load i32, ptr %array.idx, align 4
+ ret i32 %val
+}
+
+; Used memmove.
+define i32 @used_memmove_2() {
+; CHECK-LABEL: @used_memmove_2(
+; CHECK-NEXT: [[ARRAY:%.*]] = alloca [26 x i32], align 16
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ARRAY]], i8 0, i64 104, i1 false)
+; CHECK-NEXT: [[ARRAY_IDX:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i64 4
+; CHECK-NEXT: store i32 1, ptr [[ARRAY]], align 4
+; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 16 [[ARRAY]], ptr align 4 [[ARRAY_IDX]], i64 100, i1 false)
+; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[ARRAY_IDX]], align 4
+; CHECK-NEXT: ret i32 [[VAL]]
+;
+ %array = alloca [26 x i32], align 16
+ call void @llvm.memset.p0.i64(ptr align 16 %array, i8 0, i64 104, i1 false)
+ %array.idx = getelementptr inbounds i8, ptr %array, i64 4
+ store i32 1, ptr %array
+ call void @llvm.memmove.p0.p0.i64(ptr align 16 %array, ptr align 4 %array.idx, i64 100, i1 false)
+ %val = load i32, ptr %array.idx, align 4
+ ret i32 %val
+}
+
+; Used memmove, buffer clobbered by opaque.
+define i32 @used_memmove_3() {
+; CHECK-LABEL: @used_memmove_3(
+; CHECK-NEXT: [[ARRAY:%.*]] = alloca [25 x i32], align 16
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ARRAY]], i8 0, i64 100, i1 false)
+; CHECK-NEXT: call void @opaque(ptr [[ARRAY]])
+; CHECK-NEXT: [[ARRAY_IDX:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i64 4
+; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 16 [[ARRAY]], ptr align 4 [[ARRAY_IDX]], i64 96, i1 false)
+; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[ARRAY]], align 16
+; CHECK-NEXT: ret i32 [[VAL]]
+;
+ %array = alloca [25 x i32], align 16
+ call void @llvm.memset.p0.i64(ptr align 16 %array, i8 0, i64 100, i1 false)
+ call void @opaque(ptr %array)
+ %array.idx = getelementptr inbounds i8, ptr %array, i64 4
+ call void @llvm.memmove.p0.p0.i64(ptr align 16 %array, ptr align 4 %array.idx, i64 96, i1 false)
+ %val = load i32, ptr %array, align 16
+ ret i32 %val
+}
+
+; Redundant memmove, not within the same basic block.
+define i32 @redundant_memmove_
diff erent_bbs() {
+; CHECK-LABEL: @redundant_memmove_
diff erent_bbs(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ARRAY:%.*]] = alloca [26 x i32], align 16
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ARRAY]], i8 0, i64 104, i1 false)
+; CHECK-NEXT: [[ARRAY_IDX:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i64 4
+; CHECK-NEXT: br label [[USE:%.*]]
+; CHECK: use:
+; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 16 [[ARRAY]], ptr align 4 [[ARRAY_IDX]], i64 100, i1 false)
+; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[ARRAY]], align 16
+; CHECK-NEXT: ret i32 [[VAL]]
+;
+entry:
+ %array = alloca [26 x i32], align 16
+ call void @llvm.memset.p0.i64(ptr align 16 %array, i8 0, i64 104, i1 false)
+ %array.idx = getelementptr inbounds i8, ptr %array, i64 4
+ br label %use
+
+use: ; preds = %entry
+ call void @llvm.memmove.p0.p0.i64(ptr align 16 %array, ptr align 4 %array.idx, i64 100, i1 false)
+ %val = load i32, ptr %array, align 16
+ ret i32 %val
+}
+
+ at g_var = global [26 x i32] zeroinitializer, align 16
+
+; Redundant memmove on a global variable.
+define ptr @redundant_memmove_memset_global_variable() {
+; CHECK-LABEL: @redundant_memmove_memset_global_variable(
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 @g_var, i8 0, i64 104, i1 false)
+; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 16 @g_var, ptr align 4 getelementptr inbounds nuw (i8, ptr @g_var, i64 4), i64 100, i1 false)
+; CHECK-NEXT: ret ptr @g_var
+;
+ call void @llvm.memset.p0.i64(ptr align 16 @g_var, i8 0, i64 104, i1 false)
+ call void @llvm.memmove.p0.p0.i64(ptr align 16 @g_var, ptr align 4 getelementptr inbounds nuw (i8, ptr @g_var, i64 4), i64 100, i1 false)
+ ret ptr @g_var
+}
+
+; Memset only partial.
+define i32 @partial_memset() {
+; CHECK-LABEL: @partial_memset(
+; CHECK-NEXT: [[ARRAY:%.*]] = alloca [26 x i32], align 16
+; CHECK-NEXT: [[ARRAY_IDX:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i64 92
+; CHECK-NEXT: store i32 1, ptr [[ARRAY_IDX]], align 4
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ARRAY]], i8 0, i64 26, i1 false)
+; CHECK-NEXT: [[ARRAY_IDX_2:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i64 4
+; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 16 [[ARRAY]], ptr align 4 [[ARRAY_IDX_2]], i64 100, i1 false)
+; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[ARRAY_IDX]], align 4
+; CHECK-NEXT: ret i32 [[VAL]]
+;
+ %array = alloca [26 x i32], align 16
+ %array.idx = getelementptr inbounds i8, ptr %array, i64 92
+ store i32 1, ptr %array.idx
+ call void @llvm.memset.p0.i64(ptr align 16 %array, i8 0, i64 26, i1 false)
+ %array.idx.2 = getelementptr inbounds i8, ptr %array, i64 4
+ call void @llvm.memmove.p0.p0.i64(ptr align 16 %array, ptr align 4 %array.idx.2, i64 100, i1 false)
+ %val = load i32, ptr %array.idx, align 4
+ ret i32 %val
+}
+
+; Memset length not constant.
+define i32 @memset_length_not_constant(i64 %size) {
+; CHECK-LABEL: @memset_length_not_constant(
+; CHECK-NEXT: [[ARRAY:%.*]] = alloca [26 x i32], align 16
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ARRAY]], i8 0, i64 [[SIZE:%.*]], i1 false)
+; CHECK-NEXT: [[ARRAY_IDX:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i64 4
+; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 16 [[ARRAY]], ptr align 4 [[ARRAY_IDX]], i64 100, i1 false)
+; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[ARRAY]], align 16
+; CHECK-NEXT: ret i32 [[VAL]]
+;
+ %array = alloca [26 x i32], align 16
+ call void @llvm.memset.p0.i64(ptr align 16 %array, i8 0, i64 %size, i1 false)
+ %array.idx = getelementptr inbounds i8, ptr %array, i64 4
+ call void @llvm.memmove.p0.p0.i64(ptr align 16 %array, ptr align 4 %array.idx, i64 100, i1 false)
+ %val = load i32, ptr %array, align 16
+ ret i32 %val
+}
+
+; Memmove buffer not memset'd,
diff erent buffers.
+define i32 @memset_memmove_dest_buffers_not_alias() {
+; CHECK-LABEL: @memset_memmove_dest_buffers_not_alias(
+; CHECK-NEXT: [[ARRAY:%.*]] = alloca [26 x i32], align 16
+; CHECK-NEXT: [[ARRAY2:%.*]] = alloca [26 x i32], align 16
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ARRAY]], i8 0, i64 104, i1 false)
+; CHECK-NEXT: [[ARRAY2_IDX:%.*]] = getelementptr inbounds i8, ptr [[ARRAY2]], i64 4
+; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 16 [[ARRAY2]], ptr align 4 [[ARRAY2_IDX]], i64 100, i1 false)
+; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[ARRAY2]], align 16
+; CHECK-NEXT: ret i32 [[VAL]]
+;
+ %array = alloca [26 x i32], align 16
+ %array2 = alloca [26 x i32], align 16
+ call void @llvm.memset.p0.i64(ptr align 16 %array, i8 0, i64 104, i1 false)
+ %array2.idx = getelementptr inbounds i8, ptr %array2, i64 4
+ call void @llvm.memmove.p0.p0.i64(ptr align 16 %array2, ptr align 4 %array2.idx, i64 100, i1 false)
+ %val = load i32, ptr %array2, align 16
+ ret i32 %val
+}
+
+declare void @opaque(ptr)
+declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1)
+declare void @llvm.memmove.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1)
More information about the llvm-commits
mailing list