xref: /aosp_15_r20/external/llvm/test/Transforms/InstCombine/assume.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -instcombine -S | FileCheck %s
2*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-unknown-linux-gnu"
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind uwtable
6*9880d681SAndroid Build Coastguard Workerdefine i32 @foo1(i32* %a) #0 {
7*9880d681SAndroid Build Coastguard Workerentry:
8*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %a, align 4
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker; Check that the alignment has been upgraded and that the assume has not
11*9880d681SAndroid Build Coastguard Worker; been removed:
12*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @foo1
13*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: load i32, i32* %a, align 32
14*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: call void @llvm.assume
15*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Worker  %ptrint = ptrtoint i32* %a to i64
18*9880d681SAndroid Build Coastguard Worker  %maskedptr = and i64 %ptrint, 31
19*9880d681SAndroid Build Coastguard Worker  %maskcond = icmp eq i64 %maskedptr, 0
20*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %maskcond)
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Worker  ret i32 %0
23*9880d681SAndroid Build Coastguard Worker}
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind uwtable
26*9880d681SAndroid Build Coastguard Workerdefine i32 @foo2(i32* %a) #0 {
27*9880d681SAndroid Build Coastguard Workerentry:
28*9880d681SAndroid Build Coastguard Worker; Same check as in @foo1, but make sure it works if the assume is first too.
29*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @foo2
30*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: load i32, i32* %a, align 32
31*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: call void @llvm.assume
32*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker  %ptrint = ptrtoint i32* %a to i64
35*9880d681SAndroid Build Coastguard Worker  %maskedptr = and i64 %ptrint, 31
36*9880d681SAndroid Build Coastguard Worker  %maskcond = icmp eq i64 %maskedptr, 0
37*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %maskcond)
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %a, align 4
40*9880d681SAndroid Build Coastguard Worker  ret i32 %0
41*9880d681SAndroid Build Coastguard Worker}
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind
44*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.assume(i1) #1
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Workerdefine i32 @simple(i32 %a) #1 {
47*9880d681SAndroid Build Coastguard Workerentry:
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @simple
50*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume
51*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 4
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 4
54*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %cmp)
55*9880d681SAndroid Build Coastguard Worker  ret i32 %a
56*9880d681SAndroid Build Coastguard Worker}
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind uwtable
59*9880d681SAndroid Build Coastguard Workerdefine i32 @can1(i1 %a, i1 %b, i1 %c) {
60*9880d681SAndroid Build Coastguard Workerentry:
61*9880d681SAndroid Build Coastguard Worker  %and1 = and i1 %a, %b
62*9880d681SAndroid Build Coastguard Worker  %and  = and i1 %and1, %c
63*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %and)
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @can1
66*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume(i1 %a)
67*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume(i1 %b)
68*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume(i1 %c)
69*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker  ret i32 5
72*9880d681SAndroid Build Coastguard Worker}
73*9880d681SAndroid Build Coastguard Worker
74*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind uwtable
75*9880d681SAndroid Build Coastguard Workerdefine i32 @can2(i1 %a, i1 %b, i1 %c) {
76*9880d681SAndroid Build Coastguard Workerentry:
77*9880d681SAndroid Build Coastguard Worker  %v = or i1 %a, %b
78*9880d681SAndroid Build Coastguard Worker  %w = xor i1 %v, 1
79*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %w)
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @can2
82*9880d681SAndroid Build Coastguard Worker; CHECK: %[[V1:[^ ]+]] = xor i1 %a, true
83*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume(i1 %[[V1]])
84*9880d681SAndroid Build Coastguard Worker; CHECK: %[[V2:[^ ]+]] = xor i1 %b, true
85*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume(i1 %[[V2]])
86*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker  ret i32 5
89*9880d681SAndroid Build Coastguard Worker}
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Workerdefine i32 @bar1(i32 %a) #0 {
92*9880d681SAndroid Build Coastguard Workerentry:
93*9880d681SAndroid Build Coastguard Worker  %and1 = and i32 %a, 3
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @bar1
96*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume
97*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 1
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker  %and = and i32 %a, 7
100*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %and, 1
101*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %cmp)
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker  ret i32 %and1
104*9880d681SAndroid Build Coastguard Worker}
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind uwtable
107*9880d681SAndroid Build Coastguard Workerdefine i32 @bar2(i32 %a) #0 {
108*9880d681SAndroid Build Coastguard Workerentry:
109*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @bar2
110*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume
111*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 1
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker  %and = and i32 %a, 7
114*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %and, 1
115*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %cmp)
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker  %and1 = and i32 %a, 3
118*9880d681SAndroid Build Coastguard Worker  ret i32 %and1
119*9880d681SAndroid Build Coastguard Worker}
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind uwtable
122*9880d681SAndroid Build Coastguard Workerdefine i32 @bar3(i32 %a, i1 %x, i1 %y) #0 {
123*9880d681SAndroid Build Coastguard Workerentry:
124*9880d681SAndroid Build Coastguard Worker  %and1 = and i32 %a, 3
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker; Don't be fooled by other assumes around.
127*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @bar3
128*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume
129*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 1
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %x)
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker  %and = and i32 %a, 7
134*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %and, 1
135*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %cmp)
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %y)
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Worker  ret i32 %and1
140*9880d681SAndroid Build Coastguard Worker}
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind uwtable
143*9880d681SAndroid Build Coastguard Workerdefine i32 @bar4(i32 %a, i32 %b) {
144*9880d681SAndroid Build Coastguard Workerentry:
145*9880d681SAndroid Build Coastguard Worker  %and1 = and i32 %b, 3
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @bar4
148*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume
149*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume
150*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 1
151*9880d681SAndroid Build Coastguard Worker
152*9880d681SAndroid Build Coastguard Worker  %and = and i32 %a, 7
153*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %and, 1
154*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %cmp)
155*9880d681SAndroid Build Coastguard Worker
156*9880d681SAndroid Build Coastguard Worker  %cmp2 = icmp eq i32 %a, %b
157*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %cmp2)
158*9880d681SAndroid Build Coastguard Worker
159*9880d681SAndroid Build Coastguard Worker  ret i32 %and1
160*9880d681SAndroid Build Coastguard Worker}
161*9880d681SAndroid Build Coastguard Worker
162*9880d681SAndroid Build Coastguard Workerdefine i32 @icmp1(i32 %a) #0 {
163*9880d681SAndroid Build Coastguard Workerentry:
164*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sgt i32 %a, 5
165*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %cmp)
166*9880d681SAndroid Build Coastguard Worker  %conv = zext i1 %cmp to i32
167*9880d681SAndroid Build Coastguard Worker  ret i32 %conv
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @icmp1
170*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume
171*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 1
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker}
174*9880d681SAndroid Build Coastguard Worker
175*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind uwtable
176*9880d681SAndroid Build Coastguard Workerdefine i32 @icmp2(i32 %a) #0 {
177*9880d681SAndroid Build Coastguard Workerentry:
178*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sgt i32 %a, 5
179*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %cmp)
180*9880d681SAndroid Build Coastguard Worker  %0 = zext i1 %cmp to i32
181*9880d681SAndroid Build Coastguard Worker  %lnot.ext = xor i32 %0, 1
182*9880d681SAndroid Build Coastguard Worker  ret i32 %lnot.ext
183*9880d681SAndroid Build Coastguard Worker
184*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @icmp2
185*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume
186*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0
187*9880d681SAndroid Build Coastguard Worker}
188*9880d681SAndroid Build Coastguard Worker
189*9880d681SAndroid Build Coastguard Workerdeclare void @escape(i32* %a)
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker; Do we canonicalize a nonnull assumption on a load into
192*9880d681SAndroid Build Coastguard Worker; metadata form?
193*9880d681SAndroid Build Coastguard Workerdefine i1 @nonnull1(i32** %a) {
194*9880d681SAndroid Build Coastguard Workerentry:
195*9880d681SAndroid Build Coastguard Worker  %load = load i32*, i32** %a
196*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ne i32* %load, null
197*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %cmp)
198*9880d681SAndroid Build Coastguard Worker  tail call void @escape(i32* %load)
199*9880d681SAndroid Build Coastguard Worker  %rval = icmp eq i32* %load, null
200*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
201*9880d681SAndroid Build Coastguard Worker
202*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @nonnull1
203*9880d681SAndroid Build Coastguard Worker; CHECK: !nonnull
204*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: call void @llvm.assume
205*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 false
206*9880d681SAndroid Build Coastguard Worker}
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Worker; Make sure the above canonicalization applies only
209*9880d681SAndroid Build Coastguard Worker; to pointer types.  Doing otherwise would be illegal.
210*9880d681SAndroid Build Coastguard Workerdefine i1 @nonnull2(i32* %a) {
211*9880d681SAndroid Build Coastguard Workerentry:
212*9880d681SAndroid Build Coastguard Worker  %load = load i32, i32* %a
213*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ne i32 %load, 0
214*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %cmp)
215*9880d681SAndroid Build Coastguard Worker  %rval = icmp eq i32 %load, 0
216*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @nonnull2
219*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: !nonnull
220*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume
221*9880d681SAndroid Build Coastguard Worker}
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Worker; Make sure the above canonicalization does not trigger
224*9880d681SAndroid Build Coastguard Worker; if the assume is control dependent on something else
225*9880d681SAndroid Build Coastguard Workerdefine i1 @nonnull3(i32** %a, i1 %control) {
226*9880d681SAndroid Build Coastguard Workerentry:
227*9880d681SAndroid Build Coastguard Worker  %load = load i32*, i32** %a
228*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ne i32* %load, null
229*9880d681SAndroid Build Coastguard Worker  br i1 %control, label %taken, label %not_taken
230*9880d681SAndroid Build Coastguard Workertaken:
231*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %cmp)
232*9880d681SAndroid Build Coastguard Worker  %rval = icmp eq i32* %load, null
233*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
234*9880d681SAndroid Build Coastguard Workernot_taken:
235*9880d681SAndroid Build Coastguard Worker  ret i1 true
236*9880d681SAndroid Build Coastguard Worker
237*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @nonnull3
238*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: !nonnull
239*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume
240*9880d681SAndroid Build Coastguard Worker}
241*9880d681SAndroid Build Coastguard Worker
242*9880d681SAndroid Build Coastguard Worker; Make sure the above canonicalization does not trigger
243*9880d681SAndroid Build Coastguard Worker; if the path from the load to the assume is potentially
244*9880d681SAndroid Build Coastguard Worker; interrupted by an exception being thrown
245*9880d681SAndroid Build Coastguard Workerdefine i1 @nonnull4(i32** %a) {
246*9880d681SAndroid Build Coastguard Workerentry:
247*9880d681SAndroid Build Coastguard Worker  %load = load i32*, i32** %a
248*9880d681SAndroid Build Coastguard Worker  ;; This call may throw!
249*9880d681SAndroid Build Coastguard Worker  tail call void @escape(i32* %load)
250*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ne i32* %load, null
251*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %cmp)
252*9880d681SAndroid Build Coastguard Worker  %rval = icmp eq i32* %load, null
253*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
254*9880d681SAndroid Build Coastguard Worker
255*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @nonnull4
256*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: !nonnull
257*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.assume
258*9880d681SAndroid Build Coastguard Worker}
259*9880d681SAndroid Build Coastguard Worker
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Worker
262*9880d681SAndroid Build Coastguard Worker
263*9880d681SAndroid Build Coastguard Workerattributes #0 = { nounwind uwtable }
264*9880d681SAndroid Build Coastguard Workerattributes #1 = { nounwind }
265*9880d681SAndroid Build Coastguard Worker
266