@@ -8,8 +8,8 @@ define void @test_unconditional(i1 %c, ptr dereferenceable(8) align 8 %p) {
8
8
; CHECK-LABEL: define void @test_unconditional
9
9
; CHECK-SAME: (i1 [[C:%.*]], ptr align 8 dereferenceable(8) [[P:%.*]]) {
10
10
; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0:![0-9]+]]
11
- ; CHECK-NEXT: [[V2:%.*]] = load ptr, ptr [[P]], align 8, !nonnull !1 , !noundef !1
12
- ; CHECK-NEXT: [[V3:%.*]] = load ptr, ptr [[P]], align 8, !dereferenceable !2 , !align !2
11
+ ; CHECK-NEXT: [[V2:%.*]] = load ptr, ptr [[P]], align 8, !nonnull [[META1:![0-9]+]] , !noundef [[META1]]
12
+ ; CHECK-NEXT: [[V3:%.*]] = load ptr, ptr [[P]], align 8, !dereferenceable [[META2:![0-9]+]] , !align [[META2]]
13
13
; CHECK-NEXT: br label [[LOOP:%.*]]
14
14
; CHECK: loop:
15
15
; CHECK-NEXT: call void @foo(i32 [[V1]], ptr [[V2]], ptr [[V3]])
@@ -36,8 +36,8 @@ define void @test_conditional(i1 %c, i1 %c2, ptr dereferenceable(8) align 8 %p)
36
36
; CHECK-LABEL: define void @test_conditional
37
37
; CHECK-SAME: (i1 [[C:%.*]], i1 [[C2:%.*]], ptr align 8 dereferenceable(8) [[P:%.*]]) {
38
38
; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0]]
39
- ; CHECK-NEXT: [[V2:%.*]] = load ptr, ptr [[P]], align 8, !nonnull !1
40
- ; CHECK-NEXT: [[V3:%.*]] = load ptr, ptr [[P]], align 8, !align !2
39
+ ; CHECK-NEXT: [[V2:%.*]] = load ptr, ptr [[P]], align 8, !nonnull [[META1]]
40
+ ; CHECK-NEXT: [[V3:%.*]] = load ptr, ptr [[P]], align 8, !align [[META2]]
41
41
; CHECK-NEXT: br label [[LOOP:%.*]]
42
42
; CHECK: loop:
43
43
; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[LATCH:%.*]]
@@ -67,10 +67,76 @@ latch:
67
67
exit:
68
68
ret void
69
69
}
70
+
71
+ declare i16 @e (i32 )
72
+
73
+ ; FIXME: alias metadata violations are UB, so should not be set on the hoisted
74
+ ; load, as it may not execute.
75
+ define void @noalias_metadata_load_may_not_execute () {
76
+ ; CHECK-LABEL: define void @noalias_metadata_load_may_not_execute() {
77
+ ; CHECK-NEXT: entry:
78
+ ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 16
79
+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[A]]
80
+ ; CHECK-NEXT: [[GEP_PROMOTED:%.*]] = load i32, ptr [[GEP]], align 4, !tbaa [[TBAA3:![0-9]+]], !noalias [[META7:![0-9]+]]
81
+ ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
82
+ ; CHECK: loop.header:
83
+ ; CHECK-NEXT: [[ADD1:%.*]] = phi i32 [ [[GEP_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[LOOP_LATCH:%.*]] ]
84
+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH]] ]
85
+ ; CHECK-NEXT: [[CALL:%.*]] = call signext i16 @e(i32 [[IV]])
86
+ ; CHECK-NEXT: [[C:%.*]] = icmp eq i16 [[CALL]], 0
87
+ ; CHECK-NEXT: br i1 [[C]], label [[LOOP_LATCH]], label [[EXIT:%.*]]
88
+ ; CHECK: loop.latch:
89
+ ; CHECK-NEXT: [[ADD]] = add i32 [[ADD1]], 1
90
+ ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
91
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IV]], 100
92
+ ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_HEADER]], label [[EXIT]]
93
+ ; CHECK: exit:
94
+ ; CHECK-NEXT: [[ADD2:%.*]] = phi i32 [ [[ADD]], [[LOOP_LATCH]] ], [ [[ADD1]], [[LOOP_HEADER]] ]
95
+ ; CHECK-NEXT: store i32 [[ADD2]], ptr [[GEP]], align 4, !tbaa [[TBAA3]], !noalias [[META7]]
96
+ ; CHECK-NEXT: ret void
97
+ ;
98
+ entry:
99
+ %a = alloca i32 , align 16
100
+ br label %loop.header
101
+
102
+ loop.header:
103
+ %iv = phi i32 [ 0 , %entry ], [ %iv.next , %loop.latch ]
104
+ %call = call signext i16 @e (i32 %iv )
105
+ %c = icmp eq i16 %call , 0
106
+ br i1 %c , label %loop.latch , label %exit
107
+
108
+ loop.latch:
109
+ %gep = getelementptr inbounds i32 , ptr %a
110
+ %l = load i32 , ptr %gep , !tbaa !0 , !noalias !4
111
+ %add = add i32 %l , 1
112
+ store i32 %add , ptr %gep , align 4 , !tbaa !0 , !noalias !4
113
+ %iv.next = add i32 %iv , 1
114
+ %cmp = icmp ult i32 %iv , 100
115
+ br i1 %cmp , label %loop.header , label %exit
116
+
117
+ exit:
118
+ ret void
119
+ }
120
+
121
+
122
+ !0 = !{!1 , !1 , i64 0 }
123
+ !1 = !{!"short" , !2 , i64 0 }
124
+ !2 = !{!"omnipotent char" , !3 , i64 0 }
125
+ !3 = !{!"Simple C/C++ TBAA" }
126
+ !4 = !{!5 }
127
+ !5 = distinct !{!5 , !6 }
128
+ !6 = distinct !{!6 }
70
129
;.
71
130
; CHECK: attributes #[[ATTR0:[0-9]+]] = { memory(none) }
72
131
;.
73
132
; CHECK: [[RNG0]] = !{i32 0, i32 10}
74
- ; CHECK: [[META1:![0-9]+]] = !{}
75
- ; CHECK: [[META2:![0-9]+]] = !{i64 4}
133
+ ; CHECK: [[META1]] = !{}
134
+ ; CHECK: [[META2]] = !{i64 4}
135
+ ; CHECK: [[TBAA3]] = !{[[META4:![0-9]+]], [[META4]], i64 0}
136
+ ; CHECK: [[META4]] = !{!"short", [[META5:![0-9]+]], i64 0}
137
+ ; CHECK: [[META5]] = !{!"omnipotent char", [[META6:![0-9]+]], i64 0}
138
+ ; CHECK: [[META6]] = !{!"Simple C/C++ TBAA"}
139
+ ; CHECK: [[META7]] = !{[[META8:![0-9]+]]}
140
+ ; CHECK: [[META8]] = distinct !{[[META8]], [[META9:![0-9]+]]}
141
+ ; CHECK: [[META9]] = distinct !{[[META9]]}
76
142
;.
0 commit comments