xref: /aosp_15_r20/external/llvm/test/Transforms/InstCombine/compare-unescaped.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -instcombine -S < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker@gp = global i32* null, align 8
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Workerdeclare i8* @malloc(i64) #1
6*9880d681SAndroid Build Coastguard Worker
7*9880d681SAndroid Build Coastguard Workerdefine i1 @compare_global_trivialeq() {
8*9880d681SAndroid Build Coastguard Worker  %m = call i8* @malloc(i64 4)
9*9880d681SAndroid Build Coastguard Worker  %bc = bitcast i8* %m to i32*
10*9880d681SAndroid Build Coastguard Worker  %lgp = load i32*, i32** @gp, align 8
11*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32* %bc, %lgp
12*9880d681SAndroid Build Coastguard Worker  ret i1 %cmp
13*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: compare_global_trivialeq
14*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 false
15*9880d681SAndroid Build Coastguard Worker}
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Workerdefine i1 @compare_global_trivialne() {
18*9880d681SAndroid Build Coastguard Worker  %m = call i8* @malloc(i64 4)
19*9880d681SAndroid Build Coastguard Worker  %bc = bitcast i8* %m to i32*
20*9880d681SAndroid Build Coastguard Worker  %lgp = load i32*, i32** @gp, align 8
21*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ne i32* %bc, %lgp
22*9880d681SAndroid Build Coastguard Worker  ret i1 %cmp
23*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: compare_global_trivialne
24*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 true
25*9880d681SAndroid Build Coastguard Worker}
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker; Although the %m is marked nocapture in the deopt operand in call to function f,
29*9880d681SAndroid Build Coastguard Worker; we cannot remove the alloc site: call to malloc
30*9880d681SAndroid Build Coastguard Worker; The comparison should fold to false irrespective of whether the call to malloc can be elided or not
31*9880d681SAndroid Build Coastguard Workerdeclare void @f()
32*9880d681SAndroid Build Coastguard Workerdefine i1 @compare_and_call_with_deopt() {
33*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: compare_and_call_with_deopt
34*9880d681SAndroid Build Coastguard Worker  %m = call i8* @malloc(i64 24)
35*9880d681SAndroid Build Coastguard Worker  %bc = bitcast i8* %m to i32*
36*9880d681SAndroid Build Coastguard Worker  %lgp = load i32*, i32** @gp, align 8, !nonnull !0
37*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32* %lgp, %bc
38*9880d681SAndroid Build Coastguard Worker  tail call void @f() [ "deopt"(i8* %m) ]
39*9880d681SAndroid Build Coastguard Worker  ret i1 %cmp
40*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 false
41*9880d681SAndroid Build Coastguard Worker}
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker; Same functon as above with deopt operand in function f, but comparison is NE
44*9880d681SAndroid Build Coastguard Workerdefine i1 @compare_ne_and_call_with_deopt() {
45*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: compare_ne_and_call_with_deopt
46*9880d681SAndroid Build Coastguard Worker  %m = call i8* @malloc(i64 24)
47*9880d681SAndroid Build Coastguard Worker  %bc = bitcast i8* %m to i32*
48*9880d681SAndroid Build Coastguard Worker  %lgp = load i32*, i32** @gp, align 8, !nonnull !0
49*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ne i32* %lgp, %bc
50*9880d681SAndroid Build Coastguard Worker  tail call void @f() [ "deopt"(i8* %m) ]
51*9880d681SAndroid Build Coastguard Worker  ret i1 %cmp
52*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 true
53*9880d681SAndroid Build Coastguard Worker}
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker; Same function as above, but global not marked nonnull, and we cannot fold the comparison
56*9880d681SAndroid Build Coastguard Workerdefine i1 @compare_ne_global_maybe_null() {
57*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: compare_ne_global_maybe_null
58*9880d681SAndroid Build Coastguard Worker  %m = call i8* @malloc(i64 24)
59*9880d681SAndroid Build Coastguard Worker  %bc = bitcast i8* %m to i32*
60*9880d681SAndroid Build Coastguard Worker  %lgp = load i32*, i32** @gp
61*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ne i32* %lgp, %bc
62*9880d681SAndroid Build Coastguard Worker  tail call void @f() [ "deopt"(i8* %m) ]
63*9880d681SAndroid Build Coastguard Worker  ret i1 %cmp
64*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 %cmp
65*9880d681SAndroid Build Coastguard Worker}
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker; FIXME: The comparison should fold to false since %m escapes (call to function escape)
68*9880d681SAndroid Build Coastguard Worker; after the comparison.
69*9880d681SAndroid Build Coastguard Workerdeclare void @escape(i8*)
70*9880d681SAndroid Build Coastguard Workerdefine i1 @compare_and_call_after() {
71*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: compare_and_call_after
72*9880d681SAndroid Build Coastguard Worker  %m = call i8* @malloc(i64 24)
73*9880d681SAndroid Build Coastguard Worker  %bc = bitcast i8* %m to i32*
74*9880d681SAndroid Build Coastguard Worker  %lgp = load i32*, i32** @gp, align 8, !nonnull !0
75*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32* %bc, %lgp
76*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %escape_call, label %just_return
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Workerescape_call:
79*9880d681SAndroid Build Coastguard Worker call void @escape(i8* %m)
80*9880d681SAndroid Build Coastguard Worker ret i1 true
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Workerjust_return:
83*9880d681SAndroid Build Coastguard Worker ret i1 %cmp
84*9880d681SAndroid Build Coastguard Worker}
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Workerdefine i1 @compare_distinct_mallocs() {
87*9880d681SAndroid Build Coastguard Worker  %m = call i8* @malloc(i64 4)
88*9880d681SAndroid Build Coastguard Worker  %n = call i8* @malloc(i64 4)
89*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i8* %m, %n
90*9880d681SAndroid Build Coastguard Worker  ret i1 %cmp
91*9880d681SAndroid Build Coastguard Worker  ; CHECK-LABEL: compare_distinct_mallocs
92*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i1 false
93*9880d681SAndroid Build Coastguard Worker}
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker; the compare is folded to true since the folding compare looks through bitcasts.
96*9880d681SAndroid Build Coastguard Worker; call to malloc and the bitcast instructions are elided after that since there are no uses of the malloc
97*9880d681SAndroid Build Coastguard Workerdefine i1 @compare_samepointer_under_bitcast() {
98*9880d681SAndroid Build Coastguard Worker  %m = call i8* @malloc(i64 4)
99*9880d681SAndroid Build Coastguard Worker  %bc = bitcast i8* %m to i32*
100*9880d681SAndroid Build Coastguard Worker  %bcback = bitcast i32* %bc to i8*
101*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i8* %m, %bcback
102*9880d681SAndroid Build Coastguard Worker  ret i1 %cmp
103*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: compare_samepointer_under_bitcast
104*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 true
105*9880d681SAndroid Build Coastguard Worker}
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Worker; the compare is folded to true since the folding compare looks through bitcasts.
108*9880d681SAndroid Build Coastguard Worker; The malloc call for %m cannot be elided since it is used in the call to function f.
109*9880d681SAndroid Build Coastguard Workerdefine i1 @compare_samepointer_escaped() {
110*9880d681SAndroid Build Coastguard Worker  %m = call i8* @malloc(i64 4)
111*9880d681SAndroid Build Coastguard Worker  %bc = bitcast i8* %m to i32*
112*9880d681SAndroid Build Coastguard Worker  %bcback = bitcast i32* %bc to i8*
113*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i8* %m, %bcback
114*9880d681SAndroid Build Coastguard Worker  call void @f() [ "deopt"(i8* %m) ]
115*9880d681SAndroid Build Coastguard Worker  ret i1 %cmp
116*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: compare_samepointer_escaped
117*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %m = call i8* @malloc(i64 4)
118*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @f() [ "deopt"(i8* %m) ]
119*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 true
120*9880d681SAndroid Build Coastguard Worker}
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Worker; Technically, we can fold the %cmp2 comparison, even though %m escapes through
123*9880d681SAndroid Build Coastguard Worker; the ret statement since `ret` terminates the function and we cannot reach from
124*9880d681SAndroid Build Coastguard Worker; the ret to cmp.
125*9880d681SAndroid Build Coastguard Worker; FIXME: Folding this %cmp2 when %m escapes through ret could be an issue with
126*9880d681SAndroid Build Coastguard Worker; cross-threading data dependencies since we do not make the distinction between
127*9880d681SAndroid Build Coastguard Worker; atomic and non-atomic loads in capture tracking.
128*9880d681SAndroid Build Coastguard Workerdefine i8* @compare_ret_escape(i8* %c) {
129*9880d681SAndroid Build Coastguard Worker  %m = call i8* @malloc(i64 4)
130*9880d681SAndroid Build Coastguard Worker  %n = call i8* @malloc(i64 4)
131*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i8* %n, %c
132*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %retst, label %chk
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Workerretst:
135*9880d681SAndroid Build Coastguard Worker  ret i8* %m
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Workerchk:
138*9880d681SAndroid Build Coastguard Worker  %bc = bitcast i8* %m to i32*
139*9880d681SAndroid Build Coastguard Worker  %lgp = load i32*, i32** @gp, align 8, !nonnull !0
140*9880d681SAndroid Build Coastguard Worker  %cmp2 = icmp eq i32* %bc, %lgp
141*9880d681SAndroid Build Coastguard Worker  br i1 %cmp2, label %retst,  label %chk2
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Workerchk2:
144*9880d681SAndroid Build Coastguard Worker  ret i8* %n
145*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: compare_ret_escape
146*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp = icmp eq i8* %n, %c
147*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp2 = icmp eq i32* %bc, %lgp
148*9880d681SAndroid Build Coastguard Worker}
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Worker; The malloc call for %m cannot be elided since it is used in the call to function f.
151*9880d681SAndroid Build Coastguard Worker; However, the cmp can be folded to true as %n doesnt escape and %m, %n are distinct allocations
152*9880d681SAndroid Build Coastguard Workerdefine i1 @compare_distinct_pointer_escape() {
153*9880d681SAndroid Build Coastguard Worker  %m = call i8* @malloc(i64 4)
154*9880d681SAndroid Build Coastguard Worker  %n = call i8* @malloc(i64 4)
155*9880d681SAndroid Build Coastguard Worker  tail call void @f() [ "deopt"(i8* %m) ]
156*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ne i8* %m, %n
157*9880d681SAndroid Build Coastguard Worker  ret i1 %cmp
158*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: compare_distinct_pointer_escape
159*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %m = call i8* @malloc(i64 4)
160*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tail call void @f() [ "deopt"(i8* %m) ]
161*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i1 true
162*9880d681SAndroid Build Coastguard Worker}
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker!0 = !{}
165