blob: df5104ccf5fa52ee7da853c7bcd8773cdb767121 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
; RUN: opt -S -sroa-skip-mem2reg -passes='sroa<preserve-cfg>' < %s | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
; RUN: opt -S -sroa-skip-mem2reg -passes='sroa<modify-cfg>' < %s | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
%pair = type { i32, i32 }
define void @store_to_phi(i1 %cond, i32 %value) {
; CHECK-LABEL: @store_to_phi(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
; CHECK-NEXT: br i1 [[COND:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
; CHECK: left:
; CHECK-NEXT: store i32 [[VALUE:%.*]], ptr [[A]], align 4
; CHECK-NEXT: br label [[MERGE:%.*]]
; CHECK: right:
; CHECK-NEXT: store i32 [[VALUE]], ptr [[B]], align 4
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: ret void
;
entry:
%a = alloca i32, align 4
%b = alloca i32, align 4
br i1 %cond, label %left, label %right
left:
br label %merge
right:
br label %merge
merge:
%ptr = phi ptr [ %a, %left ], [ %b, %right ]
store i32 %value, ptr %ptr, align 4
ret void
}
define void @store_to_phi_alloca_and_argument(i1 %cond, i32 %value, ptr %other) {
; CHECK-LABEL: @store_to_phi_alloca_and_argument(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
; CHECK-NEXT: br i1 [[COND:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
; CHECK: left:
; CHECK-NEXT: store i32 [[VALUE:%.*]], ptr [[A]], align 4
; CHECK-NEXT: br label [[MERGE:%.*]]
; CHECK: right:
; CHECK-NEXT: store i32 [[VALUE]], ptr [[OTHER:%.*]], align 4
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: ret void
;
entry:
%a = alloca i32, align 4
br i1 %cond, label %left, label %right
left:
br label %merge
right:
br label %merge
merge:
%ptr = phi ptr [ %a, %left ], [ %other, %right ]
store i32 %value, ptr %ptr, align 4
ret void
}
define void @store_to_phi_split_edge(i1 %cond, i1 %other_cond, i32 %value) {
; CHECK-PRESERVE-CFG-LABEL: @store_to_phi_split_edge(
; CHECK-PRESERVE-CFG-NEXT: entry:
; CHECK-PRESERVE-CFG-NEXT: [[A:%.*]] = alloca i32, align 4
; CHECK-PRESERVE-CFG-NEXT: [[B:%.*]] = alloca i32, align 4
; CHECK-PRESERVE-CFG-NEXT: br i1 [[COND:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
; CHECK-PRESERVE-CFG: left:
; CHECK-PRESERVE-CFG-NEXT: br label [[MERGE:%.*]]
; CHECK-PRESERVE-CFG: right:
; CHECK-PRESERVE-CFG-NEXT: br i1 [[OTHER_COND:%.*]], label [[MERGE]], label [[EXIT:%.*]]
; CHECK-PRESERVE-CFG: merge:
; CHECK-PRESERVE-CFG-NEXT: [[PTR:%.*]] = phi ptr [ [[A]], [[LEFT]] ], [ [[B]], [[RIGHT]] ]
; CHECK-PRESERVE-CFG-NEXT: store i32 [[VALUE:%.*]], ptr [[PTR]], align 4
; CHECK-PRESERVE-CFG-NEXT: br label [[EXIT]]
; CHECK-PRESERVE-CFG: exit:
; CHECK-PRESERVE-CFG-NEXT: ret void
;
; CHECK-MODIFY-CFG-LABEL: @store_to_phi_split_edge(
; CHECK-MODIFY-CFG-NEXT: entry:
; CHECK-MODIFY-CFG-NEXT: [[A:%.*]] = alloca i32, align 4
; CHECK-MODIFY-CFG-NEXT: [[B:%.*]] = alloca i32, align 4
; CHECK-MODIFY-CFG-NEXT: br i1 [[COND:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
; CHECK-MODIFY-CFG: left:
; CHECK-MODIFY-CFG-NEXT: store i32 [[VALUE:%.*]], ptr [[A]], align 4
; CHECK-MODIFY-CFG-NEXT: br label [[MERGE:%.*]]
; CHECK-MODIFY-CFG: right:
; CHECK-MODIFY-CFG-NEXT: br i1 [[OTHER_COND:%.*]], label [[MERGE_SROA_STORE:%.*]], label [[EXIT:%.*]]
; CHECK-MODIFY-CFG: merge.sroa.store:
; CHECK-MODIFY-CFG-NEXT: store i32 [[VALUE]], ptr [[B]], align 4
; CHECK-MODIFY-CFG-NEXT: br label [[MERGE]]
; CHECK-MODIFY-CFG: merge:
; CHECK-MODIFY-CFG-NEXT: br label [[EXIT]]
; CHECK-MODIFY-CFG: exit:
; CHECK-MODIFY-CFG-NEXT: ret void
;
entry:
%a = alloca i32, align 4
%b = alloca i32, align 4
br i1 %cond, label %left, label %right
left:
br label %merge
right:
br i1 %other_cond, label %merge, label %exit
merge:
%ptr = phi ptr [ %a, %left ], [ %b, %right ]
store i32 %value, ptr %ptr, align 4
br label %exit
exit:
ret void
}
define void @store_to_phi_value_phi(i1 %cond) {
; CHECK-LABEL: @store_to_phi_value_phi(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
; CHECK-NEXT: br i1 [[COND:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
; CHECK: left:
; CHECK-NEXT: br label [[MERGE:%.*]]
; CHECK: right:
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[A]], [[LEFT]] ], [ [[B]], [[RIGHT]] ]
; CHECK-NEXT: [[VALUE:%.*]] = phi i32 [ 1, [[LEFT]] ], [ 2, [[RIGHT]] ]
; CHECK-NEXT: store i32 [[VALUE]], ptr [[PTR]], align 4
; CHECK-NEXT: ret void
;
entry:
%a = alloca i32, align 4
%b = alloca i32, align 4
br i1 %cond, label %left, label %right
left:
br label %merge
right:
br label %merge
merge:
%ptr = phi ptr [ %a, %left ], [ %b, %right ]
%value = phi i32 [ 1, %left ], [ 2, %right ]
store i32 %value, ptr %ptr, align 4
ret void
}
define void @store_to_phi_of_geps(i1 %cond, i32 %value) {
; CHECK-LABEL: @store_to_phi_of_geps(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[B_SROA_0:%.*]] = alloca i32, align 4
; CHECK-NEXT: br i1 [[COND:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
; CHECK: left:
; CHECK-NEXT: store i32 [[VALUE:%.*]], ptr [[A_SROA_0]], align 4
; CHECK-NEXT: br label [[MERGE:%.*]]
; CHECK: right:
; CHECK-NEXT: store i32 [[VALUE]], ptr [[B_SROA_0]], align 4
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: ret void
;
entry:
%a = alloca %pair, align 4
%b = alloca %pair, align 4
br i1 %cond, label %left, label %right
left:
br label %merge
right:
br label %merge
merge:
%ptr = phi ptr [ %a, %left ], [ %b, %right ]
%field = getelementptr inbounds %pair, ptr %ptr, i32 0, i32 1
store i32 %value, ptr %field, align 4
ret void
}
define void @store_atomic_to_phi(i1 %cond, i32 %value, ptr %other) {
; CHECK-LABEL: @store_atomic_to_phi(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
; CHECK-NEXT: br i1 [[COND:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
; CHECK: left:
; CHECK-NEXT: store i32 [[VALUE:%.*]], ptr [[A]], align 4
; CHECK-NEXT: br label [[MERGE:%.*]]
; CHECK: right:
; CHECK-NEXT: store atomic i32 [[VALUE]], ptr [[OTHER:%.*]] seq_cst, align 4
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: ret void
;
entry:
%a = alloca i32, align 4
br i1 %cond, label %left, label %right
left:
br label %merge
right:
br label %merge
merge:
%ptr = phi ptr [ %a, %left ], [ %other, %right ]
store atomic i32 %value, ptr %ptr seq_cst, align 4
ret void
}
define void @store_atomic_volatile_to_phi(i1 %cond, i32 %value, ptr %other) {
; CHECK-LABEL: @store_atomic_volatile_to_phi(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
; CHECK-NEXT: br i1 [[COND:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
; CHECK: left:
; CHECK-NEXT: br label [[MERGE:%.*]]
; CHECK: right:
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[A]], [[LEFT]] ], [ [[OTHER:%.*]], [[RIGHT]] ]
; CHECK-NEXT: store atomic volatile i32 [[VALUE:%.*]], ptr [[PTR]] seq_cst, align 4
; CHECK-NEXT: ret void
;
entry:
%a = alloca i32, align 4
br i1 %cond, label %left, label %right
left:
br label %merge
right:
br label %merge
merge:
%ptr = phi ptr [ %a, %left ], [ %other, %right ]
store atomic volatile i32 %value, ptr %ptr seq_cst, align 4
ret void
}