[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / pointercast.ll
blob9f141213784b9d68dace46ae526493a9bc903d82
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 define i1 @bitcast_and_cmp(i32* readonly %src, i32* readnone %min, i32* readnone %max) {
5 ; CHECK-LABEL: @bitcast_and_cmp(
6 ; CHECK-NEXT:  check.0.min:
7 ; CHECK-NEXT:    [[SRC_C:%.*]] = bitcast i32* [[SRC:%.*]] to i8*
8 ; CHECK-NEXT:    [[MIN_C:%.*]] = bitcast i32* [[MIN:%.*]] to i8*
9 ; CHECK-NEXT:    [[MAX_C:%.*]] = bitcast i32* [[MAX:%.*]] to i16*
10 ; CHECK-NEXT:    [[GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3
11 ; CHECK-NEXT:    [[GEP_3_C:%.*]] = bitcast i32* [[GEP_3]] to i16*
12 ; CHECK-NEXT:    [[C_MIN_0:%.*]] = icmp ult i8* [[SRC_C]], [[MIN_C]]
13 ; CHECK-NEXT:    [[C_MAX_3:%.*]] = icmp ugt i16* [[GEP_3_C]], [[MAX_C]]
14 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_MIN_0]], [[C_MAX_3]]
15 ; CHECK-NEXT:    br i1 [[OR]], label [[TRAP:%.*]], label [[CHECKS:%.*]]
16 ; CHECK:       trap:
17 ; CHECK-NEXT:    ret i1 false
18 ; CHECK:       checks:
19 ; CHECK-NEXT:    [[C_3_MIN:%.*]] = icmp ult i32* [[GEP_3]], [[MIN]]
20 ; CHECK-NEXT:    [[C_3_MAX:%.*]] = icmp ult i32* [[GEP_3]], [[MAX]]
21 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 false, [[C_3_MAX]]
22 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
23 ; CHECK-NEXT:    [[C_1_MIN:%.*]] = icmp ult i32* [[GEP_1]], [[MIN]]
24 ; CHECK-NEXT:    [[C_1_MAX:%.*]] = icmp ult i32* [[GEP_1]], [[MAX]]
25 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 false, true
26 ; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2
27 ; CHECK-NEXT:    [[C_2_MIN:%.*]] = icmp ult i32* [[GEP_2]], [[MIN]]
28 ; CHECK-NEXT:    [[C_2_MAX:%.*]] = icmp ult i32* [[GEP_2]], [[MAX]]
29 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 false, true
30 ; CHECK-NEXT:    [[GEP_4:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 4
31 ; CHECK-NEXT:    [[C_4_MIN:%.*]] = icmp ult i32* [[GEP_4]], [[MIN]]
32 ; CHECK-NEXT:    [[C_4_MAX:%.*]] = icmp ult i32* [[GEP_4]], [[MAX]]
33 ; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 false, [[C_4_MAX]]
34 ; CHECK-NEXT:    [[RES_5:%.*]] = xor i1 [[RES_1]], [[RES_2]]
35 ; CHECK-NEXT:    [[RES_6:%.*]] = xor i1 [[RES_5]], [[RES_3]]
36 ; CHECK-NEXT:    [[RES_7:%.*]] = xor i1 [[RES_6]], [[RES_4]]
37 ; CHECK-NEXT:    ret i1 [[RES_7]]
39 check.0.min:
40   %src.c = bitcast i32* %src to i8*
41   %min.c = bitcast i32* %min to i8*
42   %max.c = bitcast i32* %max to i16*
44   %gep.3 = getelementptr inbounds i32, i32* %src, i64 3
45   %gep.3.c = bitcast i32* %gep.3 to i16*
46   %c.min.0 = icmp ult i8* %src.c, %min.c
47   %c.max.3 = icmp ugt i16* %gep.3.c, %max.c
49   %or = or i1 %c.min.0, %c.max.3
50   br i1 %or, label %trap, label %checks
52 trap:
53   ret i1 0
55 checks:
56   %c.3.min = icmp ult i32* %gep.3, %min
57   %c.3.max = icmp ult i32* %gep.3, %max
58   %res.1 = xor i1 %c.3.min, %c.3.max
60   %gep.1 = getelementptr inbounds i32, i32* %src, i64 1
61   %c.1.min = icmp ult i32* %gep.1, %min
62   %c.1.max = icmp ult i32* %gep.1, %max
63   %res.2 = xor i1 %c.1.min, %c.1.max
65   %gep.2 = getelementptr inbounds i32, i32* %src, i64 2
66   %c.2.min = icmp ult i32* %gep.2, %min
67   %c.2.max = icmp ult i32* %gep.2, %max
68   %res.3 = xor i1 %c.2.min, %c.2.max
70   %gep.4 = getelementptr inbounds i32, i32* %src, i64 4
71   %c.4.min = icmp ult i32* %gep.4, %min
72   %c.4.max = icmp ult i32* %gep.4, %max
73   %res.4 = xor i1 %c.4.min, %c.4.max
75   %res.5 = xor i1 %res.1, %res.2
76   %res.6 = xor i1 %res.5, %res.3
77   %res.7 = xor i1 %res.6, %res.4
79   ret i1 %res.7
82 define i1 @gep0_and_cmp(i32* readonly %src, i32* readnone %min, i32* readnone %max) {
83 ; CHECK-LABEL: @gep0_and_cmp(
84 ; CHECK-NEXT:  check.0.min:
85 ; CHECK-NEXT:    [[SRC_C:%.*]] = getelementptr i32, i32* [[SRC:%.*]], i64 0
86 ; CHECK-NEXT:    [[MIN_C:%.*]] = getelementptr i32, i32* [[MIN:%.*]], i64 0
87 ; CHECK-NEXT:    [[GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3
88 ; CHECK-NEXT:    [[GEP_3_C:%.*]] = getelementptr i32, i32* [[GEP_3]], i32 0
89 ; CHECK-NEXT:    [[C_MIN_0:%.*]] = icmp ult i32* [[SRC_C]], [[MIN_C]]
90 ; CHECK-NEXT:    [[C_MAX_3:%.*]] = icmp ugt i32* [[GEP_3_C]], [[MAX:%.*]]
91 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_MIN_0]], [[C_MAX_3]]
92 ; CHECK-NEXT:    br i1 [[OR]], label [[TRAP:%.*]], label [[CHECKS:%.*]]
93 ; CHECK:       trap:
94 ; CHECK-NEXT:    ret i1 false
95 ; CHECK:       checks:
96 ; CHECK-NEXT:    [[C_3_MIN:%.*]] = icmp ult i32* [[GEP_3]], [[MIN]]
97 ; CHECK-NEXT:    [[C_3_MAX:%.*]] = icmp ult i32* [[GEP_3]], [[MAX]]
98 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 false, [[C_3_MAX]]
99 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
100 ; CHECK-NEXT:    [[C_1_MIN:%.*]] = icmp ult i32* [[GEP_1]], [[MIN]]
101 ; CHECK-NEXT:    [[C_1_MAX:%.*]] = icmp ult i32* [[GEP_1]], [[MAX]]
102 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 false, true
103 ; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2
104 ; CHECK-NEXT:    [[C_2_MIN:%.*]] = icmp ult i32* [[GEP_2]], [[MIN]]
105 ; CHECK-NEXT:    [[C_2_MAX:%.*]] = icmp ult i32* [[GEP_2]], [[MAX]]
106 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 false, true
107 ; CHECK-NEXT:    [[GEP_4:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 4
108 ; CHECK-NEXT:    [[C_4_MIN:%.*]] = icmp ult i32* [[GEP_4]], [[MIN]]
109 ; CHECK-NEXT:    [[C_4_MAX:%.*]] = icmp ult i32* [[GEP_4]], [[MAX]]
110 ; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 false, [[C_4_MAX]]
111 ; CHECK-NEXT:    [[RES_5:%.*]] = xor i1 [[RES_1]], [[RES_2]]
112 ; CHECK-NEXT:    [[RES_6:%.*]] = xor i1 [[RES_5]], [[RES_3]]
113 ; CHECK-NEXT:    [[RES_7:%.*]] = xor i1 [[RES_6]], [[RES_4]]
114 ; CHECK-NEXT:    ret i1 [[RES_7]]
116 check.0.min:
117   %src.c = getelementptr i32, i32* %src, i64 0
118   %min.c = getelementptr i32, i32* %min, i64 0
120   %gep.3 = getelementptr inbounds i32, i32* %src, i64 3
121   %gep.3.c = getelementptr i32, i32* %gep.3, i32 0
122   %c.min.0 = icmp ult i32* %src.c, %min.c
123   %c.max.3 = icmp ugt i32* %gep.3.c, %max
125   %or = or i1 %c.min.0, %c.max.3
126   br i1 %or, label %trap, label %checks
128 trap:
129   ret i1 0
131 checks:
132   %c.3.min = icmp ult i32* %gep.3, %min
133   %c.3.max = icmp ult i32* %gep.3, %max
134   %res.1 = xor i1 %c.3.min, %c.3.max
136   %gep.1 = getelementptr inbounds i32, i32* %src, i64 1
137   %c.1.min = icmp ult i32* %gep.1, %min
138   %c.1.max = icmp ult i32* %gep.1, %max
139   %res.2 = xor i1 %c.1.min, %c.1.max
141   %gep.2 = getelementptr inbounds i32, i32* %src, i64 2
142   %c.2.min = icmp ult i32* %gep.2, %min
143   %c.2.max = icmp ult i32* %gep.2, %max
144   %res.3 = xor i1 %c.2.min, %c.2.max
146   %gep.4 = getelementptr inbounds i32, i32* %src, i64 4
147   %c.4.min = icmp ult i32* %gep.4, %min
148   %c.4.max = icmp ult i32* %gep.4, %max
149   %res.4 = xor i1 %c.4.min, %c.4.max
151   %res.5 = xor i1 %res.1, %res.2
152   %res.6 = xor i1 %res.5, %res.3
153   %res.7 = xor i1 %res.6, %res.4
155   ret i1 %res.7
158 ; Should not look through addresspacecast, because it may change the pointer
159 ; value.
160 define i1 @addrspacecast_and_cmp(i32* readonly %src, i32* readnone %min, i32* readnone %max) {
161 ; CHECK-LABEL: @addrspacecast_and_cmp(
162 ; CHECK-NEXT:  check.0.min:
163 ; CHECK-NEXT:    [[SRC_C:%.*]] = addrspacecast i32* [[SRC:%.*]] to i8 addrspace(1)*
164 ; CHECK-NEXT:    [[MIN_C:%.*]] = addrspacecast i32* [[MIN:%.*]] to i8 addrspace(1)*
165 ; CHECK-NEXT:    [[MAX_C:%.*]] = addrspacecast i32* [[MAX:%.*]] to i16 addrspace(1)*
166 ; CHECK-NEXT:    [[GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3
167 ; CHECK-NEXT:    [[GEP_3_C:%.*]] = addrspacecast i32* [[GEP_3]] to i16 addrspace(1)*
168 ; CHECK-NEXT:    [[C_MIN_0:%.*]] = icmp ult i8 addrspace(1)* [[SRC_C]], [[MIN_C]]
169 ; CHECK-NEXT:    [[C_MAX_3:%.*]] = icmp ugt i16 addrspace(1)* [[GEP_3_C]], [[MAX_C]]
170 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_MIN_0]], [[C_MAX_3]]
171 ; CHECK-NEXT:    br i1 [[OR]], label [[TRAP:%.*]], label [[CHECKS:%.*]]
172 ; CHECK:       trap:
173 ; CHECK-NEXT:    ret i1 false
174 ; CHECK:       checks:
175 ; CHECK-NEXT:    [[C_3_MIN:%.*]] = icmp ult i32* [[GEP_3]], [[MIN]]
176 ; CHECK-NEXT:    [[C_3_MAX:%.*]] = icmp ult i32* [[GEP_3]], [[MAX]]
177 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[C_3_MIN]], [[C_3_MAX]]
178 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
179 ; CHECK-NEXT:    [[C_1_MIN:%.*]] = icmp ult i32* [[GEP_1]], [[MIN]]
180 ; CHECK-NEXT:    [[C_1_MAX:%.*]] = icmp ult i32* [[GEP_1]], [[MAX]]
181 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[C_1_MIN]], [[C_1_MAX]]
182 ; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2
183 ; CHECK-NEXT:    [[C_2_MIN:%.*]] = icmp ult i32* [[GEP_2]], [[MIN]]
184 ; CHECK-NEXT:    [[C_2_MAX:%.*]] = icmp ult i32* [[GEP_2]], [[MAX]]
185 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[C_2_MIN]], [[C_2_MAX]]
186 ; CHECK-NEXT:    [[GEP_4:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 4
187 ; CHECK-NEXT:    [[C_4_MIN:%.*]] = icmp ult i32* [[GEP_4]], [[MIN]]
188 ; CHECK-NEXT:    [[C_4_MAX:%.*]] = icmp ult i32* [[GEP_4]], [[MAX]]
189 ; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[C_4_MIN]], [[C_4_MAX]]
190 ; CHECK-NEXT:    [[RES_5:%.*]] = xor i1 [[RES_1]], [[RES_2]]
191 ; CHECK-NEXT:    [[RES_6:%.*]] = xor i1 [[RES_5]], [[RES_3]]
192 ; CHECK-NEXT:    [[RES_7:%.*]] = xor i1 [[RES_6]], [[RES_4]]
193 ; CHECK-NEXT:    ret i1 [[RES_7]]
195 check.0.min:
196   %src.c = addrspacecast i32* %src to i8 addrspace(1)*
197   %min.c = addrspacecast i32* %min to i8 addrspace(1)*
198   %max.c = addrspacecast i32* %max to i16 addrspace(1)*
200   %gep.3 = getelementptr inbounds i32, i32* %src, i64 3
201   %gep.3.c = addrspacecast i32* %gep.3 to i16 addrspace(1) *
202   %c.min.0 = icmp ult i8 addrspace(1)* %src.c, %min.c
203   %c.max.3 = icmp ugt i16 addrspace(1)* %gep.3.c, %max.c
205   %or = or i1 %c.min.0, %c.max.3
206   br i1 %or, label %trap, label %checks
208 trap:
209   ret i1 0
211 checks:
212   %c.3.min = icmp ult i32* %gep.3, %min
213   %c.3.max = icmp ult i32* %gep.3, %max
214   %res.1 = xor i1 %c.3.min, %c.3.max
216   %gep.1 = getelementptr inbounds i32, i32* %src, i64 1
217   %c.1.min = icmp ult i32* %gep.1, %min
218   %c.1.max = icmp ult i32* %gep.1, %max
219   %res.2 = xor i1 %c.1.min, %c.1.max
221   %gep.2 = getelementptr inbounds i32, i32* %src, i64 2
222   %c.2.min = icmp ult i32* %gep.2, %min
223   %c.2.max = icmp ult i32* %gep.2, %max
224   %res.3 = xor i1 %c.2.min, %c.2.max
226   %gep.4 = getelementptr inbounds i32, i32* %src, i64 4
227   %c.4.min = icmp ult i32* %gep.4, %min
228   %c.4.max = icmp ult i32* %gep.4, %max
229   %res.4 = xor i1 %c.4.min, %c.4.max
231   %res.5 = xor i1 %res.1, %res.2
232   %res.6 = xor i1 %res.5, %res.3
233   %res.7 = xor i1 %res.6, %res.4
235   ret i1 %res.7