1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test lib call simplification of __stpcpy_chk calls with various values
; for src, dst, and slen.
;
; RUN: opt < %s -instcombine -S | FileCheck %s
target 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"
@a = common global [60 x i8] zeroinitializer, align 1
@b = common global [60 x i8] zeroinitializer, align 1
@.str = private constant [12 x i8] c"abcdefghijk\00"
; Check cases where slen >= strlen (src).
define i8* @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false)
; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 11)
;
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0
%ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 60)
ret i8* %ret
}
define i8* @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false)
; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 11)
;
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0
%ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 12)
ret i8* %ret
}
define i8* @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false)
; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 11)
;
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0
%ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
ret i8* %ret
}
define i8* @test_simplify1_tail() {
; CHECK-LABEL: @test_simplify1_tail(
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false)
; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 11)
;
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0
%ret = tail call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 60)
ret i8* %ret
}
; Check cases where there are no string constants.
define i8* @test_simplify4() {
; CHECK-LABEL: @test_simplify4(
; CHECK-NEXT: [[STPCPY:%.*]] = call i8* @stpcpy(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0))
; CHECK-NEXT: ret i8* [[STPCPY]]
;
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
%ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
ret i8* %ret
}
define i8* @test_simplify4_tail() {
; CHECK-LABEL: @test_simplify4_tail(
; CHECK-NEXT: [[STPCPY:%.*]] = tail call i8* @stpcpy(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0))
; CHECK-NEXT: ret i8* [[STPCPY]]
;
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
%ret = tail call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
ret i8* %ret
}
; Check case where the string length is not constant.
define i8* @test_simplify5() {
; CHECK-LABEL: @test_simplify5(
; CHECK-NEXT: [[LEN:%.*]] = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false)
; CHECK-NEXT: [[TMP1:%.*]] = call i8* @__memcpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i32 [[LEN]])
; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 11)
;
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0
%len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false)
%ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 %len)
ret i8* %ret
}
; Check case where the source and destination are the same.
define i8* @test_simplify6() {
; CHECK-LABEL: @test_simplify6(
; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0))
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 [[STRLEN]]
; CHECK-NEXT: ret i8* [[TMP1]]
;
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
%len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false)
%ret = call i8* @__stpcpy_chk(i8* %dst, i8* %dst, i32 %len)
ret i8* %ret
}
; Check cases where there are no string constants, and is a tail call.
define i8* @test_simplify7() {
; CHECK-LABEL: @test_simplify7(
; CHECK-NEXT: [[STPCPY:%.*]] = tail call i8* @stpcpy(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0))
; CHECK-NEXT: ret i8* [[STPCPY]]
;
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
%ret = tail call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
ret i8* %ret
}
; Check case where slen < strlen (src).
define i8* @test_no_simplify1() {
; CHECK-LABEL: @test_no_simplify1(
; CHECK-NEXT: [[RET:%.*]] = call i8* @__stpcpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0), i32 8)
; CHECK-NEXT: ret i8* [[RET]]
;
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
%ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 8)
ret i8* %ret
}
declare i8* @__stpcpy_chk(i8*, i8*, i32) nounwind
declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1, i1) nounwind readonly
|