blob: 2042590b159a4f65777644971f5e3c5b5504a4b6 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes='logical-sroa' -S | FileCheck %s --check-prefixes=CHECK
declare void @llvm.lifetime.start.p0(ptr nocapture)
declare void @llvm.lifetime.end.p0(ptr nocapture)
declare ptr @llvm.structured.alloca.p0()
declare ptr @llvm.structured.gep.p0(ptr, ...)
define i32 @test_simple_scalar() {
; CHECK-LABEL: define i32 @test_simple_scalar() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[TMP:%.*]] = call elementtype(i32) ptr @llvm.structured.alloca.p0()
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[TMP]])
; CHECK-NEXT: store i32 0, ptr [[TMP]], align 4
; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[TMP]], align 4
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[TMP]])
; CHECK-NEXT: ret i32 [[RES]]
;
entry:
%tmp = call elementtype(i32) ptr @llvm.structured.alloca.p0()
call void @llvm.lifetime.start.p0(ptr %tmp)
store i32 0, ptr %tmp
%res = load i32, ptr %tmp
call void @llvm.lifetime.end.p0(ptr %tmp)
ret i32 %res
}
define i32 @test_simple_struct_entire_write_read() {
; CHECK-LABEL: define i32 @test_simple_struct_entire_write_read() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[TMP0:%.*]] = call elementtype(i32) ptr @llvm.structured.alloca.p0()
; CHECK-NEXT: [[TMP1:%.*]] = call elementtype(i32) ptr @llvm.structured.alloca.p0()
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[TMP0]])
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[TMP1]])
; CHECK-NEXT: store i32 0, ptr [[TMP0]], align 4
; CHECK-NEXT: store i32 1, ptr [[TMP1]], align 4
; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[TMP0]], align 4
; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[TMP1]], align 4
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[TMP0]])
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[TMP1]])
; CHECK-NEXT: [[RES:%.*]] = add i32 [[A]], [[B]]
; CHECK-NEXT: ret i32 [[RES]]
;
entry:
%tmp = call elementtype({ i32, i32 }) ptr @llvm.structured.alloca.p0()
%ptr0 = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype({ i32, i32 }) %tmp, i32 0)
%ptr1 = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype({ i32, i32 }) %tmp, i32 1)
call void @llvm.lifetime.start.p0(ptr %tmp)
store i32 0, ptr %ptr0
store i32 1, ptr %ptr1
%a = load i32, ptr %ptr0
%b = load i32, ptr %ptr1
call void @llvm.lifetime.end.p0(ptr %tmp)
%res = add i32 %a, %b
ret i32 %res
}
define i32 @test_simple_struct_aliasing() {
; CHECK-LABEL: define i32 @test_simple_struct_aliasing() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[TMP0:%.*]] = call elementtype(i32) ptr @llvm.structured.alloca.p0()
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[TMP0]])
; CHECK-NEXT: store i32 0, ptr [[TMP0]], align 4
; CHECK-NEXT: store i32 1, ptr [[TMP0]], align 4
; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[TMP0]], align 4
; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[TMP0]], align 4
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[TMP0]])
; CHECK-NEXT: [[RES:%.*]] = add i32 [[A]], [[B]]
; CHECK-NEXT: ret i32 [[RES]]
;
entry:
%tmp = call elementtype({ i32, i32 }) ptr @llvm.structured.alloca.p0()
%ptr0 = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype({ i32, i32 }) %tmp, i32 0)
%ptr1 = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype({ i32, i32 }) %tmp, i32 0)
call void @llvm.lifetime.start.p0(ptr %tmp)
store i32 0, ptr %ptr0
store i32 1, ptr %ptr1
%a = load i32, ptr %ptr0
%b = load i32, ptr %ptr1
call void @llvm.lifetime.end.p0(ptr %tmp)
%res = add i32 %a, %b
ret i32 %res
}
define i32 @test_simple_struct_partial_write_read() {
; CHECK-LABEL: define i32 @test_simple_struct_partial_write_read() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[TMP0:%.*]] = call elementtype(i32) ptr @llvm.structured.alloca.p0()
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[TMP0]])
; CHECK-NEXT: store i32 0, ptr [[TMP0]], align 4
; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[TMP0]], align 4
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[TMP0]])
; CHECK-NEXT: ret i32 [[A]]
;
entry:
%tmp = call elementtype({ i32, i32 }) ptr @llvm.structured.alloca.p0()
call void @llvm.lifetime.start.p0(ptr %tmp)
%ptr0 = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype({ i32, i32 }) %tmp, i32 0)
store i32 0, ptr %ptr0
%a = load i32, ptr %ptr0
call void @llvm.lifetime.end.p0(ptr %tmp)
ret i32 %a
}
define i32 @test_struct_use_across_lifetime() {
; CHECK-LABEL: define i32 @test_struct_use_across_lifetime() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[TMP0:%.*]] = call elementtype(i32) ptr @llvm.structured.alloca.p0()
; CHECK-NEXT: [[TMP1:%.*]] = call elementtype(i32) ptr @llvm.structured.alloca.p0()
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[TMP0]])
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[TMP1]])
; CHECK-NEXT: store i32 0, ptr [[TMP0]], align 4
; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[TMP0]], align 4
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[TMP0]])
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[TMP1]])
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[TMP0]])
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[TMP1]])
; CHECK-NEXT: store i32 0, ptr [[TMP1]], align 4
; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[TMP1]], align 4
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[TMP0]])
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[TMP1]])
; CHECK-NEXT: [[C:%.*]] = add i32 [[B]], [[A]]
; CHECK-NEXT: ret i32 [[C]]
;
entry:
%tmp = call elementtype({ i32, i32 }) ptr @llvm.structured.alloca.p0()
%ptr0 = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype({ i32, i32 }) %tmp, i32 0)
%ptr1 = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype({ i32, i32 }) %tmp, i32 1)
call void @llvm.lifetime.start.p0(ptr %tmp)
store i32 0, ptr %ptr0
%a = load i32, ptr %ptr0
call void @llvm.lifetime.end.p0(ptr %tmp)
call void @llvm.lifetime.start.p0(ptr %tmp)
store i32 0, ptr %ptr1
%b = load i32, ptr %ptr1
call void @llvm.lifetime.end.p0(ptr %tmp)
%c = add i32 %b, %a
ret i32 %c
}