1f4a2713aSLionel Sambuc; Test a pile of objectsize bounds checking. 2f4a2713aSLionel Sambuc; RUN: opt < %s -instcombine -S | FileCheck %s 3f4a2713aSLionel Sambuc; We need target data to get the sizes of the arrays and structures. 4f4a2713aSLionel Sambuctarget datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" 5f4a2713aSLionel Sambuc 6f4a2713aSLionel Sambuc@a = private global [60 x i8] zeroinitializer, align 1 ; <[60 x i8]*> 7f4a2713aSLionel Sambuc@.str = private constant [8 x i8] c"abcdefg\00" ; <[8 x i8]*> 8f4a2713aSLionel Sambucdefine i32 @foo() nounwind { 9f4a2713aSLionel Sambuc; CHECK-LABEL: @foo( 10f4a2713aSLionel Sambuc; CHECK-NEXT: ret i32 60 11f4a2713aSLionel Sambuc %1 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false) 12f4a2713aSLionel Sambuc ret i32 %1 13f4a2713aSLionel Sambuc} 14f4a2713aSLionel Sambuc 15f4a2713aSLionel Sambucdefine i8* @bar() nounwind { 16f4a2713aSLionel Sambuc; CHECK-LABEL: @bar( 17f4a2713aSLionel Sambucentry: 18f4a2713aSLionel Sambuc %retval = alloca i8* 19f4a2713aSLionel Sambuc %0 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false) 20f4a2713aSLionel Sambuc %cmp = icmp ne i32 %0, -1 21f4a2713aSLionel Sambuc; CHECK: br i1 true 22f4a2713aSLionel Sambuc br i1 %cmp, label %cond.true, label %cond.false 23f4a2713aSLionel Sambuc 24f4a2713aSLionel Sambuccond.true: 25f4a2713aSLionel Sambuc %1 = load i8** %retval 26f4a2713aSLionel Sambuc ret i8* %1 27f4a2713aSLionel Sambuc 28f4a2713aSLionel Sambuccond.false: 29f4a2713aSLionel Sambuc %2 = load i8** %retval 30f4a2713aSLionel Sambuc ret i8* %2 31f4a2713aSLionel Sambuc} 32f4a2713aSLionel Sambuc 33f4a2713aSLionel Sambucdefine i32 @f() nounwind { 34f4a2713aSLionel Sambuc; CHECK-LABEL: @f( 35f4a2713aSLionel Sambuc; CHECK-NEXT: ret i32 0 36f4a2713aSLionel Sambuc %1 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr ([60 x i8]* @a, i32 1, i32 0), i1 false) 37f4a2713aSLionel Sambuc ret i32 %1 38f4a2713aSLionel Sambuc} 39f4a2713aSLionel Sambuc 40f4a2713aSLionel Sambuc@window = external global [0 x i8] 41f4a2713aSLionel Sambuc 42f4a2713aSLionel Sambucdefine i1 @baz() nounwind { 43f4a2713aSLionel Sambuc; CHECK-LABEL: @baz( 44f4a2713aSLionel Sambuc; CHECK-NEXT: objectsize 45f4a2713aSLionel Sambuc %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([0 x i8]* @window, i32 0, i32 0), i1 false) 46f4a2713aSLionel Sambuc %2 = icmp eq i32 %1, -1 47f4a2713aSLionel Sambuc ret i1 %2 48f4a2713aSLionel Sambuc} 49f4a2713aSLionel Sambuc 50f4a2713aSLionel Sambucdefine void @test1(i8* %q, i32 %x) nounwind noinline { 51f4a2713aSLionel Sambuc; CHECK-LABEL: @test1( 52f4a2713aSLionel Sambuc; CHECK: objectsize.i32.p0i8 53f4a2713aSLionel Sambucentry: 54f4a2713aSLionel Sambuc %0 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([0 x i8]* @window, i32 0, i32 10), i1 false) ; <i64> [#uses=1] 55f4a2713aSLionel Sambuc %1 = icmp eq i32 %0, -1 ; <i1> [#uses=1] 56f4a2713aSLionel Sambuc br i1 %1, label %"47", label %"46" 57f4a2713aSLionel Sambuc 58f4a2713aSLionel Sambuc"46": ; preds = %entry 59f4a2713aSLionel Sambuc unreachable 60f4a2713aSLionel Sambuc 61f4a2713aSLionel Sambuc"47": ; preds = %entry 62f4a2713aSLionel Sambuc unreachable 63f4a2713aSLionel Sambuc} 64f4a2713aSLionel Sambuc 65f4a2713aSLionel Sambuc@.str5 = private constant [9 x i32] [i32 97, i32 98, i32 99, i32 100, i32 0, i32 66f4a2713aSLionel Sambuc 101, i32 102, i32 103, i32 0], align 4 67f4a2713aSLionel Sambucdefine i32 @test2() nounwind { 68f4a2713aSLionel Sambuc; CHECK-LABEL: @test2( 69f4a2713aSLionel Sambuc; CHECK-NEXT: ret i32 34 70f4a2713aSLionel Sambuc %1 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr (i8* bitcast ([9 x i32]* @.str5 to i8*), i32 2), i1 false) 71f4a2713aSLionel Sambuc ret i32 %1 72f4a2713aSLionel Sambuc} 73f4a2713aSLionel Sambuc 74f4a2713aSLionel Sambuc; rdar://7674946 75f4a2713aSLionel Sambuc@array = internal global [480 x float] zeroinitializer ; <[480 x float]*> [#uses=1] 76f4a2713aSLionel Sambuc 77f4a2713aSLionel Sambucdeclare i8* @__memcpy_chk(i8*, i8*, i32, i32) nounwind 78f4a2713aSLionel Sambuc 79f4a2713aSLionel Sambucdeclare i32 @llvm.objectsize.i32.p0i8(i8*, i1) nounwind readonly 80f4a2713aSLionel Sambuc 81f4a2713aSLionel Sambucdeclare i8* @__inline_memcpy_chk(i8*, i8*, i32) nounwind inlinehint 82f4a2713aSLionel Sambuc 83f4a2713aSLionel Sambucdefine void @test3() nounwind { 84f4a2713aSLionel Sambuc; CHECK-LABEL: @test3( 85f4a2713aSLionel Sambucentry: 86f4a2713aSLionel Sambuc br i1 undef, label %bb11, label %bb12 87f4a2713aSLionel Sambuc 88f4a2713aSLionel Sambucbb11: 89f4a2713aSLionel Sambuc %0 = getelementptr inbounds float* getelementptr inbounds ([480 x float]* @array, i32 0, i32 128), i32 -127 ; <float*> [#uses=1] 90f4a2713aSLionel Sambuc %1 = bitcast float* %0 to i8* ; <i8*> [#uses=1] 91f4a2713aSLionel Sambuc %2 = call i32 @llvm.objectsize.i32.p0i8(i8* %1, i1 false) ; <i32> [#uses=1] 92f4a2713aSLionel Sambuc %3 = call i8* @__memcpy_chk(i8* undef, i8* undef, i32 512, i32 %2) nounwind ; <i8*> [#uses=0] 93f4a2713aSLionel Sambuc; CHECK: unreachable 94f4a2713aSLionel Sambuc unreachable 95f4a2713aSLionel Sambuc 96f4a2713aSLionel Sambucbb12: 97f4a2713aSLionel Sambuc %4 = getelementptr inbounds float* getelementptr inbounds ([480 x float]* @array, i32 0, i32 128), i32 -127 ; <float*> [#uses=1] 98f4a2713aSLionel Sambuc %5 = bitcast float* %4 to i8* ; <i8*> [#uses=1] 99f4a2713aSLionel Sambuc %6 = call i8* @__inline_memcpy_chk(i8* %5, i8* undef, i32 512) nounwind inlinehint ; <i8*> [#uses=0] 100f4a2713aSLionel Sambuc; CHECK: @__inline_memcpy_chk 101f4a2713aSLionel Sambuc unreachable 102f4a2713aSLionel Sambuc} 103f4a2713aSLionel Sambuc 104f4a2713aSLionel Sambuc; rdar://7718857 105f4a2713aSLionel Sambuc 106f4a2713aSLionel Sambuc%struct.data = type { [100 x i32], [100 x i32], [1024 x i8] } 107f4a2713aSLionel Sambuc 108f4a2713aSLionel Sambucdefine i32 @test4(i8** %esc) nounwind ssp { 109f4a2713aSLionel Sambuc; CHECK-LABEL: @test4( 110f4a2713aSLionel Sambucentry: 111f4a2713aSLionel Sambuc %0 = alloca %struct.data, align 8 112f4a2713aSLionel Sambuc %1 = bitcast %struct.data* %0 to i8* 113f4a2713aSLionel Sambuc %2 = call i32 @llvm.objectsize.i32.p0i8(i8* %1, i1 false) nounwind 114f4a2713aSLionel Sambuc; CHECK-NOT: @llvm.objectsize 115f4a2713aSLionel Sambuc; CHECK: @llvm.memset.p0i8.i32(i8* %1, i8 0, i32 1824, i32 8, i1 false) 116f4a2713aSLionel Sambuc %3 = call i8* @__memset_chk(i8* %1, i32 0, i32 1824, i32 %2) nounwind 117f4a2713aSLionel Sambuc store i8* %1, i8** %esc 118f4a2713aSLionel Sambuc ret i32 0 119f4a2713aSLionel Sambuc} 120f4a2713aSLionel Sambuc 121f4a2713aSLionel Sambuc; rdar://7782496 122f4a2713aSLionel Sambuc@s = external global i8* 123f4a2713aSLionel Sambuc 124f4a2713aSLionel Sambucdefine i8* @test5(i32 %n) nounwind ssp { 125f4a2713aSLionel Sambuc; CHECK-LABEL: @test5( 126f4a2713aSLionel Sambucentry: 127f4a2713aSLionel Sambuc %0 = tail call noalias i8* @malloc(i32 20) nounwind 128f4a2713aSLionel Sambuc %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %0, i1 false) 129f4a2713aSLionel Sambuc %2 = load i8** @s, align 8 130f4a2713aSLionel Sambuc; CHECK-NOT: @llvm.objectsize 131f4a2713aSLionel Sambuc; CHECK: @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* %1, i32 10, i32 1, i1 false) 132f4a2713aSLionel Sambuc %3 = tail call i8* @__memcpy_chk(i8* %0, i8* %2, i32 10, i32 %1) nounwind 133f4a2713aSLionel Sambuc ret i8* %0 134f4a2713aSLionel Sambuc} 135f4a2713aSLionel Sambuc 136f4a2713aSLionel Sambucdefine void @test6(i32 %n) nounwind ssp { 137f4a2713aSLionel Sambuc; CHECK-LABEL: @test6( 138f4a2713aSLionel Sambucentry: 139f4a2713aSLionel Sambuc %0 = tail call noalias i8* @malloc(i32 20) nounwind 140f4a2713aSLionel Sambuc %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %0, i1 false) 141f4a2713aSLionel Sambuc %2 = load i8** @s, align 8 142f4a2713aSLionel Sambuc; CHECK-NOT: @llvm.objectsize 143f4a2713aSLionel Sambuc; CHECK: @__memcpy_chk(i8* %0, i8* %1, i32 30, i32 20) 144f4a2713aSLionel Sambuc %3 = tail call i8* @__memcpy_chk(i8* %0, i8* %2, i32 30, i32 %1) nounwind 145f4a2713aSLionel Sambuc ret void 146f4a2713aSLionel Sambuc} 147f4a2713aSLionel Sambuc 148f4a2713aSLionel Sambucdeclare i8* @__memset_chk(i8*, i32, i32, i32) nounwind 149f4a2713aSLionel Sambuc 150f4a2713aSLionel Sambucdeclare noalias i8* @malloc(i32) nounwind 151f4a2713aSLionel Sambuc 152f4a2713aSLionel Sambucdefine i32 @test7(i8** %esc) { 153f4a2713aSLionel Sambuc; CHECK-LABEL: @test7( 154f4a2713aSLionel Sambuc %alloc = call noalias i8* @malloc(i32 48) nounwind 155f4a2713aSLionel Sambuc store i8* %alloc, i8** %esc 156f4a2713aSLionel Sambuc %gep = getelementptr inbounds i8* %alloc, i32 16 157f4a2713aSLionel Sambuc %objsize = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 false) nounwind readonly 158f4a2713aSLionel Sambuc; CHECK: ret i32 32 159f4a2713aSLionel Sambuc ret i32 %objsize 160f4a2713aSLionel Sambuc} 161f4a2713aSLionel Sambuc 162f4a2713aSLionel Sambucdeclare noalias i8* @calloc(i32, i32) nounwind 163f4a2713aSLionel Sambuc 164f4a2713aSLionel Sambucdefine i32 @test8(i8** %esc) { 165f4a2713aSLionel Sambuc; CHECK-LABEL: @test8( 166f4a2713aSLionel Sambuc %alloc = call noalias i8* @calloc(i32 5, i32 7) nounwind 167f4a2713aSLionel Sambuc store i8* %alloc, i8** %esc 168f4a2713aSLionel Sambuc %gep = getelementptr inbounds i8* %alloc, i32 5 169f4a2713aSLionel Sambuc %objsize = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 false) nounwind readonly 170f4a2713aSLionel Sambuc; CHECK: ret i32 30 171f4a2713aSLionel Sambuc ret i32 %objsize 172f4a2713aSLionel Sambuc} 173f4a2713aSLionel Sambuc 174f4a2713aSLionel Sambucdeclare noalias i8* @strdup(i8* nocapture) nounwind 175f4a2713aSLionel Sambucdeclare noalias i8* @strndup(i8* nocapture, i32) nounwind 176f4a2713aSLionel Sambuc 177f4a2713aSLionel Sambuc; CHECK-LABEL: @test9( 178f4a2713aSLionel Sambucdefine i32 @test9(i8** %esc) { 179f4a2713aSLionel Sambuc %call = tail call i8* @strdup(i8* getelementptr inbounds ([8 x i8]* @.str, i64 0, i64 0)) nounwind 180f4a2713aSLionel Sambuc store i8* %call, i8** %esc, align 8 181f4a2713aSLionel Sambuc %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true) 182f4a2713aSLionel Sambuc; CHECK: ret i32 8 183f4a2713aSLionel Sambuc ret i32 %1 184f4a2713aSLionel Sambuc} 185f4a2713aSLionel Sambuc 186f4a2713aSLionel Sambuc; CHECK-LABEL: @test10( 187f4a2713aSLionel Sambucdefine i32 @test10(i8** %esc) { 188f4a2713aSLionel Sambuc %call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8]* @.str, i64 0, i64 0), i32 3) nounwind 189f4a2713aSLionel Sambuc store i8* %call, i8** %esc, align 8 190f4a2713aSLionel Sambuc %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true) 191f4a2713aSLionel Sambuc; CHECK: ret i32 4 192f4a2713aSLionel Sambuc ret i32 %1 193f4a2713aSLionel Sambuc} 194f4a2713aSLionel Sambuc 195f4a2713aSLionel Sambuc; CHECK-LABEL: @test11( 196f4a2713aSLionel Sambucdefine i32 @test11(i8** %esc) { 197f4a2713aSLionel Sambuc %call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8]* @.str, i64 0, i64 0), i32 7) nounwind 198f4a2713aSLionel Sambuc store i8* %call, i8** %esc, align 8 199f4a2713aSLionel Sambuc %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true) 200f4a2713aSLionel Sambuc; CHECK: ret i32 8 201f4a2713aSLionel Sambuc ret i32 %1 202f4a2713aSLionel Sambuc} 203f4a2713aSLionel Sambuc 204f4a2713aSLionel Sambuc; CHECK-LABEL: @test12( 205f4a2713aSLionel Sambucdefine i32 @test12(i8** %esc) { 206f4a2713aSLionel Sambuc %call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8]* @.str, i64 0, i64 0), i32 8) nounwind 207f4a2713aSLionel Sambuc store i8* %call, i8** %esc, align 8 208f4a2713aSLionel Sambuc %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true) 209f4a2713aSLionel Sambuc; CHECK: ret i32 8 210f4a2713aSLionel Sambuc ret i32 %1 211f4a2713aSLionel Sambuc} 212f4a2713aSLionel Sambuc 213f4a2713aSLionel Sambuc; CHECK-LABEL: @test13( 214f4a2713aSLionel Sambucdefine i32 @test13(i8** %esc) { 215f4a2713aSLionel Sambuc %call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8]* @.str, i64 0, i64 0), i32 57) nounwind 216f4a2713aSLionel Sambuc store i8* %call, i8** %esc, align 8 217f4a2713aSLionel Sambuc %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true) 218f4a2713aSLionel Sambuc; CHECK: ret i32 8 219f4a2713aSLionel Sambuc ret i32 %1 220f4a2713aSLionel Sambuc} 221f4a2713aSLionel Sambuc 222f4a2713aSLionel Sambuc; CHECK-LABEL: @PR13390( 223f4a2713aSLionel Sambucdefine i32 @PR13390(i1 %bool, i8* %a) { 224f4a2713aSLionel Sambucentry: 225f4a2713aSLionel Sambuc %cond = or i1 %bool, true 226f4a2713aSLionel Sambuc br i1 %cond, label %return, label %xpto 227f4a2713aSLionel Sambuc 228f4a2713aSLionel Sambucxpto: 229f4a2713aSLionel Sambuc %select = select i1 %bool, i8* %select, i8* %a 230f4a2713aSLionel Sambuc %select2 = select i1 %bool, i8* %a, i8* %select2 231f4a2713aSLionel Sambuc %0 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %select, i1 true) 232f4a2713aSLionel Sambuc %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %select2, i1 true) 233f4a2713aSLionel Sambuc %2 = add i32 %0, %1 234f4a2713aSLionel Sambuc; CHECK: ret i32 undef 235f4a2713aSLionel Sambuc ret i32 %2 236f4a2713aSLionel Sambuc 237f4a2713aSLionel Sambucreturn: 238f4a2713aSLionel Sambuc ret i32 42 239f4a2713aSLionel Sambuc} 240f4a2713aSLionel Sambuc 241f4a2713aSLionel Sambuc; CHECK-LABEL: @PR13621( 242f4a2713aSLionel Sambucdefine i32 @PR13621(i1 %bool) nounwind { 243f4a2713aSLionel Sambucentry: 244f4a2713aSLionel Sambuc %cond = or i1 %bool, true 245f4a2713aSLionel Sambuc br i1 %cond, label %return, label %xpto 246f4a2713aSLionel Sambuc 247f4a2713aSLionel Sambuc; technically reachable, but this malformed IR may appear as a result of constant propagation 248f4a2713aSLionel Sambucxpto: 249f4a2713aSLionel Sambuc %gep2 = getelementptr i8* %gep, i32 1 250f4a2713aSLionel Sambuc %gep = getelementptr i8* %gep2, i32 1 251f4a2713aSLionel Sambuc %o = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 true) 252f4a2713aSLionel Sambuc; CHECK: ret i32 undef 253f4a2713aSLionel Sambuc ret i32 %o 254f4a2713aSLionel Sambuc 255f4a2713aSLionel Sambucreturn: 256f4a2713aSLionel Sambuc ret i32 7 257f4a2713aSLionel Sambuc} 258f4a2713aSLionel Sambuc 259*0a6a1f1dSLionel Sambuc@globalalias = internal alias [60 x i8]* @a 260f4a2713aSLionel Sambuc 261f4a2713aSLionel Sambuc; CHECK-LABEL: @test18( 262f4a2713aSLionel Sambuc; CHECK-NEXT: ret i32 60 263f4a2713aSLionel Sambucdefine i32 @test18() { 264f4a2713aSLionel Sambuc %bc = bitcast [60 x i8]* @globalalias to i8* 265f4a2713aSLionel Sambuc %1 = call i32 @llvm.objectsize.i32.p0i8(i8* %bc, i1 false) 266f4a2713aSLionel Sambuc ret i32 %1 267f4a2713aSLionel Sambuc} 268f4a2713aSLionel Sambuc 269*0a6a1f1dSLionel Sambuc@globalalias2 = weak alias [60 x i8]* @a 270f4a2713aSLionel Sambuc 271f4a2713aSLionel Sambuc; CHECK-LABEL: @test19( 272f4a2713aSLionel Sambuc; CHECK: llvm.objectsize 273f4a2713aSLionel Sambucdefine i32 @test19() { 274f4a2713aSLionel Sambuc %bc = bitcast [60 x i8]* @globalalias2 to i8* 275f4a2713aSLionel Sambuc %1 = call i32 @llvm.objectsize.i32.p0i8(i8* %bc, i1 false) 276f4a2713aSLionel Sambuc ret i32 %1 277f4a2713aSLionel Sambuc} 278f4a2713aSLionel Sambuc 279