xref: /llvm-project/llvm/test/Transforms/DeadStoreElimination/overlap.ll (revision 1ca64c5fb74270661ca2f9ebd821f47dcb3152b4)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=dse -S | FileCheck %s
3; RUN: opt < %s -aa-pipeline=basic-aa -passes=dse -S | FileCheck %s
4
5declare void @use(ptr)
6
7define void @test1() {
8; CHECK-LABEL: @test1(
9; CHECK-NEXT:    [[A:%.*]] = alloca i64, align 8
10; CHECK-NEXT:    call void @use(ptr [[A]])
11; CHECK-NEXT:    [[PTR2:%.*]] = getelementptr i8, ptr [[A]], i32 1
12; CHECK-NEXT:    store i8 10, ptr [[A]], align 1
13; CHECK-NEXT:    store i8 20, ptr [[PTR2]], align 1
14; CHECK-NEXT:    [[LV:%.*]] = load i64, ptr [[A]], align 4
15; CHECK-NEXT:    store i8 0, ptr [[A]], align 1
16; CHECK-NEXT:    call void @use(ptr [[A]])
17; CHECK-NEXT:    ret void
18;
19  %a = alloca i64
20  call void @use(ptr %a)
21  %ptr2 = getelementptr i8, ptr %a, i32 1
22
23  store i8 10, ptr %a
24  store i8 20, ptr %ptr2
25  %lv = load i64, ptr %a
26  store i8 0, ptr %a
27
28  call void @use(ptr %a)
29  ret void
30}
31
32define void @test2(i1 %arg) {
33; CHECK-LABEL: @test2(
34; CHECK-NEXT:    [[A:%.*]] = alloca i64, align 8
35; CHECK-NEXT:    call void @use(ptr [[A]])
36; CHECK-NEXT:    [[PTR2:%.*]] = getelementptr i8, ptr [[A]], i32 1
37; CHECK-NEXT:    store i8 10, ptr [[A]], align 1
38; CHECK-NEXT:    store i8 20, ptr [[PTR2]], align 1
39; CHECK-NEXT:    br i1 %arg, label [[BB1:%.*]], label [[END:%.*]]
40; CHECK:       bb1:
41; CHECK-NEXT:    [[LV:%.*]] = load i64, ptr [[A]], align 4
42; CHECK-NEXT:    br label [[END]]
43; CHECK:       end:
44; CHECK-NEXT:    store i8 0, ptr [[A]], align 1
45; CHECK-NEXT:    call void @use(ptr [[A]])
46; CHECK-NEXT:    ret void
47;
48  %a = alloca i64
49  call void @use(ptr %a)
50  %ptr2 = getelementptr i8, ptr %a, i32 1
51
52  store i8 10, ptr %a
53  store i8 20, ptr %ptr2
54  br i1 %arg, label %bb1, label %end
55
56bb1:
57  %lv = load i64, ptr %a
58  br label %end
59
60end:
61  store i8 0, ptr %a
62  call void @use(ptr %a)
63  ret void
64}
65
66; The store to %a0 is dead, because only %a1 is read later.
67define void @test3(i1 %c) {
68; CHECK-LABEL: @test3(
69; CHECK-NEXT:    [[A:%.*]] = alloca [2 x i8], align 1
70; CHECK-NEXT:    [[A1:%.*]] = getelementptr [2 x i8], ptr [[A]], i32 0, i32 1
71; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
72; CHECK:       if:
73; CHECK-NEXT:    store [2 x i8] zeroinitializer, ptr [[A]], align 1
74; CHECK-NEXT:    br label [[ELSE]]
75; CHECK:       else:
76; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[A1]], align 1
77; CHECK-NEXT:    ret void
78;
79  %a = alloca [2 x i8]
80  %a1 = getelementptr [2 x i8], ptr %a, i32 0, i32 1
81  store i8 1, ptr %a
82  br i1 %c, label %if, label %else
83
84if:
85  store [2 x i8] zeroinitializer, ptr %a
86  br label %else
87
88else:
89  load i8, ptr %a1
90  ret void
91}
92
93; Variation on the previous test case, where only the store to %a is dead,
94; but not the one to %a1. This tests for a potential caching bug.
95define void @test4(i1 %c) {
96; CHECK-LABEL: @test4(
97; CHECK-NEXT:    [[A:%.*]] = alloca [2 x i8], align 1
98; CHECK-NEXT:    [[A1:%.*]] = getelementptr [2 x i8], ptr [[A]], i32 0, i32 1
99; CHECK-NEXT:    store i8 1, ptr [[A1]], align 1
100; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
101; CHECK:       if:
102; CHECK-NEXT:    store [2 x i8] zeroinitializer, ptr [[A]], align 1
103; CHECK-NEXT:    br label [[ELSE]]
104; CHECK:       else:
105; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[A1]], align 1
106; CHECK-NEXT:    ret void
107;
108  %a = alloca [2 x i8]
109  %a1 = getelementptr [2 x i8], ptr %a, i32 0, i32 1
110  store i8 1, ptr %a1
111  store i8 1, ptr %a
112  br i1 %c, label %if, label %else
113
114if:
115  store [2 x i8] zeroinitializer, ptr %a
116  br label %else
117
118else:
119  load i8, ptr %a1
120  ret void
121}
122