55 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -S -passes=newgvn < %s | FileCheck %s3 4 5; MemorySSA says that load1 depends on the lifetime start.6; That's OK since MemorySSA is may-alias; however, NewGVN should7; check whether the lifetime start *actually* defines the loaded pointer8; before simplifying to uninitialized memory.9define void @foo(ptr %arg) {10; CHECK-LABEL: define void @foo(11; CHECK-SAME: ptr [[ARG:%.*]]) {12; CHECK-NEXT: [[BB:.*:]]13; CHECK-NEXT: [[ALLOCA:%.*]] = alloca i8, align 1614; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[ALLOCA]])15; CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr [[ARG]], align 816; CHECK-NEXT: [[LOAD1:%.*]] = load ptr, ptr [[LOAD]], align 817; CHECK-NEXT: [[CALL:%.*]] = call ptr [[LOAD1]](ptr [[ALLOCA]])18; CHECK-NEXT: ret void19;20bb:21 %alloca = alloca i8, align 1622 call void @llvm.lifetime.start.p0(ptr %alloca)23 %load = load ptr, ptr %arg, align 824 %load1 = load ptr, ptr %load, align 825 %call = call ptr %load1(ptr %alloca)26 ret void27}28 29declare void @llvm.lifetime.start.p0(ptr captures(none)) #030 31declare ptr @malloc(i64)32 33; This case is handled correctly. 34; Since malloc returns a pointer, NewGVN checks whether35; it is the same pointer, an equivalent one, or a must-alias.36define void @wombat(ptr %arg) {37; CHECK-LABEL: define void @wombat(38; CHECK-SAME: ptr [[ARG:%.*]]) {39; CHECK-NEXT: [[BB:.*:]]40; CHECK-NEXT: [[CALL:%.*]] = call ptr @malloc(i64 1)41; CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr [[ARG]], align 842; CHECK-NEXT: [[LOAD1:%.*]] = load ptr, ptr [[LOAD]], align 843; CHECK-NEXT: [[CALL2:%.*]] = call ptr [[LOAD1]](ptr [[CALL]])44; CHECK-NEXT: ret void45;46bb:47 %call = call ptr @malloc(i64 1)48 %load = load ptr, ptr %arg, align 849 %load1 = load ptr, ptr %load, align 850 %call2 = call ptr %load1(ptr %call)51 ret void52}53 54attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }55