CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
181 lines
8.5 KiB
LLVM
181 lines
8.5 KiB
LLVM
; 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: [[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_different_bbs() {
|
|
; CHECK-LABEL: @redundant_memmove_different_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: [[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
|
|
}
|
|
|
|
@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: 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, different 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)
|