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