xref: /llvm-project/llvm/test/Transforms/SROA/select-store.ll (revision 89a6106ce50689c733be13aaef4be5f3f73708a2)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes='sroa<preserve-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
3; RUN: opt < %s -passes='sroa<modify-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
4
5declare i8 @gen.i8()
6declare ptr @gen.ptr()
7
8define i8 @store(i8 %init, i1 %cond, ptr dereferenceable(4) %escape) {
9; CHECK-PRESERVE-CFG-LABEL: @store(
10; CHECK-PRESERVE-CFG-NEXT:  entry:
11; CHECK-PRESERVE-CFG-NEXT:    [[TMP:%.*]] = alloca i8, align 4
12; CHECK-PRESERVE-CFG-NEXT:    store i8 [[INIT:%.*]], ptr [[TMP]], align 4
13; CHECK-PRESERVE-CFG-NEXT:    [[REINIT:%.*]] = call i8 @gen.i8()
14; CHECK-PRESERVE-CFG-NEXT:    [[ADDR:%.*]] = select i1 [[COND:%.*]], ptr [[TMP]], ptr [[ESCAPE:%.*]]
15; CHECK-PRESERVE-CFG-NEXT:    store i8 [[REINIT]], ptr [[ADDR]], align 4
16; CHECK-PRESERVE-CFG-NEXT:    [[TMP_0_RES:%.*]] = load i8, ptr [[TMP]], align 4
17; CHECK-PRESERVE-CFG-NEXT:    ret i8 [[TMP_0_RES]]
18;
19; CHECK-MODIFY-CFG-LABEL: @store(
20; CHECK-MODIFY-CFG-NEXT:  entry:
21; CHECK-MODIFY-CFG-NEXT:    [[REINIT:%.*]] = call i8 @gen.i8()
22; CHECK-MODIFY-CFG-NEXT:    br i1 [[COND:%.*]], label [[ENTRY_THEN:%.*]], label [[ENTRY_ELSE:%.*]]
23; CHECK-MODIFY-CFG:       entry.then:
24; CHECK-MODIFY-CFG-NEXT:    br label [[ENTRY_CONT:%.*]]
25; CHECK-MODIFY-CFG:       entry.else:
26; CHECK-MODIFY-CFG-NEXT:    store i8 [[REINIT]], ptr [[ESCAPE:%.*]], align 4
27; CHECK-MODIFY-CFG-NEXT:    br label [[ENTRY_CONT]]
28; CHECK-MODIFY-CFG:       entry.cont:
29; CHECK-MODIFY-CFG-NEXT:    [[TMP_0:%.*]] = phi i8 [ [[REINIT]], [[ENTRY_THEN]] ], [ [[INIT:%.*]], [[ENTRY_ELSE]] ]
30; CHECK-MODIFY-CFG-NEXT:    ret i8 [[TMP_0]]
31;
32entry:
33  %tmp = alloca i8, align 4
34  store i8 %init, ptr %tmp, align 4
35  %reinit = call i8 @gen.i8()
36  %addr = select i1 %cond, ptr %tmp, ptr %escape
37  store i8 %reinit, ptr %addr, align 4
38  %res = load i8, ptr %tmp, align 4
39  ret i8 %res
40}
41
42define ptr @store_of_addr(ptr %init, i1 %cond, ptr %other.ptr, ptr dereferenceable(4) %escape.dest) {
43; CHECK-LABEL: @store_of_addr(
44; CHECK-NEXT:  entry:
45; CHECK-NEXT:    [[TMP:%.*]] = alloca ptr, align 4
46; CHECK-NEXT:    store ptr [[INIT:%.*]], ptr [[TMP]], align 4
47; CHECK-NEXT:    [[REINIT:%.*]] = call ptr @gen.ptr()
48; CHECK-NEXT:    [[ADDR:%.*]] = select i1 [[COND:%.*]], ptr [[TMP]], ptr [[OTHER_PTR:%.*]]
49; CHECK-NEXT:    store ptr [[ADDR]], ptr [[ESCAPE_DEST:%.*]], align 4
50; CHECK-NEXT:    [[RES:%.*]] = load ptr, ptr [[TMP]], align 4
51; CHECK-NEXT:    ret ptr [[RES]]
52;
53entry:
54  %tmp = alloca ptr, align 4
55  store ptr %init, ptr %tmp, align 4
56  %reinit = call ptr @gen.ptr()
57  %addr = select i1 %cond, ptr %tmp, ptr %other.ptr
58  store ptr %addr, ptr %escape.dest, align 4
59  %res = load ptr, ptr %tmp, align 4
60  ret ptr %res
61}
62
63define i8 @store_atomic_unord(i8 %init, i1 %cond, ptr dereferenceable(4) %escape) {
64; CHECK-PRESERVE-CFG-LABEL: @store_atomic_unord(
65; CHECK-PRESERVE-CFG-NEXT:  entry:
66; CHECK-PRESERVE-CFG-NEXT:    [[TMP:%.*]] = alloca i8, align 4
67; CHECK-PRESERVE-CFG-NEXT:    store i8 [[INIT:%.*]], ptr [[TMP]], align 4
68; CHECK-PRESERVE-CFG-NEXT:    [[REINIT:%.*]] = call i8 @gen.i8()
69; CHECK-PRESERVE-CFG-NEXT:    [[ADDR:%.*]] = select i1 [[COND:%.*]], ptr [[TMP]], ptr [[ESCAPE:%.*]]
70; CHECK-PRESERVE-CFG-NEXT:    store atomic i8 [[REINIT]], ptr [[ADDR]] unordered, align 4
71; CHECK-PRESERVE-CFG-NEXT:    [[TMP_0_RES:%.*]] = load i8, ptr [[TMP]], align 4
72; CHECK-PRESERVE-CFG-NEXT:    ret i8 [[TMP_0_RES]]
73;
74; CHECK-MODIFY-CFG-LABEL: @store_atomic_unord(
75; CHECK-MODIFY-CFG-NEXT:  entry:
76; CHECK-MODIFY-CFG-NEXT:    [[REINIT:%.*]] = call i8 @gen.i8()
77; CHECK-MODIFY-CFG-NEXT:    br i1 [[COND:%.*]], label [[ENTRY_THEN:%.*]], label [[ENTRY_ELSE:%.*]]
78; CHECK-MODIFY-CFG:       entry.then:
79; CHECK-MODIFY-CFG-NEXT:    br label [[ENTRY_CONT:%.*]]
80; CHECK-MODIFY-CFG:       entry.else:
81; CHECK-MODIFY-CFG-NEXT:    store atomic i8 [[REINIT]], ptr [[ESCAPE:%.*]] unordered, align 4
82; CHECK-MODIFY-CFG-NEXT:    br label [[ENTRY_CONT]]
83; CHECK-MODIFY-CFG:       entry.cont:
84; CHECK-MODIFY-CFG-NEXT:    [[TMP_0:%.*]] = phi i8 [ [[REINIT]], [[ENTRY_THEN]] ], [ [[INIT:%.*]], [[ENTRY_ELSE]] ]
85; CHECK-MODIFY-CFG-NEXT:    ret i8 [[TMP_0]]
86;
87entry:
88  %tmp = alloca i8, align 4
89  store i8 %init, ptr %tmp, align 4
90  %reinit = call i8 @gen.i8()
91  %addr = select i1 %cond, ptr %tmp, ptr %escape
92  store atomic i8 %reinit, ptr %addr unordered, align 4
93  %res = load i8, ptr %tmp, align 4
94  ret i8 %res
95}
96
97define i8 @store_volatile(i8 %init, i1 %cond, ptr dereferenceable(4) %escape) {
98; CHECK-LABEL: @store_volatile(
99; CHECK-NEXT:  entry:
100; CHECK-NEXT:    [[TMP:%.*]] = alloca i8, align 4
101; CHECK-NEXT:    store i8 [[INIT:%.*]], ptr [[TMP]], align 4
102; CHECK-NEXT:    [[REINIT:%.*]] = call i8 @gen.i8()
103; CHECK-NEXT:    [[ADDR:%.*]] = select i1 [[COND:%.*]], ptr [[TMP]], ptr [[ESCAPE:%.*]]
104; CHECK-NEXT:    store volatile i8 [[REINIT]], ptr [[ADDR]], align 4
105; CHECK-NEXT:    [[TMP_0_RES:%.*]] = load i8, ptr [[TMP]], align 4
106; CHECK-NEXT:    ret i8 [[TMP_0_RES]]
107;
108entry:
109  %tmp = alloca i8, align 4
110  store i8 %init, ptr %tmp, align 4
111  %reinit = call i8 @gen.i8()
112  %addr = select i1 %cond, ptr %tmp, ptr %escape
113  store volatile i8 %reinit, ptr %addr, align 4
114  %res = load i8, ptr %tmp, align 4
115  ret i8 %res
116}
117