1 ; Test lib call simplification of __memset_chk calls with various values 2 ; for dstlen and len. 3 ; 4 ; RUN: opt < %s -instcombine -S | FileCheck %s 5 ; rdar://7719085 6 7 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 8 9 %struct.T = type { [100 x i32], [100 x i32], [1024 x i8] } 10 @t = common global %struct.T zeroinitializer 11 12 ; Check cases where dstlen >= len. 13 14 define i8* @test_simplify1() { 15 ; CHECK-LABEL: @test_simplify1( 16 %dst = bitcast %struct.T* @t to i8* 17 18 ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* bitcast (%struct.T* @t to i8*), i8 0, i64 1824, i32 4, i1 false) 19 ; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*) 20 %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 1824) 21 ret i8* %ret 22 } 23 24 define i8* @test_simplify2() { 25 ; CHECK-LABEL: @test_simplify2( 26 %dst = bitcast %struct.T* @t to i8* 27 28 ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* bitcast (%struct.T* @t to i8*), i8 0, i64 1824, i32 4, i1 false) 29 ; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*) 30 %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 3648) 31 ret i8* %ret 32 } 33 34 define i8* @test_simplify3() { 35 ; CHECK-LABEL: @test_simplify3( 36 %dst = bitcast %struct.T* @t to i8* 37 38 ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* bitcast (%struct.T* @t to i8*), i8 0, i64 1824, i32 4, i1 false) 39 ; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*) 40 %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 -1) 41 ret i8* %ret 42 } 43 44 ; Check cases where dstlen < len. 45 46 define i8* @test_no_simplify1() { 47 ; CHECK-LABEL: @test_no_simplify1( 48 %dst = bitcast %struct.T* @t to i8* 49 50 ; CHECK-NEXT: %ret = call i8* @__memset_chk(i8* bitcast (%struct.T* @t to i8*), i32 0, i64 1824, i64 400) 51 ; CHECK-NEXT: ret i8* %ret 52 %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 400) 53 ret i8* %ret 54 } 55 56 define i8* @test_no_simplify2() { 57 ; CHECK-LABEL: @test_no_simplify2( 58 %dst = bitcast %struct.T* @t to i8* 59 60 ; CHECK-NEXT: %ret = call i8* @__memset_chk(i8* bitcast (%struct.T* @t to i8*), i32 0, i64 1824, i64 0) 61 ; CHECK-NEXT: ret i8* %ret 62 %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 0) 63 ret i8* %ret 64 } 65 66 ; Test that RAUW in SimplifyLibCalls for __memset_chk generates valid IR 67 define i32 @test_rauw(i8* %a, i8* %b, i8** %c) { 68 ; CHECK-LABEL: test_rauw 69 entry: 70 %call49 = call i64 @strlen(i8* %a) 71 %add180 = add i64 %call49, 1 72 %yo107 = call i64 @llvm.objectsize.i64.p0i8(i8* %b, i1 false) 73 %call50 = call i8* @__memmove_chk(i8* %b, i8* %a, i64 %add180, i64 %yo107) 74 ; CHECK: %strlen = call i64 @strlen(i8* %b) 75 ; CHECK-NEXT: %strchr2 = getelementptr i8, i8* %b, i64 %strlen 76 %call51i = call i8* @strrchr(i8* %b, i32 0) 77 %d = load i8*, i8** %c, align 8 78 %sub182 = ptrtoint i8* %d to i64 79 %sub183 = ptrtoint i8* %b to i64 80 %sub184 = sub i64 %sub182, %sub183 81 %add52.i.i = add nsw i64 %sub184, 1 82 ; CHECK: call void @llvm.memset.p0i8.i64(i8* %strchr2 83 %call185 = call i8* @__memset_chk(i8* %call51i, i32 0, i64 %add52.i.i, i64 -1) 84 ret i32 4 85 } 86 87 declare i8* @__memmove_chk(i8*, i8*, i64, i64) 88 declare i8* @strrchr(i8*, i32) 89 declare i64 @strlen(i8* nocapture) 90 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) 91 92 declare i8* @__memset_chk(i8*, i32, i64, i64) 93