1; RUN: opt -passes='loop-mssa(licm),print<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s 2; REQUIRES: asserts 3 4@arr = global [12 x i8] [i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 9, i8 10, i8 11, i8 12], align 1 5 6; CHECK-LABEL: @func() 7define void @func() { 8entry: 9 %res.addr.i = alloca i8, align 1 10 %sum = alloca i8, align 1 11 %n = alloca i8, align 1 12 %i = alloca i8, align 1 13 %cleanup.dest.slot = alloca i32, align 1 14 call void @llvm.lifetime.start.p0(i64 1, ptr %sum) #3 15 store i8 0, ptr %sum, align 1 16 call void @llvm.lifetime.start.p0(i64 1, ptr %n) #3 17 %call = call i8 @idi(i8 10) 18 store i8 %call, ptr %n, align 1 19 call void @llvm.lifetime.start.p0(i64 1, ptr %i) #3 20 store i8 0, ptr %i, align 1 21 br label %for.cond 22 23for.cond: ; preds = %for.inc, %entry 24 %0 = load i8, ptr %i, align 1 25 %1 = load i8, ptr %n, align 1 26 %cmp = icmp slt i8 %0, %1 27 br i1 %cmp, label %for.body, label %for.cond.cleanup 28 29for.cond.cleanup: ; preds = %for.cond 30 store i32 2, ptr %cleanup.dest.slot, align 1 31 br label %final.cleanup 32 33for.body: ; preds = %for.cond 34 %2 = load i8, ptr %i, align 1 35 %idxprom = sext i8 %2 to i32 36 %arrayidx = getelementptr inbounds [12 x i8], ptr @arr, i32 0, i32 %idxprom 37 %3 = load i8, ptr %arrayidx, align 1 38 %cmp1 = icmp eq i8 %3, 3 39 br i1 %cmp1, label %if.then, label %if.end 40 41if.then: ; preds = %for.body 42 store i32 2, ptr %cleanup.dest.slot, align 1 43 br label %final.cleanup 44 45if.end: ; preds = %for.body 46 %4 = load i8, ptr %i, align 1 47 %idxprom2 = sext i8 %4 to i32 48 %arrayidx3 = getelementptr inbounds [12 x i8], ptr @arr, i32 0, i32 %idxprom2 49 %5 = load i8, ptr %arrayidx3, align 1 50 %6 = load i8, ptr %sum, align 1 51 %add = add nsw i8 %6, %5 52 store i8 %add, ptr %sum, align 1 53 br label %for.inc 54 55for.inc: ; preds = %if.end 56 %7 = load i8, ptr %i, align 1 57 %inc = add nsw i8 %7, 1 58 store i8 %inc, ptr %i, align 1 59 br label %for.cond 60 61; CHECK: final.cleanup: 62; CHECK-NEXT: ; [[NO20:.*]] = MemoryPhi({if.then,[[NO9:.*]]},{for.cond.cleanup,[[NO8:.*]]}) 63; CHECK-NEXT: ; [[NO12:.*]] = MemoryDef([[NO20]]) 64; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 1, ptr %i) 65final.cleanup: ; preds = %if.then, %for.cond.cleanup 66 call void @llvm.lifetime.end.p0(i64 1, ptr %i) #3 67 br label %for.end 68 69; CHECK: for.end: 70; CHECK-NEXT: ; MemoryUse([[NO20]]) 71; CHECK-NEXT: %3 = load i8, ptr %sum, align 1 72for.end: ; preds = %final.cleanup 73 %8 = load i8, ptr %sum, align 1 74 call void @llvm.lifetime.start.p0(i64 1, ptr %res.addr.i) 75 store i8 %8, ptr %res.addr.i, align 1 76 %9 = load i8, ptr %res.addr.i, align 1 77 call void @foo(i8 %9) #3 78 call void @llvm.lifetime.end.p0(i64 1, ptr %res.addr.i) 79 call void @llvm.lifetime.end.p0(i64 1, ptr %n) #3 80 call void @llvm.lifetime.end.p0(i64 1, ptr %sum) #3 81 ret void 82} 83 84; Function Attrs: argmemonly nofree nosync nounwind willreturn 85declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1 86 87declare i8 @idi(i8) 88 89; Function Attrs: argmemonly nofree nosync nounwind willreturn 90declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1 91 92; Function Attrs: nounwind 93declare void @foo(i8) 94 95attributes #1 = { argmemonly nofree nosync nounwind willreturn } 96attributes #3 = { nounwind } 97