blob: 979aa69d46363d8413b57f0d2b07fa939e290335 [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=newgvn < %s | FileCheck %s
; MemorySSA says that load1 depends on the lifetime start.
; That's OK since MemorySSA is may-alias; however, NewGVN should
; check whether the lifetime start *actually* defines the loaded pointer
; before simplifying to uninitialized memory.
define void @foo(ptr %arg) {
; CHECK-LABEL: define void @foo(
; CHECK-SAME: ptr [[ARG:%.*]]) {
; CHECK-NEXT: [[BB:.*:]]
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca i8, align 16
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[ALLOCA]])
; CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr [[ARG]], align 8
; CHECK-NEXT: [[LOAD1:%.*]] = load ptr, ptr [[LOAD]], align 8
; CHECK-NEXT: [[CALL:%.*]] = call ptr [[LOAD1]](ptr [[ALLOCA]])
; CHECK-NEXT: ret void
;
bb:
%alloca = alloca i8, align 16
call void @llvm.lifetime.start.p0(ptr %alloca)
%load = load ptr, ptr %arg, align 8
%load1 = load ptr, ptr %load, align 8
%call = call ptr %load1(ptr %alloca)
ret void
}
declare void @llvm.lifetime.start.p0(ptr captures(none)) #0
declare ptr @malloc(i64)
; This case is handled correctly.
; Since malloc returns a pointer, NewGVN checks whether
; it is the same pointer, an equivalent one, or a must-alias.
define void @wombat(ptr %arg) {
; CHECK-LABEL: define void @wombat(
; CHECK-SAME: ptr [[ARG:%.*]]) {
; CHECK-NEXT: [[BB:.*:]]
; CHECK-NEXT: [[CALL:%.*]] = call ptr @malloc(i64 1)
; CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr [[ARG]], align 8
; CHECK-NEXT: [[LOAD1:%.*]] = load ptr, ptr [[LOAD]], align 8
; CHECK-NEXT: [[CALL2:%.*]] = call ptr [[LOAD1]](ptr [[CALL]])
; CHECK-NEXT: ret void
;
bb:
%call = call ptr @malloc(i64 1)
%load = load ptr, ptr %arg, align 8
%load1 = load ptr, ptr %load, align 8
%call2 = call ptr %load1(ptr %call)
ret void
}
attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }