1*9880d681SAndroid Build Coastguard Worker; RUN: opt -print-memderefs -analyze -S <%s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; Uses the print-deref (+ analyze to print) pass to run 4*9880d681SAndroid Build Coastguard Worker; isDereferenceablePointer() on many load instruction operands 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-i32:32:64" 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Worker%TypeOpaque = type opaque 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Workerdeclare zeroext i1 @return_i1() 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Workerdeclare i32* @foo() 13*9880d681SAndroid Build Coastguard Worker@globalstr = global [6 x i8] c"hello\00" 14*9880d681SAndroid Build Coastguard Worker@globali32ptr = external global i32* 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Worker%struct.A = type { [8 x i8], [5 x i8] } 17*9880d681SAndroid Build Coastguard Worker@globalstruct = external global %struct.A 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Worker@globalptr.align1 = external global i8, align 1 20*9880d681SAndroid Build Coastguard Worker@globalptr.align16 = external global i8, align 16 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: 'test' 23*9880d681SAndroid Build Coastguard Workerdefine void @test(i32 addrspace(1)* dereferenceable(8) %dparam, 24*9880d681SAndroid Build Coastguard Worker i8 addrspace(1)* dereferenceable(32) align 1 %dparam.align1, 25*9880d681SAndroid Build Coastguard Worker i8 addrspace(1)* dereferenceable(32) align 16 %dparam.align16) 26*9880d681SAndroid Build Coastguard Worker gc "statepoint-example" { 27*9880d681SAndroid Build Coastguard Worker; CHECK: The following are dereferenceable: 28*9880d681SAndroid Build Coastguard Workerentry: 29*9880d681SAndroid Build Coastguard Worker; CHECK: %globalptr{{.*}}(aligned) 30*9880d681SAndroid Build Coastguard Worker %globalptr = getelementptr inbounds [6 x i8], [6 x i8]* @globalstr, i32 0, i32 0 31*9880d681SAndroid Build Coastguard Worker %load1 = load i8, i8* %globalptr 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker; CHECK: %alloca{{.*}}(aligned) 34*9880d681SAndroid Build Coastguard Worker %alloca = alloca i1 35*9880d681SAndroid Build Coastguard Worker %load2 = load i1, i1* %alloca 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Worker; CHECK: %dparam{{.*}}(aligned) 38*9880d681SAndroid Build Coastguard Worker %load3 = load i32, i32 addrspace(1)* %dparam 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker; CHECK: %relocate{{.*}}(aligned) 41*9880d681SAndroid Build Coastguard Worker %tok = tail call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %dparam) 42*9880d681SAndroid Build Coastguard Worker %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 7, i32 7) 43*9880d681SAndroid Build Coastguard Worker %load4 = load i32, i32 addrspace(1)* %relocate 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %nparam 46*9880d681SAndroid Build Coastguard Worker %dpa = call i32 addrspace(1)* @func1(i32 addrspace(1)* %dparam) 47*9880d681SAndroid Build Coastguard Worker %nparam = getelementptr i32, i32 addrspace(1)* %dpa, i32 5 48*9880d681SAndroid Build Coastguard Worker %load5 = load i32, i32 addrspace(1)* %nparam 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker ; Load from a non-dereferenceable load 51*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %nd_load 52*9880d681SAndroid Build Coastguard Worker %nd_load = load i32*, i32** @globali32ptr 53*9880d681SAndroid Build Coastguard Worker %load6 = load i32, i32* %nd_load 54*9880d681SAndroid Build Coastguard Worker 55*9880d681SAndroid Build Coastguard Worker ; Load from a dereferenceable load 56*9880d681SAndroid Build Coastguard Worker; CHECK: %d4_load{{.*}}(aligned) 57*9880d681SAndroid Build Coastguard Worker %d4_load = load i32*, i32** @globali32ptr, !dereferenceable !0 58*9880d681SAndroid Build Coastguard Worker %load7 = load i32, i32* %d4_load 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Worker ; Load from an offset not covered by the dereferenceable portion 61*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %d2_load 62*9880d681SAndroid Build Coastguard Worker %d2_load = load i32*, i32** @globali32ptr, !dereferenceable !1 63*9880d681SAndroid Build Coastguard Worker %load8 = load i32, i32* %d2_load 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker ; Load from a potentially null pointer with dereferenceable_or_null 66*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %d_or_null_load 67*9880d681SAndroid Build Coastguard Worker %d_or_null_load = load i32*, i32** @globali32ptr, !dereferenceable_or_null !0 68*9880d681SAndroid Build Coastguard Worker %load9 = load i32, i32* %d_or_null_load 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Worker ; Load from a non-null pointer with dereferenceable_or_null 71*9880d681SAndroid Build Coastguard Worker; CHECK: %d_or_null_non_null_load{{.*}}(aligned) 72*9880d681SAndroid Build Coastguard Worker %d_or_null_non_null_load = load i32*, i32** @globali32ptr, !nonnull !2, !dereferenceable_or_null !0 73*9880d681SAndroid Build Coastguard Worker %load10 = load i32, i32* %d_or_null_non_null_load 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Worker ; It's OK to overrun static array size as long as we stay within underlying object size 76*9880d681SAndroid Build Coastguard Worker; CHECK: %within_allocation{{.*}}(aligned) 77*9880d681SAndroid Build Coastguard Worker %within_allocation = getelementptr inbounds %struct.A, %struct.A* @globalstruct, i64 0, i32 0, i64 10 78*9880d681SAndroid Build Coastguard Worker %load11 = load i8, i8* %within_allocation 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker ; GEP is outside the underlying object size 81*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %outside_allocation 82*9880d681SAndroid Build Coastguard Worker %outside_allocation = getelementptr inbounds %struct.A, %struct.A* @globalstruct, i64 0, i32 1, i64 10 83*9880d681SAndroid Build Coastguard Worker %load12 = load i8, i8* %outside_allocation 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Worker ; Loads from aligned globals 86*9880d681SAndroid Build Coastguard Worker; CHECK: @globalptr.align1{{.*}}(unaligned) 87*9880d681SAndroid Build Coastguard Worker; CHECK: @globalptr.align16{{.*}}(aligned) 88*9880d681SAndroid Build Coastguard Worker %load13 = load i8, i8* @globalptr.align1, align 16 89*9880d681SAndroid Build Coastguard Worker %load14 = load i8, i8* @globalptr.align16, align 16 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard Worker ; Loads from aligned arguments 92*9880d681SAndroid Build Coastguard Worker; CHECK: %dparam.align1{{.*}}(unaligned) 93*9880d681SAndroid Build Coastguard Worker; CHECK: %dparam.align16{{.*}}(aligned) 94*9880d681SAndroid Build Coastguard Worker %load15 = load i8, i8 addrspace(1)* %dparam.align1, align 16 95*9880d681SAndroid Build Coastguard Worker %load16 = load i8, i8 addrspace(1)* %dparam.align16, align 16 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard Worker ; Loads from aligned allocas 98*9880d681SAndroid Build Coastguard Worker; CHECK: %alloca.align1{{.*}}(unaligned) 99*9880d681SAndroid Build Coastguard Worker; CHECK: %alloca.align16{{.*}}(aligned) 100*9880d681SAndroid Build Coastguard Worker %alloca.align1 = alloca i1, align 1 101*9880d681SAndroid Build Coastguard Worker %alloca.align16 = alloca i1, align 16 102*9880d681SAndroid Build Coastguard Worker %load17 = load i1, i1* %alloca.align1, align 16 103*9880d681SAndroid Build Coastguard Worker %load18 = load i1, i1* %alloca.align16, align 16 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Worker ; Loads from GEPs 106*9880d681SAndroid Build Coastguard Worker; CHECK: %gep.align1.offset1{{.*}}(unaligned) 107*9880d681SAndroid Build Coastguard Worker; CHECK: %gep.align16.offset1{{.*}}(unaligned) 108*9880d681SAndroid Build Coastguard Worker; CHECK: %gep.align1.offset16{{.*}}(unaligned) 109*9880d681SAndroid Build Coastguard Worker; CHECK: %gep.align16.offset16{{.*}}(aligned) 110*9880d681SAndroid Build Coastguard Worker %gep.align1.offset1 = getelementptr inbounds i8, i8 addrspace(1)* %dparam.align1, i32 1 111*9880d681SAndroid Build Coastguard Worker %gep.align16.offset1 = getelementptr inbounds i8, i8 addrspace(1)* %dparam.align16, i32 1 112*9880d681SAndroid Build Coastguard Worker %gep.align1.offset16 = getelementptr inbounds i8, i8 addrspace(1)* %dparam.align1, i32 16 113*9880d681SAndroid Build Coastguard Worker %gep.align16.offset16 = getelementptr inbounds i8, i8 addrspace(1)* %dparam.align16, i32 16 114*9880d681SAndroid Build Coastguard Worker %load19 = load i8, i8 addrspace(1)* %gep.align1.offset1, align 16 115*9880d681SAndroid Build Coastguard Worker %load20 = load i8, i8 addrspace(1)* %gep.align16.offset1, align 16 116*9880d681SAndroid Build Coastguard Worker %load21 = load i8, i8 addrspace(1)* %gep.align1.offset16, align 16 117*9880d681SAndroid Build Coastguard Worker %load22 = load i8, i8 addrspace(1)* %gep.align16.offset16, align 16 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %no_deref_return 120*9880d681SAndroid Build Coastguard Worker; CHECK: %deref_return{{.*}}(unaligned) 121*9880d681SAndroid Build Coastguard Worker; CHECK: %deref_and_aligned_return{{.*}}(aligned) 122*9880d681SAndroid Build Coastguard Worker %no_deref_return = call i32* @foo() 123*9880d681SAndroid Build Coastguard Worker %deref_return = call dereferenceable(32) i32* @foo() 124*9880d681SAndroid Build Coastguard Worker %deref_and_aligned_return = call dereferenceable(32) align 16 i32* @foo() 125*9880d681SAndroid Build Coastguard Worker %load23 = load i32, i32* %no_deref_return 126*9880d681SAndroid Build Coastguard Worker %load24 = load i32, i32* %deref_return, align 16 127*9880d681SAndroid Build Coastguard Worker %load25 = load i32, i32* %deref_and_aligned_return, align 16 128*9880d681SAndroid Build Coastguard Worker 129*9880d681SAndroid Build Coastguard Worker ; Load from a dereferenceable and aligned load 130*9880d681SAndroid Build Coastguard Worker; CHECK: %d4_unaligned_load{{.*}}(unaligned) 131*9880d681SAndroid Build Coastguard Worker; CHECK: %d4_aligned_load{{.*}}(aligned) 132*9880d681SAndroid Build Coastguard Worker %d4_unaligned_load = load i32*, i32** @globali32ptr, !dereferenceable !0 133*9880d681SAndroid Build Coastguard Worker %d4_aligned_load = load i32*, i32** @globali32ptr, !dereferenceable !0, !align !{i64 16} 134*9880d681SAndroid Build Coastguard Worker %load26 = load i32, i32* %d4_unaligned_load, align 16 135*9880d681SAndroid Build Coastguard Worker %load27 = load i32, i32* %d4_aligned_load, align 16 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Worker ; Alloca with no explicit alignment is aligned to preferred alignment of 138*9880d681SAndroid Build Coastguard Worker ; the type (specified by datalayout string). 139*9880d681SAndroid Build Coastguard Worker; CHECK: %alloca.noalign{{.*}}(aligned) 140*9880d681SAndroid Build Coastguard Worker %alloca.noalign = alloca i32 141*9880d681SAndroid Build Coastguard Worker %load28 = load i32, i32* %alloca.noalign, align 8 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Worker ret void 144*9880d681SAndroid Build Coastguard Worker} 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker; Just check that we don't crash. 147*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: 'opaque_type_crasher' 148*9880d681SAndroid Build Coastguard Workerdefine void @opaque_type_crasher(%TypeOpaque* dereferenceable(16) %a) { 149*9880d681SAndroid Build Coastguard Workerentry: 150*9880d681SAndroid Build Coastguard Worker %bc = bitcast %TypeOpaque* %a to i8* 151*9880d681SAndroid Build Coastguard Worker %ptr8 = getelementptr inbounds i8, i8* %bc, i32 8 152*9880d681SAndroid Build Coastguard Worker %ptr32 = bitcast i8* %ptr8 to i32* 153*9880d681SAndroid Build Coastguard Worker br i1 undef, label %if.then, label %if.end 154*9880d681SAndroid Build Coastguard Worker 155*9880d681SAndroid Build Coastguard Workerif.then: 156*9880d681SAndroid Build Coastguard Worker %res = load i32, i32* %ptr32, align 4 157*9880d681SAndroid Build Coastguard Worker br label %if.end 158*9880d681SAndroid Build Coastguard Worker 159*9880d681SAndroid Build Coastguard Workerif.end: 160*9880d681SAndroid Build Coastguard Worker ret void 161*9880d681SAndroid Build Coastguard Worker} 162*9880d681SAndroid Build Coastguard Worker 163*9880d681SAndroid Build Coastguard Workerdeclare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) 164*9880d681SAndroid Build Coastguard Workerdeclare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32) 165*9880d681SAndroid Build Coastguard Worker 166*9880d681SAndroid Build Coastguard Workerdeclare i32 addrspace(1)* @func1(i32 addrspace(1)* returned) nounwind argmemonly 167*9880d681SAndroid Build Coastguard Worker 168*9880d681SAndroid Build Coastguard Worker!0 = !{i64 4} 169*9880d681SAndroid Build Coastguard Worker!1 = !{i64 2} 170*9880d681SAndroid Build Coastguard Worker!2 = !{} 171