Files
clang-p2996/llvm/test/Transforms/MemCpyOpt/mixed-sizes.ll
Nikita Popov 624af932a8 [MemCpyOpt] Port to MemorySSA
This is a straightforward port of MemCpyOpt to MemorySSA following
the approach of D26739. MemDep queries are replaced with MSSA queries
without changing the overall structure of the pass. Some care has
to be taken to account for differences between these APIs
(MemDep also returns reads, MSSA doesn't).

Differential Revision: https://reviews.llvm.org/D89207
2020-12-01 17:57:41 +01:00

75 lines
3.8 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -memcpyopt -S -enable-memcpyopt-memoryssa=0 | FileCheck %s --check-prefix=NO_MSSA
; RUN: opt < %s -memcpyopt -S -enable-memcpyopt-memoryssa=1 -verify-memoryssa | FileCheck %s --check-prefix=MSSA
; Handle memcpy-memcpy dependencies of differing sizes correctly.
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
; Don't delete the second memcpy, even though there's an earlier
; memcpy with a larger size from the same address.
define i32 @foo(i1 %z) {
; NO_MSSA-LABEL: @foo(
; NO_MSSA-NEXT: entry:
; NO_MSSA-NEXT: [[A:%.*]] = alloca [10 x i32], align 4
; NO_MSSA-NEXT: [[S:%.*]] = alloca [10 x i32], align 4
; NO_MSSA-NEXT: [[TMP0:%.*]] = bitcast [10 x i32]* [[A]] to i8*
; NO_MSSA-NEXT: [[TMP1:%.*]] = bitcast [10 x i32]* [[S]] to i8*
; NO_MSSA-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 16 [[TMP1]], i8 0, i64 40, i1 false)
; NO_MSSA-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[A]], i64 0, i64 0
; NO_MSSA-NEXT: store i32 1, i32* [[ARRAYIDX]], align 4
; NO_MSSA-NEXT: [[SCEVGEP:%.*]] = getelementptr [10 x i32], [10 x i32]* [[S]], i64 0, i64 1
; NO_MSSA-NEXT: [[SCEVGEP7:%.*]] = bitcast i32* [[SCEVGEP]] to i8*
; NO_MSSA-NEXT: br i1 [[Z:%.*]], label [[FOR_BODY3_LR_PH:%.*]], label [[FOR_INC7_1:%.*]]
; NO_MSSA: for.body3.lr.ph:
; NO_MSSA-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP0]], i8* align 4 [[SCEVGEP7]], i64 17179869180, i1 false)
; NO_MSSA-NEXT: br label [[FOR_INC7_1]]
; NO_MSSA: for.inc7.1:
; NO_MSSA-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP0]], i8* align 4 [[SCEVGEP7]], i64 4, i1 false)
; NO_MSSA-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
; NO_MSSA-NEXT: ret i32 [[TMP2]]
;
; MSSA-LABEL: @foo(
; MSSA-NEXT: entry:
; MSSA-NEXT: [[A:%.*]] = alloca [10 x i32], align 4
; MSSA-NEXT: [[S:%.*]] = alloca [10 x i32], align 4
; MSSA-NEXT: [[TMP0:%.*]] = bitcast [10 x i32]* [[A]] to i8*
; MSSA-NEXT: [[TMP1:%.*]] = bitcast [10 x i32]* [[S]] to i8*
; MSSA-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 16 [[TMP1]], i8 0, i64 40, i1 false)
; MSSA-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[A]], i64 0, i64 0
; MSSA-NEXT: store i32 1, i32* [[ARRAYIDX]], align 4
; MSSA-NEXT: [[SCEVGEP:%.*]] = getelementptr [10 x i32], [10 x i32]* [[S]], i64 0, i64 1
; MSSA-NEXT: [[SCEVGEP7:%.*]] = bitcast i32* [[SCEVGEP]] to i8*
; MSSA-NEXT: br i1 [[Z:%.*]], label [[FOR_BODY3_LR_PH:%.*]], label [[FOR_INC7_1:%.*]]
; MSSA: for.body3.lr.ph:
; MSSA-NEXT: br label [[FOR_INC7_1]]
; MSSA: for.inc7.1:
; MSSA-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP0]], i8* align 4 [[SCEVGEP7]], i64 4, i1 false)
; MSSA-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
; MSSA-NEXT: ret i32 [[TMP2]]
;
entry:
%a = alloca [10 x i32]
%s = alloca [10 x i32]
%0 = bitcast [10 x i32]* %a to i8*
%1 = bitcast [10 x i32]* %s to i8*
call void @llvm.memset.p0i8.i64(i8* nonnull align 16 %1, i8 0, i64 40, i1 false)
%arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %a, i64 0, i64 0
store i32 1, i32* %arrayidx
%scevgep = getelementptr [10 x i32], [10 x i32]* %s, i64 0, i64 1
%scevgep7 = bitcast i32* %scevgep to i8*
br i1 %z, label %for.body3.lr.ph, label %for.inc7.1
for.body3.lr.ph: ; preds = %entry
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 %scevgep7, i64 17179869180, i1 false)
br label %for.inc7.1
for.inc7.1:
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 %scevgep7, i64 4, i1 false)
%2 = load i32, i32* %arrayidx
ret i32 %2
}
declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1)
declare void @llvm.memset.p0i8.i64(i8*, i8, i64, i1)