1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -functionattrs -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker@g = global i32* null ; <i32**> [#uses=1] 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker; CHECK: define i32* @c1(i32* readnone %q) 5*9880d681SAndroid Build Coastguard Workerdefine i32* @c1(i32* %q) { 6*9880d681SAndroid Build Coastguard Worker ret i32* %q 7*9880d681SAndroid Build Coastguard Worker} 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Worker; CHECK: define void @c2(i32* %q) 10*9880d681SAndroid Build Coastguard Worker; It would also be acceptable to mark %q as readnone. Update @c3 too. 11*9880d681SAndroid Build Coastguard Workerdefine void @c2(i32* %q) { 12*9880d681SAndroid Build Coastguard Worker store i32* %q, i32** @g 13*9880d681SAndroid Build Coastguard Worker ret void 14*9880d681SAndroid Build Coastguard Worker} 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Worker; CHECK: define void @c3(i32* %q) 17*9880d681SAndroid Build Coastguard Workerdefine void @c3(i32* %q) { 18*9880d681SAndroid Build Coastguard Worker call void @c2(i32* %q) 19*9880d681SAndroid Build Coastguard Worker ret void 20*9880d681SAndroid Build Coastguard Worker} 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Worker; CHECK: define i1 @c4(i32* %q, i32 %bitno) 23*9880d681SAndroid Build Coastguard Workerdefine i1 @c4(i32* %q, i32 %bitno) { 24*9880d681SAndroid Build Coastguard Worker %tmp = ptrtoint i32* %q to i32 25*9880d681SAndroid Build Coastguard Worker %tmp2 = lshr i32 %tmp, %bitno 26*9880d681SAndroid Build Coastguard Worker %bit = trunc i32 %tmp2 to i1 27*9880d681SAndroid Build Coastguard Worker br i1 %bit, label %l1, label %l0 28*9880d681SAndroid Build Coastguard Workerl0: 29*9880d681SAndroid Build Coastguard Worker ret i1 0 ; escaping value not caught by def-use chaining. 30*9880d681SAndroid Build Coastguard Workerl1: 31*9880d681SAndroid Build Coastguard Worker ret i1 1 ; escaping value not caught by def-use chaining. 32*9880d681SAndroid Build Coastguard Worker} 33*9880d681SAndroid Build Coastguard Worker 34*9880d681SAndroid Build Coastguard Worker@lookup_table = global [2 x i1] [ i1 0, i1 1 ] 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker; CHECK: define i1 @c5(i32* %q, i32 %bitno) 37*9880d681SAndroid Build Coastguard Workerdefine i1 @c5(i32* %q, i32 %bitno) { 38*9880d681SAndroid Build Coastguard Worker %tmp = ptrtoint i32* %q to i32 39*9880d681SAndroid Build Coastguard Worker %tmp2 = lshr i32 %tmp, %bitno 40*9880d681SAndroid Build Coastguard Worker %bit = and i32 %tmp2, 1 41*9880d681SAndroid Build Coastguard Worker ; subtle escape mechanism follows 42*9880d681SAndroid Build Coastguard Worker %lookup = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0, i32 %bit 43*9880d681SAndroid Build Coastguard Worker %val = load i1, i1* %lookup 44*9880d681SAndroid Build Coastguard Worker ret i1 %val 45*9880d681SAndroid Build Coastguard Worker} 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Workerdeclare void @throw_if_bit_set(i8*, i8) readonly 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker; CHECK: define i1 @c6(i8* readonly %q, i8 %bit) 50*9880d681SAndroid Build Coastguard Workerdefine i1 @c6(i8* %q, i8 %bit) personality i32 (...)* @__gxx_personality_v0 { 51*9880d681SAndroid Build Coastguard Worker invoke void @throw_if_bit_set(i8* %q, i8 %bit) 52*9880d681SAndroid Build Coastguard Worker to label %ret0 unwind label %ret1 53*9880d681SAndroid Build Coastguard Workerret0: 54*9880d681SAndroid Build Coastguard Worker ret i1 0 55*9880d681SAndroid Build Coastguard Workerret1: 56*9880d681SAndroid Build Coastguard Worker %exn = landingpad {i8*, i32} 57*9880d681SAndroid Build Coastguard Worker cleanup 58*9880d681SAndroid Build Coastguard Worker ret i1 1 59*9880d681SAndroid Build Coastguard Worker} 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Workerdeclare i32 @__gxx_personality_v0(...) 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Workerdefine i1* @lookup_bit(i32* %q, i32 %bitno) readnone nounwind { 64*9880d681SAndroid Build Coastguard Worker %tmp = ptrtoint i32* %q to i32 65*9880d681SAndroid Build Coastguard Worker %tmp2 = lshr i32 %tmp, %bitno 66*9880d681SAndroid Build Coastguard Worker %bit = and i32 %tmp2, 1 67*9880d681SAndroid Build Coastguard Worker %lookup = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0, i32 %bit 68*9880d681SAndroid Build Coastguard Worker ret i1* %lookup 69*9880d681SAndroid Build Coastguard Worker} 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Worker; CHECK: define i1 @c7(i32* readonly %q, i32 %bitno) 72*9880d681SAndroid Build Coastguard Workerdefine i1 @c7(i32* %q, i32 %bitno) { 73*9880d681SAndroid Build Coastguard Worker %ptr = call i1* @lookup_bit(i32* %q, i32 %bitno) 74*9880d681SAndroid Build Coastguard Worker %val = load i1, i1* %ptr 75*9880d681SAndroid Build Coastguard Worker ret i1 %val 76*9880d681SAndroid Build Coastguard Worker} 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Worker; CHECK: define i32 @nc1(i32* %q, i32* nocapture %p, i1 %b) 80*9880d681SAndroid Build Coastguard Workerdefine i32 @nc1(i32* %q, i32* %p, i1 %b) { 81*9880d681SAndroid Build Coastguard Workere: 82*9880d681SAndroid Build Coastguard Worker br label %l 83*9880d681SAndroid Build Coastguard Workerl: 84*9880d681SAndroid Build Coastguard Worker %x = phi i32* [ %p, %e ] 85*9880d681SAndroid Build Coastguard Worker %y = phi i32* [ %q, %e ] 86*9880d681SAndroid Build Coastguard Worker %tmp = bitcast i32* %x to i32* ; <i32*> [#uses=2] 87*9880d681SAndroid Build Coastguard Worker %tmp2 = select i1 %b, i32* %tmp, i32* %y 88*9880d681SAndroid Build Coastguard Worker %val = load i32, i32* %tmp2 ; <i32> [#uses=1] 89*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %tmp 90*9880d681SAndroid Build Coastguard Worker store i32* %y, i32** @g 91*9880d681SAndroid Build Coastguard Worker ret i32 %val 92*9880d681SAndroid Build Coastguard Worker} 93*9880d681SAndroid Build Coastguard Worker 94*9880d681SAndroid Build Coastguard Worker; CHECK: define i32 @nc1_addrspace(i32* %q, i32 addrspace(1)* nocapture %p, i1 %b) 95*9880d681SAndroid Build Coastguard Workerdefine i32 @nc1_addrspace(i32* %q, i32 addrspace(1)* %p, i1 %b) { 96*9880d681SAndroid Build Coastguard Workere: 97*9880d681SAndroid Build Coastguard Worker br label %l 98*9880d681SAndroid Build Coastguard Workerl: 99*9880d681SAndroid Build Coastguard Worker %x = phi i32 addrspace(1)* [ %p, %e ] 100*9880d681SAndroid Build Coastguard Worker %y = phi i32* [ %q, %e ] 101*9880d681SAndroid Build Coastguard Worker %tmp = addrspacecast i32 addrspace(1)* %x to i32* ; <i32*> [#uses=2] 102*9880d681SAndroid Build Coastguard Worker %tmp2 = select i1 %b, i32* %tmp, i32* %y 103*9880d681SAndroid Build Coastguard Worker %val = load i32, i32* %tmp2 ; <i32> [#uses=1] 104*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %tmp 105*9880d681SAndroid Build Coastguard Worker store i32* %y, i32** @g 106*9880d681SAndroid Build Coastguard Worker ret i32 %val 107*9880d681SAndroid Build Coastguard Worker} 108*9880d681SAndroid Build Coastguard Worker 109*9880d681SAndroid Build Coastguard Worker; CHECK: define void @nc2(i32* nocapture %p, i32* %q) 110*9880d681SAndroid Build Coastguard Workerdefine void @nc2(i32* %p, i32* %q) { 111*9880d681SAndroid Build Coastguard Worker %1 = call i32 @nc1(i32* %q, i32* %p, i1 0) ; <i32> [#uses=0] 112*9880d681SAndroid Build Coastguard Worker ret void 113*9880d681SAndroid Build Coastguard Worker} 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Worker; CHECK: define void @nc3(void ()* nocapture %p) 116*9880d681SAndroid Build Coastguard Workerdefine void @nc3(void ()* %p) { 117*9880d681SAndroid Build Coastguard Worker call void %p() 118*9880d681SAndroid Build Coastguard Worker ret void 119*9880d681SAndroid Build Coastguard Worker} 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Workerdeclare void @external(i8*) readonly nounwind 122*9880d681SAndroid Build Coastguard Worker; CHECK: define void @nc4(i8* nocapture readonly %p) 123*9880d681SAndroid Build Coastguard Workerdefine void @nc4(i8* %p) { 124*9880d681SAndroid Build Coastguard Worker call void @external(i8* %p) 125*9880d681SAndroid Build Coastguard Worker ret void 126*9880d681SAndroid Build Coastguard Worker} 127*9880d681SAndroid Build Coastguard Worker 128*9880d681SAndroid Build Coastguard Worker; CHECK: define void @nc5(void (i8*)* nocapture %f, i8* nocapture %p) 129*9880d681SAndroid Build Coastguard Workerdefine void @nc5(void (i8*)* %f, i8* %p) { 130*9880d681SAndroid Build Coastguard Worker call void %f(i8* %p) readonly nounwind 131*9880d681SAndroid Build Coastguard Worker call void %f(i8* nocapture %p) 132*9880d681SAndroid Build Coastguard Worker ret void 133*9880d681SAndroid Build Coastguard Worker} 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1_1(i8* nocapture readnone %x1_1, i8* %y1_1) 136*9880d681SAndroid Build Coastguard Worker; It would be acceptable to add readnone to %y1_1 and %y1_2. 137*9880d681SAndroid Build Coastguard Workerdefine void @test1_1(i8* %x1_1, i8* %y1_1) { 138*9880d681SAndroid Build Coastguard Worker call i8* @test1_2(i8* %x1_1, i8* %y1_1) 139*9880d681SAndroid Build Coastguard Worker store i32* null, i32** @g 140*9880d681SAndroid Build Coastguard Worker ret void 141*9880d681SAndroid Build Coastguard Worker} 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Worker; CHECK: define i8* @test1_2(i8* nocapture readnone %x1_2, i8* %y1_2) 144*9880d681SAndroid Build Coastguard Workerdefine i8* @test1_2(i8* %x1_2, i8* %y1_2) { 145*9880d681SAndroid Build Coastguard Worker call void @test1_1(i8* %x1_2, i8* %y1_2) 146*9880d681SAndroid Build Coastguard Worker store i32* null, i32** @g 147*9880d681SAndroid Build Coastguard Worker ret i8* %y1_2 148*9880d681SAndroid Build Coastguard Worker} 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test2(i8* nocapture readnone %x2) 151*9880d681SAndroid Build Coastguard Workerdefine void @test2(i8* %x2) { 152*9880d681SAndroid Build Coastguard Worker call void @test2(i8* %x2) 153*9880d681SAndroid Build Coastguard Worker store i32* null, i32** @g 154*9880d681SAndroid Build Coastguard Worker ret void 155*9880d681SAndroid Build Coastguard Worker} 156*9880d681SAndroid Build Coastguard Worker 157*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test3(i8* nocapture readnone %x3, i8* nocapture readnone %y3, i8* nocapture readnone %z3) 158*9880d681SAndroid Build Coastguard Workerdefine void @test3(i8* %x3, i8* %y3, i8* %z3) { 159*9880d681SAndroid Build Coastguard Worker call void @test3(i8* %z3, i8* %y3, i8* %x3) 160*9880d681SAndroid Build Coastguard Worker store i32* null, i32** @g 161*9880d681SAndroid Build Coastguard Worker ret void 162*9880d681SAndroid Build Coastguard Worker} 163*9880d681SAndroid Build Coastguard Worker 164*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test4_1(i8* %x4_1) 165*9880d681SAndroid Build Coastguard Workerdefine void @test4_1(i8* %x4_1) { 166*9880d681SAndroid Build Coastguard Worker call i8* @test4_2(i8* %x4_1, i8* %x4_1, i8* %x4_1) 167*9880d681SAndroid Build Coastguard Worker store i32* null, i32** @g 168*9880d681SAndroid Build Coastguard Worker ret void 169*9880d681SAndroid Build Coastguard Worker} 170*9880d681SAndroid Build Coastguard Worker 171*9880d681SAndroid Build Coastguard Worker; CHECK: define i8* @test4_2(i8* nocapture readnone %x4_2, i8* readnone %y4_2, i8* nocapture readnone %z4_2) 172*9880d681SAndroid Build Coastguard Workerdefine i8* @test4_2(i8* %x4_2, i8* %y4_2, i8* %z4_2) { 173*9880d681SAndroid Build Coastguard Worker call void @test4_1(i8* null) 174*9880d681SAndroid Build Coastguard Worker store i32* null, i32** @g 175*9880d681SAndroid Build Coastguard Worker ret i8* %y4_2 176*9880d681SAndroid Build Coastguard Worker} 177*9880d681SAndroid Build Coastguard Worker 178*9880d681SAndroid Build Coastguard Workerdeclare i8* @test5_1(i8* %x5_1) 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test5_2(i8* %x5_2) 181*9880d681SAndroid Build Coastguard Workerdefine void @test5_2(i8* %x5_2) { 182*9880d681SAndroid Build Coastguard Worker call i8* @test5_1(i8* %x5_2) 183*9880d681SAndroid Build Coastguard Worker store i32* null, i32** @g 184*9880d681SAndroid Build Coastguard Worker ret void 185*9880d681SAndroid Build Coastguard Worker} 186*9880d681SAndroid Build Coastguard Worker 187*9880d681SAndroid Build Coastguard Workerdeclare void @test6_1(i8* %x6_1, i8* nocapture %y6_1, ...) 188*9880d681SAndroid Build Coastguard Worker 189*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test6_2(i8* %x6_2, i8* nocapture %y6_2, i8* %z6_2) 190*9880d681SAndroid Build Coastguard Workerdefine void @test6_2(i8* %x6_2, i8* %y6_2, i8* %z6_2) { 191*9880d681SAndroid Build Coastguard Worker call void (i8*, i8*, ...) @test6_1(i8* %x6_2, i8* %y6_2, i8* %z6_2) 192*9880d681SAndroid Build Coastguard Worker store i32* null, i32** @g 193*9880d681SAndroid Build Coastguard Worker ret void 194*9880d681SAndroid Build Coastguard Worker} 195*9880d681SAndroid Build Coastguard Worker 196*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test_cmpxchg(i32* nocapture %p) 197*9880d681SAndroid Build Coastguard Workerdefine void @test_cmpxchg(i32* %p) { 198*9880d681SAndroid Build Coastguard Worker cmpxchg i32* %p, i32 0, i32 1 acquire monotonic 199*9880d681SAndroid Build Coastguard Worker ret void 200*9880d681SAndroid Build Coastguard Worker} 201*9880d681SAndroid Build Coastguard Worker 202*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test_cmpxchg_ptr(i32** nocapture %p, i32* %q) 203*9880d681SAndroid Build Coastguard Workerdefine void @test_cmpxchg_ptr(i32** %p, i32* %q) { 204*9880d681SAndroid Build Coastguard Worker cmpxchg i32** %p, i32* null, i32* %q acquire monotonic 205*9880d681SAndroid Build Coastguard Worker ret void 206*9880d681SAndroid Build Coastguard Worker} 207*9880d681SAndroid Build Coastguard Worker 208*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test_atomicrmw(i32* nocapture %p) 209*9880d681SAndroid Build Coastguard Workerdefine void @test_atomicrmw(i32* %p) { 210*9880d681SAndroid Build Coastguard Worker atomicrmw add i32* %p, i32 1 seq_cst 211*9880d681SAndroid Build Coastguard Worker ret void 212*9880d681SAndroid Build Coastguard Worker} 213*9880d681SAndroid Build Coastguard Worker 214*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test_volatile(i32* %x) 215*9880d681SAndroid Build Coastguard Workerdefine void @test_volatile(i32* %x) { 216*9880d681SAndroid Build Coastguard Workerentry: 217*9880d681SAndroid Build Coastguard Worker %gep = getelementptr i32, i32* %x, i64 1 218*9880d681SAndroid Build Coastguard Worker store volatile i32 0, i32* %gep, align 4 219*9880d681SAndroid Build Coastguard Worker ret void 220*9880d681SAndroid Build Coastguard Worker} 221