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
58 lines
2.6 KiB
LLVM
58 lines
2.6 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
|
|
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
; Don't delete the memcpy in %if.then, even though it depends on an instruction
|
|
; which will be deleted.
|
|
|
|
define void @foo(i1 %c, i8* %d, i8* %e, i8* %f) {
|
|
; NO_MSSA-LABEL: @foo(
|
|
; NO_MSSA-NEXT: entry:
|
|
; NO_MSSA-NEXT: [[TMP:%.*]] = alloca [50 x i8], align 8
|
|
; NO_MSSA-NEXT: [[TMP4:%.*]] = bitcast [50 x i8]* [[TMP]] to i8*
|
|
; NO_MSSA-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[TMP4]], i64 1
|
|
; NO_MSSA-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull [[D:%.*]], i8 0, i64 10, i1 false)
|
|
; NO_MSSA-NEXT: call void @llvm.memset.p0i8.i64(i8* align 8 [[TMP4]], i8 0, i64 11, i1 false)
|
|
; NO_MSSA-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[EXIT:%.*]]
|
|
; NO_MSSA: if.then:
|
|
; NO_MSSA-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[F:%.*]], i8* nonnull align 8 [[TMP4]], i64 30, i1 false)
|
|
; NO_MSSA-NEXT: br label [[EXIT]]
|
|
; NO_MSSA: exit:
|
|
; NO_MSSA-NEXT: ret void
|
|
;
|
|
; MSSA-LABEL: @foo(
|
|
; MSSA-NEXT: entry:
|
|
; MSSA-NEXT: [[TMP:%.*]] = alloca [50 x i8], align 8
|
|
; MSSA-NEXT: [[TMP4:%.*]] = bitcast [50 x i8]* [[TMP]] to i8*
|
|
; MSSA-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[TMP4]], i64 1
|
|
; MSSA-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull [[D:%.*]], i8 0, i64 10, i1 false)
|
|
; MSSA-NEXT: call void @llvm.memset.p0i8.i64(i8* align 8 [[TMP4]], i8 0, i64 11, i1 false)
|
|
; MSSA-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[EXIT:%.*]]
|
|
; MSSA: if.then:
|
|
; MSSA-NEXT: call void @llvm.memset.p0i8.i64(i8* align 8 [[F:%.*]], i8 0, i64 11, i1 false)
|
|
; MSSA-NEXT: br label [[EXIT]]
|
|
; MSSA: exit:
|
|
; MSSA-NEXT: ret void
|
|
;
|
|
entry:
|
|
%tmp = alloca [50 x i8], align 8
|
|
%tmp4 = bitcast [50 x i8]* %tmp to i8*
|
|
%tmp1 = getelementptr inbounds i8, i8* %tmp4, i64 1
|
|
call void @llvm.memset.p0i8.i64(i8* nonnull %d, i8 0, i64 10, i1 false)
|
|
store i8 0, i8* %tmp4, align 8
|
|
call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull %tmp1, i8* nonnull %d, i64 10, i1 false)
|
|
br i1 %c, label %if.then, label %exit
|
|
|
|
if.then:
|
|
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %f, i8* nonnull align 8 %tmp4, i64 30, i1 false)
|
|
br label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1)
|
|
declare void @llvm.memset.p0i8.i64(i8*, i8, i64, i1)
|