Skip to content

Commit 7f19b1e

Browse files
committed
[LICM] Add test showing incorrectly setting alasing metadata.
The new test illustrates a case where LICM introduces UB-implying metadata on speculated loads that may not execute in the original version. The aliasing metadata behavior has been clarified in #116220.
1 parent f4ed79b commit 7f19b1e

File tree

1 file changed

+72
-6
lines changed

1 file changed

+72
-6
lines changed

llvm/test/Transforms/LICM/hoist-metadata.ll

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ define void @test_unconditional(i1 %c, ptr dereferenceable(8) align 8 %p) {
88
; CHECK-LABEL: define void @test_unconditional
99
; CHECK-SAME: (i1 [[C:%.*]], ptr align 8 dereferenceable(8) [[P:%.*]]) {
1010
; 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]]
1313
; CHECK-NEXT: br label [[LOOP:%.*]]
1414
; CHECK: loop:
1515
; 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)
3636
; CHECK-LABEL: define void @test_conditional
3737
; CHECK-SAME: (i1 [[C:%.*]], i1 [[C2:%.*]], ptr align 8 dereferenceable(8) [[P:%.*]]) {
3838
; 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]]
4141
; CHECK-NEXT: br label [[LOOP:%.*]]
4242
; CHECK: loop:
4343
; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[LATCH:%.*]]
@@ -67,10 +67,76 @@ latch:
6767
exit:
6868
ret void
6969
}
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}
70129
;.
71130
; CHECK: attributes #[[ATTR0:[0-9]+]] = { memory(none) }
72131
;.
73132
; 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]]}
76142
;.

0 commit comments

Comments
 (0)