From babb59496b540583c6951813d1e0b3abdea97e7d Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 14 Aug 2020 16:46:37 -0400 Subject: [PATCH] [PhaseOrdering] add test for memcpy removal (PR47114); NFC --- llvm/test/Transforms/PhaseOrdering/memcpyopt.ll | 134 ++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 llvm/test/Transforms/PhaseOrdering/memcpyopt.ll diff --git a/llvm/test/Transforms/PhaseOrdering/memcpyopt.ll b/llvm/test/Transforms/PhaseOrdering/memcpyopt.ll new file mode 100644 index 0000000..39b4f3b --- /dev/null +++ b/llvm/test/Transforms/PhaseOrdering/memcpyopt.ll @@ -0,0 +1,134 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -O2 -S < %s | FileCheck %s --check-prefixes=ANY,OLDPM +; RUN: opt -passes='default' -aa-pipeline=default -S < %s | FileCheck %s --check-prefixes=ANY,NEWPM + +; There should not be any remaining 'memcpy' calls in this code. +; http://bugs.llvm.org/PR47114 + +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + +%struct.Arr = type { [2 x %struct.String] } +%struct.String = type { i64, i64, i8* } +%struct.PartialArr = type { %struct.Arr } + +define void @c(%struct.Arr* noalias sret align 8 %agg.result) #0 { +; OLDPM-LABEL: @c( +; OLDPM-NEXT: entry: +; OLDPM-NEXT: [[DATA:%.*]] = alloca [[STRUCT_PARTIALARR:%.*]], align 8 +; OLDPM-NEXT: [[TMP0:%.*]] = bitcast %struct.PartialArr* [[DATA]] to i8* +; OLDPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 48, i8* nonnull [[TMP0]]) [[ATTR3:#.*]] +; OLDPM-NEXT: [[TMP1:%.*]] = bitcast %struct.PartialArr* [[DATA]] to i8* +; OLDPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(24) [[TMP1]], i8 0, i64 24, i1 false) +; OLDPM-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds [[STRUCT_PARTIALARR]], %struct.PartialArr* [[DATA]], i64 0, i32 0, i32 0, i64 1 +; OLDPM-NEXT: [[TMP2:%.*]] = bitcast %struct.String* [[ARRAYIDX_1]] to i8* +; OLDPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(24) [[TMP2]], i8 0, i64 24, i1 false) +; OLDPM-NEXT: [[TMP3:%.*]] = bitcast %struct.Arr* [[AGG_RESULT:%.*]] to i8* +; OLDPM-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 8 dereferenceable(48) [[TMP3]], i8* nonnull align 8 dereferenceable(48) [[TMP0]], i64 48, i1 false), !tbaa.struct !3 +; OLDPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 48, i8* nonnull [[TMP0]]) [[ATTR3]] +; OLDPM-NEXT: ret void +; +; NEWPM-LABEL: @c( +; NEWPM-NEXT: entry: +; NEWPM-NEXT: [[DATA_SROA_0:%.*]] = alloca [2 x %struct.String], align 8 +; NEWPM-NEXT: [[DATA_SROA_0_0__SROA_CAST19:%.*]] = bitcast [2 x %struct.String]* [[DATA_SROA_0]] to i8* +; NEWPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 48, i8* nonnull [[DATA_SROA_0_0__SROA_CAST19]]) +; NEWPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(24) [[DATA_SROA_0_0__SROA_CAST19]], i8 0, i64 24, i1 false) +; NEWPM-NEXT: [[DATA_SROA_0_24__SROA_IDX:%.*]] = getelementptr inbounds [2 x %struct.String], [2 x %struct.String]* [[DATA_SROA_0]], i64 0, i64 1 +; NEWPM-NEXT: [[DATA_SROA_0_24__SROA_CAST18:%.*]] = bitcast %struct.String* [[DATA_SROA_0_24__SROA_IDX]] to i8* +; NEWPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(24) [[DATA_SROA_0_24__SROA_CAST18]], i8 0, i64 24, i1 false) +; NEWPM-NEXT: [[DATA_SROA_0_0__SROA_CAST14:%.*]] = bitcast %struct.Arr* [[AGG_RESULT:%.*]] to i8* +; NEWPM-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 8 dereferenceable(48) [[DATA_SROA_0_0__SROA_CAST14]], i8* nonnull align 8 dereferenceable(48) [[DATA_SROA_0_0__SROA_CAST19]], i64 48, i1 false), !tbaa.struct !3 +; NEWPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 48, i8* nonnull [[DATA_SROA_0_0__SROA_CAST19]]) +; NEWPM-NEXT: ret void +; +entry: + %data = alloca %struct.PartialArr, align 8 + %slots = alloca [2 x %struct.String]*, align 8 + %i = alloca i64, align 8 + %tmp = alloca %struct.String, align 8 + %0 = bitcast %struct.PartialArr* %data to i8* + call void @llvm.lifetime.start.p0i8(i64 48, i8* %0) #3 + %1 = bitcast [2 x %struct.String]** %slots to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* %1) #3 + %value = getelementptr inbounds %struct.PartialArr, %struct.PartialArr* %data, i32 0, i32 0 + %data1 = getelementptr inbounds %struct.Arr, %struct.Arr* %value, i32 0, i32 0 + store [2 x %struct.String]* %data1, [2 x %struct.String]** %slots, align 8, !tbaa !3 + %2 = bitcast i64* %i to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* %2) #3 + store i64 0, i64* %i, align 8, !tbaa !7 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %3 = load i64, i64* %i, align 8, !tbaa !7 + %cmp = icmp ult i64 %3, 2 + br i1 %cmp, label %for.body, label %for.cond.cleanup + +for.cond.cleanup: ; preds = %for.cond + %4 = bitcast i64* %i to i8* + call void @llvm.lifetime.end.p0i8(i64 8, i8* %4) #3 + br label %for.end + +for.body: ; preds = %for.cond + %5 = load [2 x %struct.String]*, [2 x %struct.String]** %slots, align 8, !tbaa !3 + %6 = load i64, i64* %i, align 8, !tbaa !7 + %arrayidx = getelementptr inbounds [2 x %struct.String], [2 x %struct.String]* %5, i64 0, i64 %6 + %7 = bitcast %struct.String* %tmp to i8* + call void @llvm.lifetime.start.p0i8(i64 24, i8* %7) #3 + call void @new_string(%struct.String* sret align 8 %tmp) + %8 = bitcast %struct.String* %arrayidx to i8* + %9 = bitcast %struct.String* %tmp to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %8, i8* align 8 %9, i64 24, i1 false), !tbaa.struct !9 + %10 = bitcast %struct.String* %tmp to i8* + call void @llvm.lifetime.end.p0i8(i64 24, i8* %10) #3 + br label %for.inc + +for.inc: ; preds = %for.body + %11 = load i64, i64* %i, align 8, !tbaa !7 + %inc = add i64 %11, 1 + store i64 %inc, i64* %i, align 8, !tbaa !7 + br label %for.cond + +for.end: ; preds = %for.cond.cleanup + %value2 = getelementptr inbounds %struct.PartialArr, %struct.PartialArr* %data, i32 0, i32 0 + %12 = bitcast %struct.Arr* %agg.result to i8* + %13 = bitcast %struct.Arr* %value2 to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %12, i8* align 8 %13, i64 48, i1 false), !tbaa.struct !10 + %14 = bitcast [2 x %struct.String]** %slots to i8* + call void @llvm.lifetime.end.p0i8(i64 8, i8* %14) #3 + %15 = bitcast %struct.PartialArr* %data to i8* + call void @llvm.lifetime.end.p0i8(i64 48, i8* %15) #3 + ret void +} + +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #1 +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 +declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #2 + +define internal void @new_string(%struct.String* noalias sret align 8 %agg.result) #0 { +entry: + %0 = bitcast %struct.String* %agg.result to i8* + call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 24, i1 false) + ret void +} + +attributes #0 = { nounwind ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind willreturn } +attributes #2 = { argmemonly nounwind willreturn writeonly } +attributes #3 = { nounwind } + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git c0bdd0753b8a3baf0629e724dc16f77b68fd9c3e)"} +!3 = !{!4, !4, i64 0} +!4 = !{!"any pointer", !5, i64 0} +!5 = !{!"omnipotent char", !6, i64 0} +!6 = !{!"Simple C/C++ TBAA"} +!7 = !{!8, !8, i64 0} +!8 = !{!"long", !5, i64 0} +!9 = !{i64 0, i64 8, !7, i64 8, i64 8, !7, i64 16, i64 8, !3} +!10 = !{i64 0, i64 48, !11} +!11 = !{!5, !5, i64 0} -- 2.7.4