Skip to content

Commit ea9e174

Browse files
authored
[msan][NFCI] Add test for llvm.bitreverse (llvm#125592)
The heuristic handler for llvm.reverse is incorrect because it doesn't reverse the shadow. Forked from llvm/test/CodeGen/X86/bitreverse.ll
1 parent 13ded68 commit ea9e174

File tree

1 file changed

+218
-0
lines changed

1 file changed

+218
-0
lines changed
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2+
; RUN: opt < %s -passes=msan -S | FileCheck %s
3+
;
4+
; The heuristic handler for llvm.reverse is incorrect because it doesn't
5+
; reverse the shadow.
6+
;
7+
; Forked from llvm/test/CodeGen/X86/bitreverse.ll
8+
9+
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
10+
target triple = "x86_64-unknown-linux-gnu"
11+
12+
declare <2 x i16> @llvm.bitreverse.v2i16(<2 x i16>) readnone
13+
14+
define <2 x i16> @test_bitreverse_v2i16(<2 x i16> %a) nounwind #0 {
15+
; CHECK-LABEL: define <2 x i16> @test_bitreverse_v2i16(
16+
; CHECK-SAME: <2 x i16> [[A:%.*]]) #[[ATTR1:[0-9]+]] {
17+
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i16>, ptr @__msan_param_tls, align 8
18+
; CHECK-NEXT: call void @llvm.donothing()
19+
; CHECK-NEXT: [[B:%.*]] = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> [[A]])
20+
; CHECK-NEXT: store <2 x i16> [[TMP1]], ptr @__msan_retval_tls, align 8
21+
; CHECK-NEXT: ret <2 x i16> [[B]]
22+
;
23+
%b = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> %a)
24+
ret <2 x i16> %b
25+
}
26+
27+
declare i64 @llvm.bitreverse.i64(i64) readnone
28+
29+
define i64 @test_bitreverse_i64(i64 %a) nounwind #0 {
30+
; CHECK-LABEL: define i64 @test_bitreverse_i64(
31+
; CHECK-SAME: i64 [[A:%.*]]) #[[ATTR1]] {
32+
; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr @__msan_param_tls, align 8
33+
; CHECK-NEXT: call void @llvm.donothing()
34+
; CHECK-NEXT: [[B:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[A]])
35+
; CHECK-NEXT: store i64 [[TMP1]], ptr @__msan_retval_tls, align 8
36+
; CHECK-NEXT: ret i64 [[B]]
37+
;
38+
%b = call i64 @llvm.bitreverse.i64(i64 %a)
39+
ret i64 %b
40+
}
41+
42+
declare i32 @llvm.bitreverse.i32(i32) readnone
43+
44+
define i32 @test_bitreverse_i32(i32 %a) nounwind #0 {
45+
; CHECK-LABEL: define i32 @test_bitreverse_i32(
46+
; CHECK-SAME: i32 [[A:%.*]]) #[[ATTR1]] {
47+
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @__msan_param_tls, align 8
48+
; CHECK-NEXT: call void @llvm.donothing()
49+
; CHECK-NEXT: [[B:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[A]])
50+
; CHECK-NEXT: store i32 [[TMP1]], ptr @__msan_retval_tls, align 8
51+
; CHECK-NEXT: ret i32 [[B]]
52+
;
53+
%b = call i32 @llvm.bitreverse.i32(i32 %a)
54+
ret i32 %b
55+
}
56+
57+
declare i24 @llvm.bitreverse.i24(i24) readnone
58+
59+
define i24 @test_bitreverse_i24(i24 %a) nounwind #0 {
60+
; CHECK-LABEL: define i24 @test_bitreverse_i24(
61+
; CHECK-SAME: i24 [[A:%.*]]) #[[ATTR1]] {
62+
; CHECK-NEXT: [[TMP1:%.*]] = load i24, ptr @__msan_param_tls, align 8
63+
; CHECK-NEXT: call void @llvm.donothing()
64+
; CHECK-NEXT: [[B:%.*]] = call i24 @llvm.bitreverse.i24(i24 [[A]])
65+
; CHECK-NEXT: store i24 [[TMP1]], ptr @__msan_retval_tls, align 8
66+
; CHECK-NEXT: ret i24 [[B]]
67+
;
68+
%b = call i24 @llvm.bitreverse.i24(i24 %a)
69+
ret i24 %b
70+
}
71+
72+
declare i16 @llvm.bitreverse.i16(i16) readnone
73+
74+
define i16 @test_bitreverse_i16(i16 %a) nounwind #0 {
75+
; CHECK-LABEL: define i16 @test_bitreverse_i16(
76+
; CHECK-SAME: i16 [[A:%.*]]) #[[ATTR1]] {
77+
; CHECK-NEXT: [[TMP1:%.*]] = load i16, ptr @__msan_param_tls, align 8
78+
; CHECK-NEXT: call void @llvm.donothing()
79+
; CHECK-NEXT: [[B:%.*]] = call i16 @llvm.bitreverse.i16(i16 [[A]])
80+
; CHECK-NEXT: store i16 [[TMP1]], ptr @__msan_retval_tls, align 8
81+
; CHECK-NEXT: ret i16 [[B]]
82+
;
83+
%b = call i16 @llvm.bitreverse.i16(i16 %a)
84+
ret i16 %b
85+
}
86+
87+
declare i8 @llvm.bitreverse.i8(i8) readnone
88+
89+
define i8 @test_bitreverse_i8(i8 %a) #0 {
90+
; CHECK-LABEL: define i8 @test_bitreverse_i8(
91+
; CHECK-SAME: i8 [[A:%.*]]) #[[ATTR2:[0-9]+]] {
92+
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr @__msan_param_tls, align 8
93+
; CHECK-NEXT: call void @llvm.donothing()
94+
; CHECK-NEXT: [[B:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[A]])
95+
; CHECK-NEXT: store i8 [[TMP1]], ptr @__msan_retval_tls, align 8
96+
; CHECK-NEXT: ret i8 [[B]]
97+
;
98+
%b = call i8 @llvm.bitreverse.i8(i8 %a)
99+
ret i8 %b
100+
}
101+
102+
declare i4 @llvm.bitreverse.i4(i4) readnone
103+
104+
define i4 @test_bitreverse_i4(i4 %a) #0 {
105+
; CHECK-LABEL: define i4 @test_bitreverse_i4(
106+
; CHECK-SAME: i4 [[A:%.*]]) #[[ATTR2]] {
107+
; CHECK-NEXT: [[TMP1:%.*]] = load i4, ptr @__msan_param_tls, align 8
108+
; CHECK-NEXT: call void @llvm.donothing()
109+
; CHECK-NEXT: [[B:%.*]] = call i4 @llvm.bitreverse.i4(i4 [[A]])
110+
; CHECK-NEXT: store i4 [[TMP1]], ptr @__msan_retval_tls, align 8
111+
; CHECK-NEXT: ret i4 [[B]]
112+
;
113+
%b = call i4 @llvm.bitreverse.i4(i4 %a)
114+
ret i4 %b
115+
}
116+
117+
; These tests check that bitreverse(constant) calls are folded
118+
119+
define <2 x i16> @fold_v2i16() #0 {
120+
; CHECK-LABEL: define <2 x i16> @fold_v2i16(
121+
; CHECK-SAME: ) #[[ATTR2]] {
122+
; CHECK-NEXT: call void @llvm.donothing()
123+
; CHECK-NEXT: [[B:%.*]] = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> <i16 15, i16 3840>)
124+
; CHECK-NEXT: store <2 x i16> zeroinitializer, ptr @__msan_retval_tls, align 8
125+
; CHECK-NEXT: ret <2 x i16> [[B]]
126+
;
127+
%b = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> <i16 15, i16 3840>)
128+
ret <2 x i16> %b
129+
}
130+
131+
define i24 @fold_i24() #0 {
132+
; CHECK-LABEL: define i24 @fold_i24(
133+
; CHECK-SAME: ) #[[ATTR2]] {
134+
; CHECK-NEXT: call void @llvm.donothing()
135+
; CHECK-NEXT: [[B:%.*]] = call i24 @llvm.bitreverse.i24(i24 4096)
136+
; CHECK-NEXT: store i24 0, ptr @__msan_retval_tls, align 8
137+
; CHECK-NEXT: ret i24 [[B]]
138+
;
139+
%b = call i24 @llvm.bitreverse.i24(i24 4096)
140+
ret i24 %b
141+
}
142+
143+
define i8 @fold_i8() #0 {
144+
; CHECK-LABEL: define i8 @fold_i8(
145+
; CHECK-SAME: ) #[[ATTR2]] {
146+
; CHECK-NEXT: call void @llvm.donothing()
147+
; CHECK-NEXT: [[B:%.*]] = call i8 @llvm.bitreverse.i8(i8 15)
148+
; CHECK-NEXT: store i8 0, ptr @__msan_retval_tls, align 8
149+
; CHECK-NEXT: ret i8 [[B]]
150+
;
151+
%b = call i8 @llvm.bitreverse.i8(i8 15)
152+
ret i8 %b
153+
}
154+
155+
define i4 @fold_i4() #0 {
156+
; CHECK-LABEL: define i4 @fold_i4(
157+
; CHECK-SAME: ) #[[ATTR2]] {
158+
; CHECK-NEXT: call void @llvm.donothing()
159+
; CHECK-NEXT: [[B:%.*]] = call i4 @llvm.bitreverse.i4(i4 -8)
160+
; CHECK-NEXT: store i4 0, ptr @__msan_retval_tls, align 8
161+
; CHECK-NEXT: ret i4 [[B]]
162+
;
163+
%b = call i4 @llvm.bitreverse.i4(i4 8)
164+
ret i4 %b
165+
}
166+
167+
; These tests check that bitreverse(bitreverse()) calls are removed
168+
169+
define i8 @identity_i8(i8 %a) #0 {
170+
; CHECK-LABEL: define i8 @identity_i8(
171+
; CHECK-SAME: i8 [[A:%.*]]) #[[ATTR2]] {
172+
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr @__msan_param_tls, align 8
173+
; CHECK-NEXT: call void @llvm.donothing()
174+
; CHECK-NEXT: [[B:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[A]])
175+
; CHECK-NEXT: [[C:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[B]])
176+
; CHECK-NEXT: store i8 [[TMP1]], ptr @__msan_retval_tls, align 8
177+
; CHECK-NEXT: ret i8 [[C]]
178+
;
179+
%b = call i8 @llvm.bitreverse.i8(i8 %a)
180+
%c = call i8 @llvm.bitreverse.i8(i8 %b)
181+
ret i8 %c
182+
}
183+
184+
define <2 x i16> @identity_v2i16(<2 x i16> %a) #0 {
185+
; CHECK-LABEL: define <2 x i16> @identity_v2i16(
186+
; CHECK-SAME: <2 x i16> [[A:%.*]]) #[[ATTR2]] {
187+
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i16>, ptr @__msan_param_tls, align 8
188+
; CHECK-NEXT: call void @llvm.donothing()
189+
; CHECK-NEXT: [[B:%.*]] = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> [[A]])
190+
; CHECK-NEXT: [[C:%.*]] = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> [[B]])
191+
; CHECK-NEXT: store <2 x i16> [[TMP1]], ptr @__msan_retval_tls, align 8
192+
; CHECK-NEXT: ret <2 x i16> [[C]]
193+
;
194+
%b = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> %a)
195+
%c = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> %b)
196+
ret <2 x i16> %c
197+
}
198+
199+
; Undef tests omitted
200+
201+
; Make sure we don't assert during type legalization promoting a large
202+
; bitreverse due to the need for a large shift that won't fit in the i8 returned
203+
; from getShiftAmountTy.
204+
define i528 @large_promotion(i528 %A) nounwind #0 {
205+
; CHECK-LABEL: define i528 @large_promotion(
206+
; CHECK-SAME: i528 [[A:%.*]]) #[[ATTR1]] {
207+
; CHECK-NEXT: [[TMP1:%.*]] = load i528, ptr @__msan_param_tls, align 8
208+
; CHECK-NEXT: call void @llvm.donothing()
209+
; CHECK-NEXT: [[Z:%.*]] = call i528 @llvm.bitreverse.i528(i528 [[A]])
210+
; CHECK-NEXT: store i528 [[TMP1]], ptr @__msan_retval_tls, align 8
211+
; CHECK-NEXT: ret i528 [[Z]]
212+
;
213+
%Z = call i528 @llvm.bitreverse.i528(i528 %A)
214+
ret i528 %Z
215+
}
216+
declare i528 @llvm.bitreverse.i528(i528)
217+
218+
attributes #0 = { sanitize_memory }

0 commit comments

Comments
 (0)