Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstCombine / icmp-custom-dl.ll
bloba595ddb07db56612490a3b3fad8318856e461d06
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 target datalayout = "e-p:40:64:64:32-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
6 declare i32 @test58_d(i64 )
8 define i1 @test59(ptr %foo) {
9 ; CHECK-LABEL: @test59(
10 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[FOO:%.*]], i32 8
11 ; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[GEP1]] to i40
12 ; CHECK-NEXT:    [[USE:%.*]] = zext i40 [[TMP1]] to i64
13 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]])
14 ; CHECK-NEXT:    ret i1 true
16   %gep1 = getelementptr inbounds i32, ptr %foo, i64 2
17   %gep2 = getelementptr inbounds i8, ptr %foo, i64 10
18   %cmp = icmp ult ptr %gep1, %gep2
19   %use = ptrtoint ptr %gep1 to i64
20   %call = call i32 @test58_d(i64 %use)
21   ret i1 %cmp
24 define i1 @test59_as1(ptr addrspace(1) %foo) {
25 ; CHECK-LABEL: @test59_as1(
26 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[FOO:%.*]], i16 8
27 ; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[GEP1]] to i16
28 ; CHECK-NEXT:    [[USE:%.*]] = zext i16 [[TMP1]] to i64
29 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]])
30 ; CHECK-NEXT:    ret i1 true
32   %gep1 = getelementptr inbounds i32, ptr addrspace(1) %foo, i64 2
33   %gep2 = getelementptr inbounds i8, ptr addrspace(1) %foo, i64 10
34   %cmp = icmp ult ptr addrspace(1) %gep1, %gep2
35   %use = ptrtoint ptr addrspace(1) %gep1 to i64
36   %call = call i32 @test58_d(i64 %use)
37   ret i1 %cmp
40 define i1 @test60(ptr %foo, i64 %i, i64 %j) {
41 ; CHECK-LABEL: @test60(
42 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i32
43 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i32 [[TMP1]], 2
44 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[J:%.*]] to i32
45 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[GEP1_IDX]], [[TMP2]]
46 ; CHECK-NEXT:    ret i1 [[CMP]]
48   %gep1 = getelementptr inbounds i32, ptr %foo, i64 %i
49   %gep2 = getelementptr inbounds i8, ptr %foo, i64 %j
50   %cmp = icmp ult ptr %gep1, %gep2
51   ret i1 %cmp
54 define i1 @test60_as1(ptr addrspace(1) %foo, i64 %i, i64 %j) {
55 ; CHECK-LABEL: @test60_as1(
56 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i16
57 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i16 [[TMP1]], 2
58 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[J:%.*]] to i16
59 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP2]]
60 ; CHECK-NEXT:    ret i1 [[CMP]]
62   %gep1 = getelementptr inbounds i32, ptr addrspace(1) %foo, i64 %i
63   %gep2 = getelementptr inbounds i8, ptr addrspace(1) %foo, i64 %j
64   %cmp = icmp ult ptr addrspace(1) %gep1, %gep2
65   ret i1 %cmp
68 ; Same as test60, but look through an addrspacecast instead of a
69 ; bitcast. This uses the same sized addrspace.
70 define i1 @test60_addrspacecast(ptr %foo, i64 %i, i64 %j) {
71 ; CHECK-LABEL: @test60_addrspacecast(
72 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[J:%.*]] to i32
73 ; CHECK-NEXT:    [[I_TR:%.*]] = trunc i64 [[I:%.*]] to i32
74 ; CHECK-NEXT:    [[TMP2:%.*]] = shl i32 [[I_TR]], 2
75 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP2]], [[TMP1]]
76 ; CHECK-NEXT:    ret i1 [[CMP]]
78   %bit = addrspacecast ptr %foo to ptr addrspace(3)
79   %gep1 = getelementptr inbounds i32, ptr addrspace(3) %bit, i64 %i
80   %gep2 = getelementptr inbounds i8, ptr %foo, i64 %j
81   %cast1 = addrspacecast ptr addrspace(3) %gep1 to ptr
82   %cmp = icmp ult ptr %cast1, %gep2
83   ret i1 %cmp
86 define i1 @test60_addrspacecast_smaller(ptr %foo, i16 %i, i64 %j) {
87 ; CHECK-LABEL: @test60_addrspacecast_smaller(
88 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i16 [[I:%.*]], 2
89 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[J:%.*]] to i16
90 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP1]]
91 ; CHECK-NEXT:    ret i1 [[CMP]]
93   %bit = addrspacecast ptr %foo to ptr addrspace(1)
94   %gep1 = getelementptr inbounds i32, ptr addrspace(1) %bit, i16 %i
95   %gep2 = getelementptr inbounds i8, ptr %foo, i64 %j
96   %cast1 = addrspacecast ptr addrspace(1) %gep1 to ptr
97   %cmp = icmp ult ptr %cast1, %gep2
98   ret i1 %cmp
101 define i1 @test60_addrspacecast_larger(ptr addrspace(1) %foo, i32 %i, i16 %j) {
102 ; CHECK-LABEL: @test60_addrspacecast_larger(
103 ; CHECK-NEXT:    [[I_TR:%.*]] = trunc i32 [[I:%.*]] to i16
104 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i16 [[I_TR]], 2
105 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[TMP1]], [[J:%.*]]
106 ; CHECK-NEXT:    ret i1 [[CMP]]
108   %bit = addrspacecast ptr addrspace(1) %foo to ptr addrspace(2)
109   %gep1 = getelementptr inbounds i32, ptr addrspace(2) %bit, i32 %i
110   %gep2 = getelementptr inbounds i8, ptr addrspace(1) %foo, i16 %j
111   %cast1 = addrspacecast ptr addrspace(2) %gep1 to ptr addrspace(1)
112   %cmp = icmp ult ptr addrspace(1) %cast1, %gep2
113   ret i1 %cmp
116 define i1 @test61(ptr %foo, i64 %i, i64 %j) {
117 ; CHECK-LABEL: @test61(
118 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i32
119 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i32, ptr [[FOO:%.*]], i32 [[TMP1]]
120 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[J:%.*]] to i32
121 ; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i8, ptr [[FOO]], i32 [[TMP2]]
122 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult ptr [[GEP1]], [[GEP2]]
123 ; CHECK-NEXT:    ret i1 [[CMP]]
125   %gep1 = getelementptr i32, ptr %foo, i64 %i
126   %gep2 = getelementptr  i8,  ptr %foo, i64 %j
127   %cmp = icmp ult ptr %gep1, %gep2
128   ret i1 %cmp
129 ; Don't transform non-inbounds GEPs.
132 define i1 @test61_as1(ptr addrspace(1) %foo, i16 %i, i16 %j) {
133 ; CHECK-LABEL: @test61_as1(
134 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i32, ptr addrspace(1) [[FOO:%.*]], i16 [[I:%.*]]
135 ; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i8, ptr addrspace(1) [[FOO]], i16 [[J:%.*]]
136 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult ptr addrspace(1) [[GEP1]], [[GEP2]]
137 ; CHECK-NEXT:    ret i1 [[CMP]]
139   %gep1 = getelementptr i32, ptr addrspace(1) %foo, i16 %i
140   %gep2 = getelementptr i8, ptr addrspace(1) %foo, i16 %j
141   %cmp = icmp ult ptr addrspace(1) %gep1, %gep2
142   ret i1 %cmp
143 ; Don't transform non-inbounds GEPs.
146 ; Negative test: GEP inbounds may cross sign boundary.
147 define i1 @test62(ptr %a) {
148 ; CHECK-LABEL: @test62(
149 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i32 1
150 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[A]], i32 10
151 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt ptr [[ARRAYIDX1]], [[ARRAYIDX2]]
152 ; CHECK-NEXT:    ret i1 [[CMP]]
154   %arrayidx1 = getelementptr inbounds i8, ptr %a, i64 1
155   %arrayidx2 = getelementptr inbounds i8, ptr %a, i64 10
156   %cmp = icmp slt ptr %arrayidx1, %arrayidx2
157   ret i1 %cmp
160 define i1 @test62_as1(ptr addrspace(1) %a) {
161 ; CHECK-LABEL: @test62_as1(
162 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[A:%.*]], i16 1
163 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[A]], i16 10
164 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt ptr addrspace(1) [[ARRAYIDX1]], [[ARRAYIDX2]]
165 ; CHECK-NEXT:    ret i1 [[CMP]]
167   %arrayidx1 = getelementptr inbounds i8, ptr addrspace(1) %a, i64 1
168   %arrayidx2 = getelementptr inbounds i8, ptr addrspace(1) %a, i64 10
169   %cmp = icmp slt ptr addrspace(1) %arrayidx1, %arrayidx2
170   ret i1 %cmp
174 ; Variation of the above with an ashr
175 define i1 @icmp_and_ashr_multiuse(i32 %X) {
176 ; CHECK-LABEL: @icmp_and_ashr_multiuse(
177 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
178 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
179 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
180 ; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
181 ; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
182 ; CHECK-NEXT:    ret i1 [[AND3]]
184   %shr = ashr i32 %X, 4
185   %and = and i32 %shr, 15
186   %and2 = and i32 %shr, 31 ; second use of the shift
187   %tobool = icmp ne i32 %and, 14
188   %tobool2 = icmp ne i32 %and2, 27
189   %and3 = and i1 %tobool, %tobool2
190   ret i1 %and3
193 define i1 @icmp_and_ashr_multiuse_logical(i32 %X) {
194 ; CHECK-LABEL: @icmp_and_ashr_multiuse_logical(
195 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
196 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
197 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
198 ; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
199 ; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
200 ; CHECK-NEXT:    ret i1 [[AND3]]
202   %shr = ashr i32 %X, 4
203   %and = and i32 %shr, 15
204   %and2 = and i32 %shr, 31 ; second use of the shift
205   %tobool = icmp ne i32 %and, 14
206   %tobool2 = icmp ne i32 %and2, 27
207   %and3 = select i1 %tobool, i1 %tobool2, i1 false
208   ret i1 %and3
211 define i1 @icmp_lshr_and_overshift(i8 %X) {
212 ; CHECK-LABEL: @icmp_lshr_and_overshift(
213 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ugt i8 [[X:%.*]], 31
214 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
216   %shr = lshr i8 %X, 5
217   %and = and i8 %shr, 15
218   %tobool = icmp ne i8 %and, 0
219   ret i1 %tobool
222 ; We shouldn't simplify this because the and uses bits that are shifted in.
223 define i1 @icmp_ashr_and_overshift(i8 %X) {
224 ; CHECK-LABEL: @icmp_ashr_and_overshift(
225 ; CHECK-NEXT:    [[SHR:%.*]] = ashr i8 [[X:%.*]], 5
226 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[SHR]], 15
227 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[AND]], 0
228 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
230   %shr = ashr i8 %X, 5
231   %and = and i8 %shr, 15
232   %tobool = icmp ne i8 %and, 0
233   ret i1 %tobool
236 ; PR16244
237 define i1 @test71(ptr %x) {
238 ; CHECK-LABEL: @test71(
239 ; CHECK-NEXT:    ret i1 false
241   %a = getelementptr i8, ptr %x, i64 8
242   %b = getelementptr inbounds i8, ptr %x, i64 8
243   %c = icmp ugt ptr %a, %b
244   ret i1 %c
247 define i1 @test71_as1(ptr addrspace(1) %x) {
248 ; CHECK-LABEL: @test71_as1(
249 ; CHECK-NEXT:    ret i1 false
251   %a = getelementptr i8, ptr addrspace(1) %x, i64 8
252   %b = getelementptr inbounds i8, ptr addrspace(1) %x, i64 8
253   %c = icmp ugt ptr addrspace(1) %a, %b
254   ret i1 %c