2
2
; RUN: opt -S -gvn -opaque-pointers < %s | FileCheck %s
3
3
4
4
declare void @use (ptr )
5
+ declare void @use.i32 (i32 )
5
6
6
- define void @test (ptr %p ) {
7
- ; CHECK-LABEL: @test (
7
+ define void @gep_cse (ptr %p ) {
8
+ ; CHECK-LABEL: @gep_cse (
8
9
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 1
9
10
; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i64, ptr [[P]], i64 1
10
11
; CHECK-NEXT: call void @use(ptr [[GEP1]])
@@ -20,3 +21,85 @@ define void @test(ptr %p) {
20
21
call void @use (ptr %gep3 )
21
22
ret void
22
23
}
24
+
25
+ define i32 @phi_trans (i1 %c , ptr %p1 , ptr %p2 ) {
26
+ ; CHECK-LABEL: @phi_trans(
27
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
28
+ ; CHECK: if:
29
+ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr [[P1:%.*]], i64 1
30
+ ; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[GEP1]], align 4
31
+ ; CHECK-NEXT: call void @use(i32 [[V1]]) #[[ATTR0:[0-9]+]]
32
+ ; CHECK-NEXT: br label [[JOIN:%.*]]
33
+ ; CHECK: else:
34
+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr [[P2:%.*]], i64 1
35
+ ; CHECK-NEXT: [[V2:%.*]] = load i32, ptr [[GEP2]], align 4
36
+ ; CHECK-NEXT: call void @use(i32 [[V2]]) #[[ATTR0]]
37
+ ; CHECK-NEXT: br label [[JOIN]]
38
+ ; CHECK: join:
39
+ ; CHECK-NEXT: [[V:%.*]] = phi i32 [ [[V1]], [[IF]] ], [ [[V2]], [[ELSE]] ]
40
+ ; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[P1]], [[IF]] ], [ [[P2]], [[ELSE]] ]
41
+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PHI]], i64 1
42
+ ; CHECK-NEXT: ret i32 [[V]]
43
+ ;
44
+ br i1 %c , label %if , label %else
45
+
46
+ if:
47
+ %gep1 = getelementptr i32 , ptr %p1 , i64 1
48
+ %v1 = load i32 , ptr %gep1
49
+ call void @use (i32 %v1 ) readnone
50
+ br label %join
51
+
52
+ else:
53
+ %gep2 = getelementptr i32 , ptr %p2 , i64 1
54
+ %v2 = load i32 , ptr %gep2
55
+ call void @use (i32 %v2 ) readnone
56
+ br label %join
57
+
58
+ join:
59
+ %phi = phi ptr [ %p1 , %if ], [ %p2 , %else ]
60
+ %gep = getelementptr i32 , ptr %phi , i64 1
61
+ %v = load i32 , ptr %gep
62
+ ret i32 %v
63
+ }
64
+
65
+ define i32 @phi_trans_different_types (i1 %c , ptr %p1 , ptr %p2 ) {
66
+ ; CHECK-LABEL: @phi_trans_different_types(
67
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
68
+ ; CHECK: if:
69
+ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr [[P1:%.*]], i64 1
70
+ ; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[GEP1]], align 4
71
+ ; CHECK-NEXT: call void @use.i32(i32 [[V1]]) #[[ATTR0]]
72
+ ; CHECK-NEXT: br label [[JOIN:%.*]]
73
+ ; CHECK: else:
74
+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i64, ptr [[P2:%.*]], i64 1
75
+ ; CHECK-NEXT: [[V2:%.*]] = load i32, ptr [[GEP2]], align 4
76
+ ; CHECK-NEXT: call void @use.i32(i32 [[V2]]) #[[ATTR0]]
77
+ ; CHECK-NEXT: [[GEP_PHI_TRANS_INSERT:%.*]] = getelementptr i32, ptr [[P2]], i64 1
78
+ ; CHECK-NEXT: [[V_PRE:%.*]] = load i32, ptr [[GEP_PHI_TRANS_INSERT]], align 4
79
+ ; CHECK-NEXT: br label [[JOIN]]
80
+ ; CHECK: join:
81
+ ; CHECK-NEXT: [[V:%.*]] = phi i32 [ [[V1]], [[IF]] ], [ [[V_PRE]], [[ELSE]] ]
82
+ ; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[P1]], [[IF]] ], [ [[P2]], [[ELSE]] ]
83
+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PHI]], i64 1
84
+ ; CHECK-NEXT: ret i32 [[V]]
85
+ ;
86
+ br i1 %c , label %if , label %else
87
+
88
+ if:
89
+ %gep1 = getelementptr i32 , ptr %p1 , i64 1
90
+ %v1 = load i32 , ptr %gep1
91
+ call void @use.i32 (i32 %v1 ) readnone
92
+ br label %join
93
+
94
+ else:
95
+ %gep2 = getelementptr i64 , ptr %p2 , i64 1
96
+ %v2 = load i32 , ptr %gep2
97
+ call void @use.i32 (i32 %v2 ) readnone
98
+ br label %join
99
+
100
+ join:
101
+ %phi = phi ptr [ %p1 , %if ], [ %p2 , %else ]
102
+ %gep = getelementptr i32 , ptr %phi , i64 1
103
+ %v = load i32 , ptr %gep
104
+ ret i32 %v
105
+ }
0 commit comments