; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes='bdce,sroa,bdce' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG ; RUN: opt < %s -passes='bdce,sroa,bdce' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG ; SROA fails to rewrite allocs but does rewrite some phis and delete ; dead instructions. Ensure that this invalidates analyses required ; for other passes. target datalayout = "e-m:e-i64:64-n32:64" target triple = "powerpc64le-grtev4-linux-gnu" %class.b = type { i64 } declare void @D(ptr sret(%class.b), ptr dereferenceable(32)) local_unnamed_addr ; Function Attrs: nounwind define void @H(ptr noalias nocapture readnone, [2 x i64], ptr %ptr, i32 signext %v, i64 %l, i64 %idx, ptr nonnull dereferenceable(32) %ptr2) { ; CHECK-LABEL: @H( ; CHECK-NEXT: [[TMP3:%.*]] = alloca [[CLASS_B:%.*]], align 8 ; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [2 x i64] [[TMP1:%.*]], 1 ; CHECK-NEXT: switch i64 [[TMP4]], label [[TMP6:%.*]] [ ; CHECK-NEXT: i64 4, label [[FOO:%.*]] ; CHECK-NEXT: i64 5, label [[TMP5:%.*]] ; CHECK-NEXT: ] ; CHECK: 5: ; CHECK-NEXT: br label [[TMP12:%.*]] ; CHECK: 6: ; CHECK-NEXT: [[TMP7:%.*]] = icmp ugt i64 [[TMP4]], 5 ; CHECK-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP12]] ; CHECK: 8: ; CHECK-NEXT: [[TMP9:%.*]] = load i8, ptr inttoptr (i64 4 to ptr), align 4 ; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i8 [[TMP9]], 47 ; CHECK-NEXT: [[TMP11:%.*]] = select i1 [[TMP10]], i64 5, i64 4 ; CHECK-NEXT: br label [[TMP12]] ; CHECK: 12: ; CHECK-NEXT: [[TMP13:%.*]] = phi i64 [ 4, [[TMP5]] ], [ [[TMP11]], [[TMP8]] ], [ 4, [[TMP6]] ] ; CHECK-NEXT: [[TMP14:%.*]] = icmp ne i64 [[TMP4]], 0 ; CHECK-NEXT: [[TMP15:%.*]] = icmp ugt i64 [[TMP4]], [[TMP13]] ; CHECK-NEXT: [[TMP16:%.*]] = and i1 [[TMP14]], [[TMP15]] ; CHECK-NEXT: br i1 [[TMP16]], label [[TMP17:%.*]], label [[A_EXIT:%.*]] ; CHECK: 17: ; CHECK-NEXT: [[TMP18:%.*]] = tail call ptr @memchr(ptr [[PTR:%.*]], i32 signext [[V:%.*]], i64 [[L:%.*]]) ; CHECK-NEXT: [[TMP19:%.*]] = icmp eq ptr [[TMP18]], null ; CHECK-NEXT: [[TMP20:%.*]] = sext i1 [[TMP19]] to i64 ; CHECK-NEXT: br label [[A_EXIT]] ; CHECK: a.exit: ; CHECK-NEXT: [[TMP21:%.*]] = phi i64 [ -1, [[TMP12]] ], [ [[TMP20]], [[TMP17]] ] ; CHECK-NEXT: [[TMP22:%.*]] = inttoptr i64 0 to ptr ; CHECK-NEXT: [[TMP23:%.*]] = sub nsw i64 [[TMP21]], [[TMP13]] ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[TMP3]]) ; CHECK-NEXT: [[TMP24:%.*]] = icmp ult i64 [[TMP23]], 2 ; CHECK-NEXT: br i1 [[TMP24]], label [[G_EXIT:%.*]], label [[TMP25:%.*]] ; CHECK: 25: ; CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds i8, ptr [[TMP22]], i64 [[IDX:%.*]] ; CHECK-NEXT: [[TMP27:%.*]] = icmp eq ptr [[TMP26]], null ; CHECK-NEXT: br i1 [[TMP27]], label [[TMP28:%.*]], label [[TMP29:%.*]] ; CHECK: 28: ; CHECK-NEXT: unreachable ; CHECK: 29: ; CHECK-NEXT: call void @D(ptr nonnull sret([[CLASS_B]]) [[TMP3]], ptr nonnull dereferenceable(32) [[PTR2:%.*]]) ; CHECK-NEXT: br label [[G_EXIT]] ; CHECK: G.exit: ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[TMP3]]) ; CHECK-NEXT: br label [[FOO]] ; CHECK: foo: ; CHECK-NEXT: ret void ; %3 = alloca %class.b, align 8 %.sroa.0 = alloca i64, align 8 store i64 0, ptr %.sroa.0, align 8 %4 = extractvalue [2 x i64] %1, 1 switch i64 %4, label %6 [ i64 4, label %foo i64 5, label %5 ] ;