diff --git a/llvm/test/Transforms/LoopIdiom/loop-strided-store-cleanup.ll b/llvm/test/Transforms/LoopIdiom/loop-strided-store-cleanup.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/LoopIdiom/loop-strided-store-cleanup.ll @@ -0,0 +1,65 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -S -loop-idiom -debug-pass=Details 2>&1 | FileCheck %s + +;; Check that processLoopStridedStore cleans up after itself, but still reports +;; that it modified the IR (even though the textual IR remains the same). + +; CHECK: Executing Pass 'Recognize loop idioms' on Loop 'bb1'... +; CHECK: Made Modification 'Recognize loop idioms' on Loop 'bb1'... +; CHECK: Freeing Pass 'Recognize loop idioms' on Loop 'bb1'... + +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.9.0" + +%struct.foo = type { %struct.pluto } +%struct.pluto = type { %struct.wombat } +%struct.wombat = type { %struct.barney } +%struct.barney = type { %struct.widget } +%struct.widget = type { %struct.hoge } +%struct.hoge = type { i64, i64, i8* } + +; Function Attrs: argmemonly nounwind willreturn writeonly +declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #0 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #1 + +define void @pluto() local_unnamed_addr #2 align 2 { +; CHECK-LABEL: @pluto( +; CHECK-NEXT: bb: +; CHECK-NEXT: br label [[BB1:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[ROCK:%.*]] = phi %struct.foo* [ [[ROCK2:%.*]], [[BB1]] ], [ null, [[BB:%.*]] ] +; CHECK-NEXT: [[ROCK2]] = getelementptr inbounds [[STRUCT_FOO:%.*]], %struct.foo* [[ROCK]], i64 -1 +; CHECK-NEXT: [[ROCK3:%.*]] = bitcast %struct.foo* [[ROCK2]] to i8* +; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 8 dereferenceable(24) undef, i8* nonnull align 8 dereferenceable(24) [[ROCK3]], i64 24, i1 false) #3 +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(24) [[ROCK3]], i8 0, i64 24, i1 false) #3 +; CHECK-NEXT: [[ROCK4:%.*]] = icmp eq %struct.foo* [[ROCK2]], undef +; CHECK-NEXT: br i1 [[ROCK4]], label [[BB5:%.*]], label [[BB1]] +; CHECK: bb5: +; CHECK-NEXT: unreachable +; +bb: + br label %bb1 + +bb1: ; preds = %bb1, %bb + %rock = phi %struct.foo* [ %rock2, %bb1 ], [ null, %bb ] + %rock2 = getelementptr inbounds %struct.foo, %struct.foo* %rock, i64 -1 + %rock3 = bitcast %struct.foo* %rock2 to i8* + tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 8 dereferenceable(24) undef, i8* nonnull align 8 dereferenceable(24) %rock3, i64 24, i1 false) #3 + tail call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(24) %rock3, i8 0, i64 24, i1 false) #3 + %rock4 = icmp eq %struct.foo* %rock2, undef + br i1 %rock4, label %bb5, label %bb1 + +bb5: ; preds = %bb1 + unreachable +} + +attributes #0 = { argmemonly nounwind willreturn writeonly } +attributes #1 = { argmemonly nounwind willreturn } +attributes #2 = { "use-soft-float"="false" } +attributes #3 = { nounwind } + +!llvm.ident = !{!0} + +!0 = !{!"clang version 12.0.0 (git@github.com:llvm/llvm-project.git 994fb86bc2a83b24340b803bde243341dee651fa)"}