1 ; RUN: llc %s -mtriple=arm64-apple-darwin -o - | \ 2 ; RUN: FileCheck --check-prefix=CHECK-DARWIN --check-prefix=CHECK %s 3 ; RUN: llc %s -mtriple=arm64-linux-gnu -o - | \ 4 ; RUN: FileCheck --check-prefix=CHECK-LINUX --check-prefix=CHECK %s 5 ; <rdar://problem/14199482> ARM64: Calls to bzero() replaced with calls to memset() 6 7 ; CHECK: @fct1 8 ; For small size (<= 256), we do not change memset to bzero. 9 ; CHECK: memset 10 define void @fct1(i8* nocapture %ptr) { 11 entry: 12 tail call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 256, i32 1, i1 false) 13 ret void 14 } 15 16 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) 17 18 ; CHECK: @fct2 19 ; When the size is bigger than 256, change into bzero. 20 ; CHECK-DARWIN: bzero 21 ; CHECK-LINUX: memset 22 define void @fct2(i8* nocapture %ptr) { 23 entry: 24 tail call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 257, i32 1, i1 false) 25 ret void 26 } 27 28 ; CHECK: @fct3 29 ; For unknown size, change to bzero. 30 ; CHECK-DARWIN: bzero 31 ; CHECK-LINUX: memset 32 define void @fct3(i8* nocapture %ptr, i32 %unknown) { 33 entry: 34 %conv = sext i32 %unknown to i64 35 tail call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 %conv, i32 1, i1 false) 36 ret void 37 } 38 39 ; CHECK: @fct4 40 ; Size <= 256, no change. 41 ; CHECK: memset 42 define void @fct4(i8* %ptr) { 43 entry: 44 %tmp = tail call i64 @llvm.objectsize.i64(i8* %ptr, i1 false) 45 %call = tail call i8* @__memset_chk(i8* %ptr, i32 0, i64 256, i64 %tmp) 46 ret void 47 } 48 49 declare i8* @__memset_chk(i8*, i32, i64, i64) 50 51 declare i64 @llvm.objectsize.i64(i8*, i1) 52 53 ; CHECK: @fct5 54 ; Size > 256, change. 55 ; CHECK-DARWIN: bzero 56 ; CHECK-LINUX: memset 57 define void @fct5(i8* %ptr) { 58 entry: 59 %tmp = tail call i64 @llvm.objectsize.i64(i8* %ptr, i1 false) 60 %call = tail call i8* @__memset_chk(i8* %ptr, i32 0, i64 257, i64 %tmp) 61 ret void 62 } 63 64 ; CHECK: @fct6 65 ; Size = unknown, change. 66 ; CHECK-DARWIN: bzero 67 ; CHECK-LINUX: memset 68 define void @fct6(i8* %ptr, i32 %unknown) { 69 entry: 70 %conv = sext i32 %unknown to i64 71 %tmp = tail call i64 @llvm.objectsize.i64(i8* %ptr, i1 false) 72 %call = tail call i8* @__memset_chk(i8* %ptr, i32 0, i64 %conv, i64 %tmp) 73 ret void 74 } 75 76 ; Next functions check that memset is not turned into bzero 77 ; when the set constant is non-zero, whatever the given size. 78 79 ; CHECK: @fct7 80 ; memset with something that is not a zero, no change. 81 ; CHECK: memset 82 define void @fct7(i8* %ptr) { 83 entry: 84 %tmp = tail call i64 @llvm.objectsize.i64(i8* %ptr, i1 false) 85 %call = tail call i8* @__memset_chk(i8* %ptr, i32 1, i64 256, i64 %tmp) 86 ret void 87 } 88 89 ; CHECK: @fct8 90 ; memset with something that is not a zero, no change. 91 ; CHECK: memset 92 define void @fct8(i8* %ptr) { 93 entry: 94 %tmp = tail call i64 @llvm.objectsize.i64(i8* %ptr, i1 false) 95 %call = tail call i8* @__memset_chk(i8* %ptr, i32 1, i64 257, i64 %tmp) 96 ret void 97 } 98 99 ; CHECK: @fct9 100 ; memset with something that is not a zero, no change. 101 ; CHECK: memset 102 define void @fct9(i8* %ptr, i32 %unknown) { 103 entry: 104 %conv = sext i32 %unknown to i64 105 %tmp = tail call i64 @llvm.objectsize.i64(i8* %ptr, i1 false) 106 %call = tail call i8* @__memset_chk(i8* %ptr, i32 1, i64 %conv, i64 %tmp) 107 ret void 108 } 109